Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow setting default build target #624

Merged
merged 4 commits into from
Mar 24, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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