Skip to content

Commit

Permalink
Add build-std config option.
Browse files Browse the repository at this point in the history
Detects if `rust-std` is not an available component for a target, and if `build-std = true` in `Cross.toml` under `[build]` or `[target.(...)]`, then use the `-Zbuild-std` flag. This has higher priority than `xargo`: `xargo` will only be used if a target is not a built-in.

A sample `Cross.toml` file is the following:

```toml
[target.x86_64-unknown-dragonfly]
build-std = true
```

Closes cross-rs#692.
  • Loading branch information
Alexhuszagh committed Jun 11, 2022
1 parent 0ab4cf1 commit 8421513
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 5 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).

### Added

- #782 - added `build-std` config option, which builds the rust standard library from source if enabled.
- #775 - forward Cargo exit code to host
- #767 - added the `cross-util` and `cross-dev` commands.
- #745 - added `thumbv7neon-*` targets.
Expand Down
4 changes: 3 additions & 1 deletion 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
build-std = true
default-target = "x86_64-unknown-linux-gnu"
```

Expand All @@ -26,6 +27,7 @@ The `target` key allows you to specify parameters for specific compilation targe
```toml
[target.aarch64-unknown-linux-gnu]
xargo = false
build-std = false
image = "test-image"
runner = "custom-runner"
```
Expand All @@ -38,4 +40,4 @@ This is similar to `build.env`, but allows you to be more specific per target.
[target.x86_64-unknown-linux-gnu.env]
volumes = ["VOL1_ARG", "VOL2_ARG"]
passthrough = ["IMPORTANT_ENV_VARIABLES"]
```
```
18 changes: 17 additions & 1 deletion src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,11 @@ impl Environment {
}

fn build_path(key: &str) -> String {
format!("BUILD_{key}")
if !key.starts_with("BUILD_") {
format!("BUILD_{key}")
} else {
key.to_string()
}
}

fn get_build_var(&self, key: &str) -> Option<String> {
Expand All @@ -56,6 +60,10 @@ impl Environment {
self.get_values_for("XARGO", target, bool_from_envvar)
}

fn build_std(&self, target: &Target) -> (Option<bool>, Option<bool>) {
self.get_values_for("BUILD_STD", target, bool_from_envvar)
}

fn image(&self, target: &Target) -> Option<String> {
self.get_target_var(target, "IMAGE")
}
Expand Down Expand Up @@ -191,6 +199,10 @@ impl Config {
self.bool_from_config(target, Environment::xargo, CrossToml::xargo)
}

pub fn build_std(&self, target: &Target) -> Option<bool> {
self.bool_from_config(target, Environment::build_std, CrossToml::build_std)
}

pub fn image(&self, target: &Target) -> Result<Option<String>> {
self.string_from_config(target, Environment::image, CrossToml::image)
}
Expand Down Expand Up @@ -270,9 +282,11 @@ mod tests {
pub fn parse_error_in_env() {
let mut map = std::collections::HashMap::new();
map.insert("CROSS_BUILD_XARGO", "tru");
map.insert("CROSS_BUILD_STD", "false");

let env = Environment::new(Some(map));
assert_eq!(env.xargo(&target()), (Some(true), None));
assert_eq!(env.build_std(&target()), (Some(false), None));
}

#[test]
Expand Down Expand Up @@ -346,10 +360,12 @@ mod tests {
pub fn env_target_and_toml_target_xargo_target_then_use_env() -> Result<()> {
let mut map = HashMap::new();
map.insert("CROSS_TARGET_AARCH64_UNKNOWN_LINUX_GNU_XARGO", "true");
map.insert("CROSS_TARGET_AARCH64_UNKNOWN_LINUX_GNU_BUILD_STD", "true");
let env = Environment::new(Some(map));

let config = Config::new_with(Some(toml(TOML_TARGET_XARGO_FALSE)?), env);
assert!(matches!(config.xargo(&target()), Some(true)));
assert!(matches!(config.build_std(&target()), Some(true)));

Ok(())
}
Expand Down
11 changes: 11 additions & 0 deletions src/cross_toml.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,16 @@ pub struct CrossBuildConfig {
#[serde(default)]
env: CrossEnvConfig,
xargo: Option<bool>,
build_std: Option<bool>,
default_target: Option<String>,
}

/// Target configuration
#[derive(Debug, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "kebab-case")]
pub struct CrossTargetConfig {
xargo: Option<bool>,
build_std: Option<bool>,
image: Option<String>,
runner: Option<String>,
#[serde(default)]
Expand Down Expand Up @@ -79,6 +82,11 @@ impl CrossToml {
self.get_bool(target, |b| b.xargo, |t| t.xargo)
}

/// Returns the `build.build-std` or the `target.{}.build-std` part of `Cross.toml`
pub fn build_std(&self, target: &Target) -> (Option<bool>, Option<bool>) {
self.get_bool(target, |b| b.build_std, |t| t.build_std)
}

/// Returns the list of environment variables to pass through for `build`,
pub fn env_passthrough_build(&self) -> &[String] {
&self.build.env.passthrough
Expand Down Expand Up @@ -165,6 +173,7 @@ mod tests {
passthrough: vec!["VAR1".to_string(), "VAR2".to_string()],
},
xargo: Some(true),
build_std: None,
default_target: None,
},
};
Expand Down Expand Up @@ -198,6 +207,7 @@ mod tests {
volumes: vec!["VOL1_ARG".to_string(), "VOL2_ARG".to_string()],
},
xargo: Some(false),
build_std: Some(true),
image: Some("test-image".to_string()),
runner: None,
},
Expand All @@ -214,6 +224,7 @@ mod tests {
passthrough = ["VAR1", "VAR2"]
[target.aarch64-unknown-linux-gnu]
xargo = false
build-std = true
image = "test-image"
"#;
let (parsed_cfg, unused) = CrossToml::parse(test_str)?;
Expand Down
17 changes: 14 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -348,10 +348,18 @@ pub fn run() -> Result<ExitStatus> {
is_nightly = channel == Channel::Nightly;
}

// build-std overrides xargo, but only use it if it's a built-in
// tool but not an available target or doesn't have rust-std.
let available_targets = rustup::available_targets(&toolchain, verbose)?;
let uses_xargo = config
.xargo(&target)
.unwrap_or_else(|| !target.is_builtin() || !available_targets.contains(&target));
let uses_build_std = config.build_std(&target).unwrap_or(false);
let uses_xargo =
!uses_build_std && config.xargo(&target).unwrap_or(!target.is_builtin());
if !is_nightly && uses_build_std {
eyre::bail!(
"no rust-std component available for {}: must use nightly",
target.triple()
);
}

if !uses_xargo
&& !available_targets.is_installed(&target)
Expand Down Expand Up @@ -409,6 +417,9 @@ pub fn run() -> Result<ExitStatus> {
if is_test && args.enable_doctests && is_nightly {
filtered_args.push("-Zdoctest-xcompile".to_string());
}
if uses_build_std {
filtered_args.push("-Zbuild-std".to_string());
}

if target.needs_docker() && args.subcommand.map(|sc| sc.needs_docker()).unwrap_or(false)
{
Expand Down

0 comments on commit 8421513

Please sign in to comment.