Skip to content

Commit

Permalink
Merge #624
Browse files Browse the repository at this point in the history
624: Allow setting default build target r=Emilgardis a=zappolowski

This implements #368 

This feature allows to specify the default target to build either in `Cross.toml`

```toml
[build]
target = "aarch64-unknown-linux-gnu"
```
or by setting `CROSS_BUILD_TARGET` to avoid the need to always specify `--target`.

I've opted for `build.target` as this resembles the configuration of [cargo](https://doc.rust-lang.org/cargo/reference/config.html#buildtarget).

Co-authored-by: Bjoern Hiller <[email protected]>
Co-authored-by: Emil Gardström <[email protected]>
  • Loading branch information
3 people authored Mar 24, 2022
2 parents b40f3fc + c84fce2 commit c4ee711
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 17 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions docs/cross_toml.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`
Expand Down
73 changes: 68 additions & 5 deletions src/config.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{CrossToml, Result, Target};
use crate::{CrossToml, Result, Target, TargetList};

use crate::errors::*;
use std::collections::HashMap;
Expand Down Expand Up @@ -78,6 +78,10 @@ impl Environment {
self.get_values_for("ENV_VOLUMES", target)
}

fn target(&self) -> Option<String> {
self.get_build_var("TARGET")
}

fn get_values_for(
&self,
var: &str,
Expand Down Expand Up @@ -181,6 +185,15 @@ impl Config {
Ok(collected)
}

pub fn target(&self, target_list: &TargetList) -> Option<Target> {
if let Some(env_value) = self.env.target() {
return Some(Target::from(&env_value, target_list));
}
self.toml
.as_ref()
.and_then(|t| t.default_target(target_list))
}

fn sum_of_env_toml_values(
toml_getter: impl FnOnce() -> Option<Vec<String>>,
env_values: Option<Vec<String>>,
Expand All @@ -201,11 +214,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)
}

Expand Down Expand Up @@ -349,6 +368,45 @@ 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(())
}

#[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(())
}

#[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
Expand All @@ -364,6 +422,11 @@ mod tests {
volumes = ["VOLUME3", "VOLUME4"]
[target.aarch64-unknown-linux-gnu]
xargo = false
"#;

static TOML_DEFAULT_TARGET: &str = r#"
[build]
default-target = "aarch64-unknown-linux-gnu"
"#;
}
}
17 changes: 13 additions & 4 deletions src/cross_toml.rs
Original file line number Diff line number Diff line change
@@ -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;

Expand All @@ -16,10 +16,11 @@ pub struct CrossBuildEnvConfig {

/// Build configuration
#[derive(Debug, Deserialize, PartialEq, Default)]
#[serde(rename_all = "kebab-case")]
pub struct CrossBuildConfig {
env: Option<CrossBuildEnvConfig>,
xargo: Option<bool>,
target: Option<String>,
default_target: Option<String>,
}

/// Target configuration
Expand Down Expand Up @@ -91,6 +92,14 @@ impl CrossToml {
.map_or(Vec::new(), |t| t.volumes.clone())
}

/// Returns the default target to build,
pub fn default_target(&self, target_list: &TargetList) -> Option<Target> {
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`
fn get_target(&self, target: &Target) -> Option<&CrossTargetConfig> {
self.targets.get(target)
Expand Down Expand Up @@ -129,14 +138,14 @@ mod tests {
passthrough: vec!["VAR1".to_string(), "VAR2".to_string()],
}),
xargo: Some(true),
target: None,
default_target: None,
}),
};

let test_str = r#"
[build]
xargo = true
[build.env]
volumes = ["VOL1_ARG", "VOL2_ARG"]
passthrough = ["VAR1", "VAR2"]
Expand Down
22 changes: 14 additions & 8 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -270,14 +270,14 @@ fn run() -> Result<ExitStatus> {
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_else(|| 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()
Expand Down Expand Up @@ -353,6 +353,12 @@ fn run() -> Result<ExitStatus> {
}
}
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()
};
Expand Down
1 change: 1 addition & 0 deletions src/rustc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use crate::errors::*;
use crate::extensions::CommandExt;
use crate::{Host, Target};

#[derive(Debug)]
pub struct TargetList {
pub triples: Vec<String>,
}
Expand Down

0 comments on commit c4ee711

Please sign in to comment.