Skip to content

Commit

Permalink
Auto merge of #9322 - jameshilliard:split-host, r=joshtriplett
Browse files Browse the repository at this point in the history
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
  • Loading branch information
bors committed Jun 1, 2021
2 parents 6597523 + 5338bb2 commit 0cecbd6
Show file tree
Hide file tree
Showing 6 changed files with 514 additions and 9 deletions.
13 changes: 9 additions & 4 deletions src/cargo/core/compiler/build_context/target_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -682,10 +682,15 @@ impl<'cfg> RustcTargetData<'cfg> {
) -> CargoResult<RustcTargetData<'cfg>> {
let config = ws.config();
let rustc = config.load_global_rustc(Some(ws))?;
let host_config = config.target_cfg_triple(&rustc.host)?;
let host_info = TargetInfo::new(config, requested_kinds, &rustc, CompileKind::Host)?;
let mut target_config = HashMap::new();
let mut target_info = HashMap::new();
let target_applies_to_host = config.target_applies_to_host()?;
let host_info = TargetInfo::new(config, requested_kinds, &rustc, CompileKind::Host)?;
let host_config = if target_applies_to_host {
config.target_cfg_triple(&rustc.host)?
} else {
config.host_cfg_triple(&rustc.host)?
};

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

let mut res = RustcTargetData {
rustc,
Expand Down
4 changes: 4 additions & 0 deletions src/cargo/core/features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -600,6 +600,8 @@ unstable_cli_options!(
namespaced_features: bool = ("Allow features with `dep:` prefix"),
no_index_update: bool = ("Do not update the registry index even if the cache is outdated"),
panic_abort_tests: bool = ("Enable support to run tests with -Cpanic=abort"),
host_config: bool = ("Enable the [host] section in the .cargo/config.toml file"),
target_applies_to_host: bool = ("Enable the `target-applies-to-host` key in the .cargo/config.toml file"),
patch_in_config: bool = ("Allow `[patch]` sections in .cargo/config.toml files"),
rustdoc_map: bool = ("Allow passing external documentation mappings to rustdoc"),
separate_nightlies: bool = (HIDDEN),
Expand Down Expand Up @@ -787,6 +789,8 @@ impl CliUnstable {
"panic-abort-tests" => self.panic_abort_tests = parse_empty(k, v)?,
"jobserver-per-rustc" => self.jobserver_per_rustc = parse_empty(k, v)?,
"configurable-env" => self.configurable_env = parse_empty(k, v)?,
"host-config" => self.host_config = parse_empty(k, v)?,
"target-applies-to-host" => self.target_applies_to_host = parse_empty(k, v)?,
"patch-in-config" => self.patch_in_config = parse_empty(k, v)?,
"features" => {
// For now this is still allowed (there are still some
Expand Down
10 changes: 10 additions & 0 deletions src/cargo/util/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1486,6 +1486,16 @@ impl Config {
.try_borrow_with(|| self.get::<RustdocExternMap>("doc.extern-map"))
}

/// Returns true if the `[target]` table should be applied to host targets.
pub fn target_applies_to_host(&self) -> CargoResult<bool> {
target::get_target_applies_to_host(self)
}

/// Returns the `[host]` table definition for the given target triple.
pub fn host_cfg_triple(&self, target: &str) -> CargoResult<TargetConfig> {
target::load_host_triple(self, target)
}

/// Returns the `[target]` table definition for the given target triple.
pub fn target_cfg_triple(&self, target: &str) -> CargoResult<TargetConfig> {
target::load_target_triple(self, target)
Expand Down
54 changes: 49 additions & 5 deletions src/cargo/util/config/target.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ pub struct TargetCfgConfig {
pub other: BTreeMap<String, toml::Value>,
}

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

/// Returns true if the `[target]` table should be applied to host targets.
pub(super) fn get_target_applies_to_host(config: &Config) -> CargoResult<bool> {
if config.cli_unstable().target_applies_to_host {
if let Ok(target_applies_to_host) = config.get::<bool>("target-applies-to-host") {
Ok(target_applies_to_host)
} else {
Ok(!config.cli_unstable().host_config)
}
} else {
if config.cli_unstable().host_config {
anyhow::bail!(
"the -Zhost-config flag requires the -Ztarget-applies-to-host flag to be set"
);
} else {
Ok(true)
}
}
}

/// Loads a single `[host]` table for the given triple.
pub(super) fn load_host_triple(config: &Config, triple: &str) -> CargoResult<TargetConfig> {
if config.cli_unstable().host_config {
let host_triple_prefix = format!("host.{}", triple);
let host_triple_key = ConfigKey::from_str(&host_triple_prefix);
let host_prefix = match config.get_cv(&host_triple_key)? {
Some(_) => host_triple_prefix,
None => "host".to_string(),
};
load_config_table(config, &host_prefix)
} else {
Ok(TargetConfig {
runner: None,
rustflags: None,
linker: None,
links_overrides: BTreeMap::new(),
})
}
}

/// Loads a single `[target]` table for the given triple.
pub(super) fn load_target_triple(config: &Config, triple: &str) -> CargoResult<TargetConfig> {
load_config_table(config, &format!("target.{}", triple))
}

/// Loads a single table for the given prefix.
fn load_config_table(config: &Config, prefix: &str) -> CargoResult<TargetConfig> {
// This needs to get each field individually because it cannot fetch the
// struct all at once due to `links_overrides`. Can't use `serde(flatten)`
// because it causes serde to use `deserialize_map` which means the config
// deserializer does not know which keys to deserialize, which means
// environment variables would not work.
let runner: OptValue<PathAndArgs> = config.get(&format!("target.{}.runner", triple))?;
let rustflags: OptValue<StringList> = config.get(&format!("target.{}.rustflags", triple))?;
let linker: OptValue<ConfigRelativePath> = config.get(&format!("target.{}.linker", triple))?;
let runner: OptValue<PathAndArgs> = config.get(&format!("{}.runner", prefix))?;
let rustflags: OptValue<StringList> = config.get(&format!("{}.rustflags", prefix))?;
let linker: OptValue<ConfigRelativePath> = config.get(&format!("{}.linker", prefix))?;
// Links do not support environment variables.
let target_key = ConfigKey::from_str(&format!("target.{}", triple));
let target_key = ConfigKey::from_str(prefix);
let links_overrides = match config.get_table(&target_key)? {
Some(links) => parse_links_overrides(&target_key, links.val, config)?,
None => BTreeMap::new(),
Expand Down
55 changes: 55 additions & 0 deletions src/doc/src/reference/unstable.md
Original file line number Diff line number Diff line change
Expand Up @@ -705,6 +705,61 @@ cargo +nightly -Zunstable-options -Zconfig-include --config somefile.toml build

CLI paths are relative to the current working directory.

### target-applies-to-host
* Original Pull Request: [#9322](https://github.com/rust-lang/cargo/pull/9322)
* Tracking Issue: [#9453](https://github.com/rust-lang/cargo/issues/9453)

The `target-applies-to-host` key in a config file can be used set the desired
behavior for passing target config flags to build scripts.

It requires the `-Ztarget-applies-to-host` command-line option.

The current default for `target-applies-to-host` is `true`, which will be
changed to `false` in the future, if `-Zhost-config` is used the new `false`
default will be set for `target-applies-to-host`.

```toml
# config.toml
target-applies-to-host = false
```

```console
cargo +nightly -Ztarget-applies-to-host build --target x86_64-unknown-linux-gnu
```

### host-config
* Original Pull Request: [#9322](https://github.com/rust-lang/cargo/pull/9322)
* Tracking Issue: [#9452](https://github.com/rust-lang/cargo/issues/9452)

The `host` key in a config file can be used pass flags to host build targets
such as build scripts that must run on the host system instead of the target
system when cross compiling. It supports both generic and host arch specific
tables. Matching host arch tables take precedence over generic host tables.

It requires the `-Zhost-config` and `-Ztarget-applies-to-host` command-line
options to be set.

```toml
# config.toml
[host]
linker = "/path/to/host/linker"
[host.x86_64-unknown-linux-gnu]
linker = "/path/to/host/arch/linker"
[target.x86_64-unknown-linux-gnu]
linker = "/path/to/target/linker"
```

The generic `host` table above will be entirely ignored when building on a
`x86_64-unknown-linux-gnu` host as the `host.x86_64-unknown-linux-gnu` table
takes precedence.

Setting `-Zhost-config` changes the default for `target-applies-to-host` to
`false` from `true`.

```console
cargo +nightly -Ztarget-applies-to-host -Zhost-config build --target x86_64-unknown-linux-gnu
```

### unit-graph
* Tracking Issue: [#8002](https://github.com/rust-lang/cargo/issues/8002)

Expand Down
Loading

0 comments on commit 0cecbd6

Please sign in to comment.