Skip to content

Commit 5fce888

Browse files
committed
Add various support for cargo configuration.
Also adds support for parsing and reading configuration options/environment variables from cargo, and allows users to ignore config files in the package. This adds the `[build.env.cargo-config]` option, which can be set to `complete`, `ignore`, or `default`. If set to `complete`, cross will have access to every to every cargo config file on the host (if using remote cross, a config file is written to a temporary file which is mounted on the data volume at `/.cargo/config.toml`). If set to ignore, any `.cargo/config.toml` files outside of `CARGO_HOME` are ignored, by mounting anonymous data volumes to hide config files in any `.cargo` directories. The default behavior uses the backwards-compatible behavior, allowing cross to access any config files in the package and `CARGO_HOME` directories. If the build is called outside the workspace root or at the workspace root, then we only mount an anonymous volume at `$PWD/.cargo`. The alias support includes recursive subcommand detection, and errors before it invokes cargo. A sample error message is `[cross] error: alias y has unresolvable recursive definition: x -> y -> z -> a -> y`, and therefore can handle non-trivial recursive subcommands.
1 parent 59ec530 commit 5fce888

18 files changed

+1681
-972
lines changed

.changes/931.json

+12-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,12 @@
1-
{
2-
"description": "deny installation of debian packages that conflict with our cross-compiler toolchains.",
3-
"type": "fixed"
4-
}
1+
[
2+
{
3+
"description": "add support for cargo aliases.",
4+
"type": "added",
5+
"issues": [562]
6+
},
7+
{
8+
"description": "allow users to ignore config files in the package.",
9+
"type": "added",
10+
"issues": [621]
11+
}
12+
]

.changes/933.json

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"description": "deny installation of debian packages that conflict with our cross-compiler toolchains.",
3+
"type": "fixed"
4+
}

docs/cross_toml.md

+2
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ For example:
2121

2222
```toml
2323
[build.env]
24+
cargo-config = "complete"
2425
volumes = ["VOL1_ARG", "VOL2_ARG"]
2526
passthrough = ["IMPORTANT_ENV_VARIABLES"]
2627
```
@@ -73,6 +74,7 @@ This is similar to `build.env`, but allows you to be more specific per target.
7374

7475
```toml
7576
[target.x86_64-unknown-linux-gnu.env]
77+
cargo-config = "ignore"
7678
volumes = ["VOL1_ARG", "VOL2_ARG"]
7779
passthrough = ["IMPORTANT_ENV_VARIABLES"]
7880
```

src/bin/commands/containers.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -392,7 +392,7 @@ pub fn create_persistent_volume(
392392
channel: Option<&Toolchain>,
393393
msg_info: &mut MessageInfo,
394394
) -> cross::Result<()> {
395-
let config = cross::config::Config::new(None);
395+
let config = cross::CrossConfig::new(None);
396396
let toolchain_host: cross::Target = toolchain.into();
397397
let mut toolchain = QualifiedToolchain::default(&config, msg_info)?;
398398
toolchain.replace_host(&ImagePlatform::from_target(
@@ -483,7 +483,7 @@ pub fn remove_persistent_volume(
483483
channel: Option<&Toolchain>,
484484
msg_info: &mut MessageInfo,
485485
) -> cross::Result<()> {
486-
let config = cross::config::Config::new(None);
486+
let config = cross::CrossConfig::new(None);
487487
let target_host: cross::Target = toolchain.into();
488488
let mut toolchain = QualifiedToolchain::default(&config, msg_info)?;
489489
toolchain.replace_host(&ImagePlatform::from_target(target_host.target().clone())?);

src/bin/cross.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,20 @@ use std::{
88
use cross::{
99
cargo, cli, rustc,
1010
shell::{self, Verbosity},
11-
OutputExt, Subcommand,
11+
CargoConfig, CargoToml, OutputExt, Subcommand,
1212
};
1313

1414
pub fn main() -> cross::Result<()> {
1515
cross::install_panic_hook()?;
1616
cross::install_termination_hook()?;
1717

1818
let target_list = rustc::target_list(&mut Verbosity::Quiet.into())?;
19-
let args = cli::parse(&target_list)?;
19+
let cargo_toml = CargoToml::read()?;
20+
let cargo_config = CargoConfig::new(cargo_toml);
21+
let args = cli::parse(&target_list, &cargo_config)?;
2022
let subcommand = args.subcommand;
2123
let mut msg_info = shell::MessageInfo::create(args.verbose, args.quiet, args.color.as_deref())?;
22-
let status = match cross::run(args, target_list, &mut msg_info)? {
24+
let status = match cross::run(args, target_list, cargo_config, &mut msg_info)? {
2325
Some(status) => status,
2426
None => {
2527
// if we fallback to the host cargo, use the same invocation that was made to cross

src/cargo_config.rs

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
use std::collections::HashMap;
2+
3+
use crate::cargo_toml::CargoToml;
4+
use crate::config::{split_to_cloned_by_ws, Environment};
5+
use crate::errors::*;
6+
7+
pub const CARGO_NO_PREFIX_ENVVARS: &[&str] = &[
8+
"http_proxy",
9+
"TERM",
10+
"RUSTDOCFLAGS",
11+
"RUSTFLAGS",
12+
"BROWSER",
13+
"HTTPS_PROXY",
14+
"HTTP_TIMEOUT",
15+
"https_proxy",
16+
];
17+
18+
#[derive(Debug)]
19+
struct CargoEnvironment(Environment);
20+
21+
impl CargoEnvironment {
22+
fn new(map: Option<HashMap<&'static str, &'static str>>) -> Self {
23+
CargoEnvironment(Environment::new("CARGO", map))
24+
}
25+
26+
pub fn alias(&self, name: &str) -> Option<Vec<String>> {
27+
let key = format!("ALIAS_{name}");
28+
self.0
29+
.get_var(&self.0.var_name(&key))
30+
.map(|x| split_to_cloned_by_ws(&x))
31+
}
32+
}
33+
34+
#[derive(Debug)]
35+
pub struct CargoConfig {
36+
toml: Option<CargoToml>,
37+
env: CargoEnvironment,
38+
}
39+
40+
impl CargoConfig {
41+
pub fn new(toml: Option<CargoToml>) -> Self {
42+
CargoConfig {
43+
toml,
44+
env: CargoEnvironment::new(None),
45+
}
46+
}
47+
48+
pub fn alias(&self, name: &str) -> Result<Option<Vec<String>>> {
49+
match self.env.alias(name) {
50+
Some(alias) => Ok(Some(alias)),
51+
None => match self.toml.as_ref() {
52+
Some(t) => t.alias(name),
53+
None => Ok(None),
54+
},
55+
}
56+
}
57+
58+
pub fn to_toml(&self) -> Result<Option<String>> {
59+
match self.toml.as_ref() {
60+
Some(t) => Ok(Some(t.to_toml()?)),
61+
None => Ok(None),
62+
}
63+
}
64+
}

0 commit comments

Comments
 (0)