Skip to content

Commit 0cecbd6

Browse files
committed
Auto merge of #9322 - jameshilliard:split-host, r=joshtriplett
Configure hosts separately from targets when --target is specified. This prevents target configs from accidentally being picked up when cross compiling from hosts that have the same architecture as their targets. closes #3349
2 parents 6597523 + 5338bb2 commit 0cecbd6

File tree

6 files changed

+514
-9
lines changed

6 files changed

+514
-9
lines changed

src/cargo/core/compiler/build_context/target_info.rs

+9-4
Original file line numberDiff line numberDiff line change
@@ -682,10 +682,15 @@ impl<'cfg> RustcTargetData<'cfg> {
682682
) -> CargoResult<RustcTargetData<'cfg>> {
683683
let config = ws.config();
684684
let rustc = config.load_global_rustc(Some(ws))?;
685-
let host_config = config.target_cfg_triple(&rustc.host)?;
686-
let host_info = TargetInfo::new(config, requested_kinds, &rustc, CompileKind::Host)?;
687685
let mut target_config = HashMap::new();
688686
let mut target_info = HashMap::new();
687+
let target_applies_to_host = config.target_applies_to_host()?;
688+
let host_info = TargetInfo::new(config, requested_kinds, &rustc, CompileKind::Host)?;
689+
let host_config = if target_applies_to_host {
690+
config.target_cfg_triple(&rustc.host)?
691+
} else {
692+
config.host_cfg_triple(&rustc.host)?
693+
};
689694

690695
// This is a hack. The unit_dependency graph builder "pretends" that
691696
// `CompileKind::Host` is `CompileKind::Target(host)` if the
@@ -695,8 +700,8 @@ impl<'cfg> RustcTargetData<'cfg> {
695700
if requested_kinds.iter().any(CompileKind::is_host) {
696701
let ct = CompileTarget::new(&rustc.host)?;
697702
target_info.insert(ct, host_info.clone());
698-
target_config.insert(ct, host_config.clone());
699-
}
703+
target_config.insert(ct, config.target_cfg_triple(&rustc.host)?);
704+
};
700705

701706
let mut res = RustcTargetData {
702707
rustc,

src/cargo/core/features.rs

+4
Original file line numberDiff line numberDiff line change
@@ -600,6 +600,8 @@ unstable_cli_options!(
600600
namespaced_features: bool = ("Allow features with `dep:` prefix"),
601601
no_index_update: bool = ("Do not update the registry index even if the cache is outdated"),
602602
panic_abort_tests: bool = ("Enable support to run tests with -Cpanic=abort"),
603+
host_config: bool = ("Enable the [host] section in the .cargo/config.toml file"),
604+
target_applies_to_host: bool = ("Enable the `target-applies-to-host` key in the .cargo/config.toml file"),
603605
patch_in_config: bool = ("Allow `[patch]` sections in .cargo/config.toml files"),
604606
rustdoc_map: bool = ("Allow passing external documentation mappings to rustdoc"),
605607
separate_nightlies: bool = (HIDDEN),
@@ -787,6 +789,8 @@ impl CliUnstable {
787789
"panic-abort-tests" => self.panic_abort_tests = parse_empty(k, v)?,
788790
"jobserver-per-rustc" => self.jobserver_per_rustc = parse_empty(k, v)?,
789791
"configurable-env" => self.configurable_env = parse_empty(k, v)?,
792+
"host-config" => self.host_config = parse_empty(k, v)?,
793+
"target-applies-to-host" => self.target_applies_to_host = parse_empty(k, v)?,
790794
"patch-in-config" => self.patch_in_config = parse_empty(k, v)?,
791795
"features" => {
792796
// For now this is still allowed (there are still some

src/cargo/util/config/mod.rs

+10
Original file line numberDiff line numberDiff line change
@@ -1486,6 +1486,16 @@ impl Config {
14861486
.try_borrow_with(|| self.get::<RustdocExternMap>("doc.extern-map"))
14871487
}
14881488

1489+
/// Returns true if the `[target]` table should be applied to host targets.
1490+
pub fn target_applies_to_host(&self) -> CargoResult<bool> {
1491+
target::get_target_applies_to_host(self)
1492+
}
1493+
1494+
/// Returns the `[host]` table definition for the given target triple.
1495+
pub fn host_cfg_triple(&self, target: &str) -> CargoResult<TargetConfig> {
1496+
target::load_host_triple(self, target)
1497+
}
1498+
14891499
/// Returns the `[target]` table definition for the given target triple.
14901500
pub fn target_cfg_triple(&self, target: &str) -> CargoResult<TargetConfig> {
14911501
target::load_target_triple(self, target)

src/cargo/util/config/target.rs

+49-5
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ pub struct TargetCfgConfig {
1919
pub other: BTreeMap<String, toml::Value>,
2020
}
2121

22-
/// Config definition of a `[target]` table.
22+
/// Config definition of a `[target]` table or `[host]`.
2323
#[derive(Debug, Clone)]
2424
pub struct TargetConfig {
2525
/// Process to run as a wrapper for `cargo run`, `test`, and `bench` commands.
@@ -64,18 +64,62 @@ pub(super) fn load_target_cfgs(config: &Config) -> CargoResult<Vec<(String, Targ
6464
Ok(result)
6565
}
6666

67+
/// Returns true if the `[target]` table should be applied to host targets.
68+
pub(super) fn get_target_applies_to_host(config: &Config) -> CargoResult<bool> {
69+
if config.cli_unstable().target_applies_to_host {
70+
if let Ok(target_applies_to_host) = config.get::<bool>("target-applies-to-host") {
71+
Ok(target_applies_to_host)
72+
} else {
73+
Ok(!config.cli_unstable().host_config)
74+
}
75+
} else {
76+
if config.cli_unstable().host_config {
77+
anyhow::bail!(
78+
"the -Zhost-config flag requires the -Ztarget-applies-to-host flag to be set"
79+
);
80+
} else {
81+
Ok(true)
82+
}
83+
}
84+
}
85+
86+
/// Loads a single `[host]` table for the given triple.
87+
pub(super) fn load_host_triple(config: &Config, triple: &str) -> CargoResult<TargetConfig> {
88+
if config.cli_unstable().host_config {
89+
let host_triple_prefix = format!("host.{}", triple);
90+
let host_triple_key = ConfigKey::from_str(&host_triple_prefix);
91+
let host_prefix = match config.get_cv(&host_triple_key)? {
92+
Some(_) => host_triple_prefix,
93+
None => "host".to_string(),
94+
};
95+
load_config_table(config, &host_prefix)
96+
} else {
97+
Ok(TargetConfig {
98+
runner: None,
99+
rustflags: None,
100+
linker: None,
101+
links_overrides: BTreeMap::new(),
102+
})
103+
}
104+
}
105+
67106
/// Loads a single `[target]` table for the given triple.
68107
pub(super) fn load_target_triple(config: &Config, triple: &str) -> CargoResult<TargetConfig> {
108+
load_config_table(config, &format!("target.{}", triple))
109+
}
110+
111+
/// Loads a single table for the given prefix.
112+
fn load_config_table(config: &Config, prefix: &str) -> CargoResult<TargetConfig> {
69113
// This needs to get each field individually because it cannot fetch the
70114
// struct all at once due to `links_overrides`. Can't use `serde(flatten)`
71115
// because it causes serde to use `deserialize_map` which means the config
72116
// deserializer does not know which keys to deserialize, which means
73117
// environment variables would not work.
74-
let runner: OptValue<PathAndArgs> = config.get(&format!("target.{}.runner", triple))?;
75-
let rustflags: OptValue<StringList> = config.get(&format!("target.{}.rustflags", triple))?;
76-
let linker: OptValue<ConfigRelativePath> = config.get(&format!("target.{}.linker", triple))?;
118+
let runner: OptValue<PathAndArgs> = config.get(&format!("{}.runner", prefix))?;
119+
let rustflags: OptValue<StringList> = config.get(&format!("{}.rustflags", prefix))?;
120+
let linker: OptValue<ConfigRelativePath> = config.get(&format!("{}.linker", prefix))?;
77121
// Links do not support environment variables.
78-
let target_key = ConfigKey::from_str(&format!("target.{}", triple));
122+
let target_key = ConfigKey::from_str(prefix);
79123
let links_overrides = match config.get_table(&target_key)? {
80124
Some(links) => parse_links_overrides(&target_key, links.val, config)?,
81125
None => BTreeMap::new(),

src/doc/src/reference/unstable.md

+55
Original file line numberDiff line numberDiff line change
@@ -705,6 +705,61 @@ cargo +nightly -Zunstable-options -Zconfig-include --config somefile.toml build
705705

706706
CLI paths are relative to the current working directory.
707707

708+
### target-applies-to-host
709+
* Original Pull Request: [#9322](https://github.com/rust-lang/cargo/pull/9322)
710+
* Tracking Issue: [#9453](https://github.com/rust-lang/cargo/issues/9453)
711+
712+
The `target-applies-to-host` key in a config file can be used set the desired
713+
behavior for passing target config flags to build scripts.
714+
715+
It requires the `-Ztarget-applies-to-host` command-line option.
716+
717+
The current default for `target-applies-to-host` is `true`, which will be
718+
changed to `false` in the future, if `-Zhost-config` is used the new `false`
719+
default will be set for `target-applies-to-host`.
720+
721+
```toml
722+
# config.toml
723+
target-applies-to-host = false
724+
```
725+
726+
```console
727+
cargo +nightly -Ztarget-applies-to-host build --target x86_64-unknown-linux-gnu
728+
```
729+
730+
### host-config
731+
* Original Pull Request: [#9322](https://github.com/rust-lang/cargo/pull/9322)
732+
* Tracking Issue: [#9452](https://github.com/rust-lang/cargo/issues/9452)
733+
734+
The `host` key in a config file can be used pass flags to host build targets
735+
such as build scripts that must run on the host system instead of the target
736+
system when cross compiling. It supports both generic and host arch specific
737+
tables. Matching host arch tables take precedence over generic host tables.
738+
739+
It requires the `-Zhost-config` and `-Ztarget-applies-to-host` command-line
740+
options to be set.
741+
742+
```toml
743+
# config.toml
744+
[host]
745+
linker = "/path/to/host/linker"
746+
[host.x86_64-unknown-linux-gnu]
747+
linker = "/path/to/host/arch/linker"
748+
[target.x86_64-unknown-linux-gnu]
749+
linker = "/path/to/target/linker"
750+
```
751+
752+
The generic `host` table above will be entirely ignored when building on a
753+
`x86_64-unknown-linux-gnu` host as the `host.x86_64-unknown-linux-gnu` table
754+
takes precedence.
755+
756+
Setting `-Zhost-config` changes the default for `target-applies-to-host` to
757+
`false` from `true`.
758+
759+
```console
760+
cargo +nightly -Ztarget-applies-to-host -Zhost-config build --target x86_64-unknown-linux-gnu
761+
```
762+
708763
### unit-graph
709764
* Tracking Issue: [#8002](https://github.com/rust-lang/cargo/issues/8002)
710765

0 commit comments

Comments
 (0)