From 2f28114fd4c2b67e56bfae866a9f2c0f1bb678d2 Mon Sep 17 00:00:00 2001 From: Bjoern Hiller Date: Sat, 8 Jan 2022 14:02:34 +0100 Subject: [PATCH 1/4] Initial infrastructure for setting default target The goal is to allow setting the default target to build. This can be done either in `Cross.toml` via ```toml [build] target = "armv7-unknown-linux-musleabihf" ``` or by setting `CROSS_BUILD_TARGET` to the desired value. --- src/config.rs | 29 ++++++++++++++++++++++++----- src/main.rs | 22 ++++++++++++++-------- 2 files changed, 38 insertions(+), 13 deletions(-) diff --git a/src/config.rs b/src/config.rs index d2ff92bc0..68ffb7f35 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,4 +1,4 @@ -use crate::{CrossToml, Result, Target}; +use crate::{CrossToml, Result, Target, TargetList}; use crate::errors::*; use std::collections::HashMap; @@ -181,6 +181,10 @@ impl Config { Ok(collected) } + pub fn target(&self, _target_list: &TargetList) -> Option { + None + } + fn sum_of_env_toml_values( toml_getter: impl FnOnce() -> Option>, env_values: Option>, @@ -201,11 +205,17 @@ mod tests { use super::*; use crate::{Target, TargetList}; - fn target() -> Target { - let target_list = TargetList { - triples: vec!["aarch64-unknown-linux-gnu".to_string()], - }; + fn target_list() -> TargetList { + TargetList { + triples: vec![ + "aarch64-unknown-linux-gnu".to_string(), + "armv7-unknown-linux-musleabihf".to_string(), + ], + } + } + fn target() -> Target { + let target_list = target_list(); Target::from("aarch64-unknown-linux-gnu", &target_list) } @@ -349,6 +359,15 @@ mod tests { Ok(()) } + #[test] + pub fn no_env_and_no_toml_default_target_then_none() -> Result<()> { + let config = Config::new_with(None, Environment::new(None)); + let config_target = config.target(&target_list()); + assert!(matches!(config_target, None)); + + Ok(()) + } + static TOML_BUILD_XARGO_FALSE: &str = r#" [build] xargo = false diff --git a/src/main.rs b/src/main.rs index 8387e2fa7..228ebe2fa 100644 --- a/src/main.rs +++ b/src/main.rs @@ -270,14 +270,14 @@ fn run() -> Result { rustc_version::version_meta().wrap_err("couldn't fetch the `rustc` version")?; if let Some(root) = cargo::root()? { let host = version_meta.host(); - - if host.is_supported(args.target.as_ref()) { - let target = args - .target - .unwrap_or_else(|| Target::from(host.triple(), &target_list)); - let toml = toml(&root)?; - let config = Config::new(toml); - + let toml = toml(&root)?; + let config = Config::new(toml); + let target = args + .target + .or(config.target(&target_list)) + .unwrap_or_else(|| Target::from(host.triple(), &target_list)); + + if host.is_supported(Some(&target)) { let mut sysroot = rustc::sysroot(&host, &target, verbose)?; let default_toolchain = sysroot .file_name() @@ -353,6 +353,12 @@ fn run() -> Result { } } filtered_args + // Make sure --target is present + } else if !args.all.iter().any(|a| a.starts_with("--target")) { + let mut args_with_target = args.all.clone(); + args_with_target.push("--target".to_string()); + args_with_target.push(target.triple().to_string()); + args_with_target } else { args.all.clone() }; From a69752a435b406352e0e0e354f11c4fc1f52582e Mon Sep 17 00:00:00 2001 From: Bjoern Hiller Date: Sat, 8 Jan 2022 14:07:09 +0100 Subject: [PATCH 2/4] Allow setting default target via environment --- src/config.rs | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/src/config.rs b/src/config.rs index 68ffb7f35..344f54618 100644 --- a/src/config.rs +++ b/src/config.rs @@ -78,6 +78,10 @@ impl Environment { self.get_values_for("ENV_VOLUMES", target) } + fn target(&self) -> Option { + self.get_build_var("TARGET") + } + fn get_values_for( &self, var: &str, @@ -181,7 +185,10 @@ impl Config { Ok(collected) } - pub fn target(&self, _target_list: &TargetList) -> Option { + pub fn target(&self, target_list: &TargetList) -> Option { + if let Some(env_value) = self.env.target() { + return Some(Target::from(&env_value, target_list)); + } None } @@ -368,6 +375,22 @@ mod tests { Ok(()) } + #[test] + pub fn env_and_toml_default_target_then_use_env() -> Result<()> { + let mut map = HashMap::new(); + map.insert("CROSS_BUILD_TARGET", "armv7-unknown-linux-musleabihf"); + let env = Environment::new(Some(map)); + let config = Config::new_with(Some(toml(TOML_DEFAULT_TARGET)?), env); + + let config_target = config.target(&target_list()).unwrap(); + assert!(matches!( + config_target.triple(), + "armv7-unknown-linux-musleabihf" + )); + + Ok(()) + } + static TOML_BUILD_XARGO_FALSE: &str = r#" [build] xargo = false @@ -383,6 +406,11 @@ mod tests { volumes = ["VOLUME3", "VOLUME4"] [target.aarch64-unknown-linux-gnu] xargo = false + "#; + + static TOML_DEFAULT_TARGET: &str = r#" + [build] + target = "aarch64-unknown-linux-gnu" "#; } } From cbb23824a7cf657cafaac5f981ddeb43e73829da Mon Sep 17 00:00:00 2001 From: Bjoern Hiller Date: Sat, 8 Jan 2022 14:07:54 +0100 Subject: [PATCH 3/4] Allow setting default target via Cross.toml N.B. `Debug` is needed for `TargetList` as linting rules demand it. --- src/config.rs | 16 +++++++++++++++- src/cross_toml.rs | 9 +++++++-- src/rustc.rs | 1 + 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/config.rs b/src/config.rs index 344f54618..352e8ff98 100644 --- a/src/config.rs +++ b/src/config.rs @@ -189,7 +189,7 @@ impl Config { if let Some(env_value) = self.env.target() { return Some(Target::from(&env_value, target_list)); } - None + self.toml.as_ref().map_or(None, |t| t.target(target_list)) } fn sum_of_env_toml_values( @@ -391,6 +391,20 @@ mod tests { Ok(()) } + #[test] + pub fn no_env_but_toml_default_target_then_use_toml() -> Result<()> { + let env = Environment::new(None); + let config = Config::new_with(Some(toml(TOML_DEFAULT_TARGET)?), env); + + let config_target = config.target(&target_list()).unwrap(); + assert!(matches!( + config_target.triple(), + "aarch64-unknown-linux-gnu" + )); + + Ok(()) + } + static TOML_BUILD_XARGO_FALSE: &str = r#" [build] xargo = false diff --git a/src/cross_toml.rs b/src/cross_toml.rs index 95101d400..b2efa1b07 100644 --- a/src/cross_toml.rs +++ b/src/cross_toml.rs @@ -1,7 +1,7 @@ #![doc = include_str!("../docs/cross_toml.md")] use crate::errors::*; -use crate::Target; +use crate::{Target, TargetList}; use serde::Deserialize; use std::collections::HashMap; @@ -91,6 +91,11 @@ impl CrossToml { .map_or(Vec::new(), |t| t.volumes.clone()) } + /// Returns the default target to build, + pub fn target(&self, target_list: &TargetList) -> Option { + self.build.as_ref().and_then(|b| b.target.as_ref()).map(|t| Target::from(t, target_list)) + } + /// Returns a reference to the [`CrossTargetConfig`] of a specific `target` fn get_target(&self, target: &Target) -> Option<&CrossTargetConfig> { self.targets.get(target) @@ -136,7 +141,7 @@ mod tests { let test_str = r#" [build] xargo = true - + [build.env] volumes = ["VOL1_ARG", "VOL2_ARG"] passthrough = ["VAR1", "VAR2"] diff --git a/src/rustc.rs b/src/rustc.rs index 173060976..47f2c2ad2 100644 --- a/src/rustc.rs +++ b/src/rustc.rs @@ -7,6 +7,7 @@ use crate::errors::*; use crate::extensions::CommandExt; use crate::{Host, Target}; +#[derive(Debug)] pub struct TargetList { pub triples: Vec, } From c84fce26b26b3c77f53bd582df38371bda228c73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emil=20Gardstr=C3=B6m?= Date: Thu, 24 Mar 2022 19:23:50 +0100 Subject: [PATCH 4/4] rename option to `default-target` also document the option --- CHANGELOG.md | 1 + docs/cross_toml.md | 1 + src/config.rs | 6 ++++-- src/cross_toml.rs | 12 ++++++++---- src/main.rs | 2 +- 5 files changed, 15 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1eb0c7b08..b82c918d8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] +- #624 - Add `build.default-target` - #670 - Use serde for deserialization of Cross.toml - Change rust edition to 2021 and bump MSRV for the cross binary to 1.58.1 - #654 - Use color-eyre for error reporting diff --git a/docs/cross_toml.md b/docs/cross_toml.md index 95f1306c4..32e0a39dc 100644 --- a/docs/cross_toml.md +++ b/docs/cross_toml.md @@ -6,6 +6,7 @@ The `build` key allows you to set global variables, e.g.: ```toml [build] xargo = true +default-target = "x86_64-unknown-linux-gnu" ``` # `build.env` diff --git a/src/config.rs b/src/config.rs index 352e8ff98..5b4a22c29 100644 --- a/src/config.rs +++ b/src/config.rs @@ -189,7 +189,9 @@ impl Config { if let Some(env_value) = self.env.target() { return Some(Target::from(&env_value, target_list)); } - self.toml.as_ref().map_or(None, |t| t.target(target_list)) + self.toml + .as_ref() + .and_then(|t| t.default_target(target_list)) } fn sum_of_env_toml_values( @@ -424,7 +426,7 @@ mod tests { static TOML_DEFAULT_TARGET: &str = r#" [build] - target = "aarch64-unknown-linux-gnu" + default-target = "aarch64-unknown-linux-gnu" "#; } } diff --git a/src/cross_toml.rs b/src/cross_toml.rs index b2efa1b07..2a571f175 100644 --- a/src/cross_toml.rs +++ b/src/cross_toml.rs @@ -16,10 +16,11 @@ pub struct CrossBuildEnvConfig { /// Build configuration #[derive(Debug, Deserialize, PartialEq, Default)] +#[serde(rename_all = "kebab-case")] pub struct CrossBuildConfig { env: Option, xargo: Option, - target: Option, + default_target: Option, } /// Target configuration @@ -92,8 +93,11 @@ impl CrossToml { } /// Returns the default target to build, - pub fn target(&self, target_list: &TargetList) -> Option { - self.build.as_ref().and_then(|b| b.target.as_ref()).map(|t| Target::from(t, target_list)) + pub fn default_target(&self, target_list: &TargetList) -> Option { + self.build + .as_ref() + .and_then(|b| b.default_target.as_ref()) + .map(|t| Target::from(t, target_list)) } /// Returns a reference to the [`CrossTargetConfig`] of a specific `target` @@ -134,7 +138,7 @@ mod tests { passthrough: vec!["VAR1".to_string(), "VAR2".to_string()], }), xargo: Some(true), - target: None, + default_target: None, }), }; diff --git a/src/main.rs b/src/main.rs index 228ebe2fa..eb7ad5943 100644 --- a/src/main.rs +++ b/src/main.rs @@ -274,7 +274,7 @@ fn run() -> Result { let config = Config::new(toml); let target = args .target - .or(config.target(&target_list)) + .or_else(|| config.target(&target_list)) .unwrap_or_else(|| Target::from(host.triple(), &target_list)); if host.is_supported(Some(&target)) {