-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
Multiple rustflags configs should be cumulative #5376
Comments
This seems like a reasonable interpretation of |
Hm, I am actually unsure about semantics... It seems to me that sometimes you'd want to override rustflangs? For example, for an hierarchy of Implicit merging is also not a great UX because it's not clear that merging is happening somewhere. What do you think about some cryptic opt-in syntax for merging?
perhaps? As for breakage, I think the path of "0. feature flag 1. irlo announcement 2. flip default on nightly and see if anything breaks too terribly" is a reasonable one in this circumstances. |
For what it’s worth I would also expect accumulation in this case, not overriding.
That sounds remarkably obscure. |
@matklad true yeah, in any case that sequence of events sounds reasonable to me! |
In my use case I have a workspace whose toplevel crate has a [build]
rustflags = ["-Ctarget-feature=+crt-static", "-Ctarget-cpu=haswell"] But in one of the subcrates (my app's yew wasm frontend), I have [build]
rustflags = "" # clear the rustflags from the parent config
target = "wasm32-unknown-unknown" Is this the correct way to prevent the parent config from affecting the subcrate? |
@Boscop I believe that Cargo’s "config" is determined once per run of the |
The frontend crate is not compiled together with the toplevel (backend) crate. But they are both in the same workspace because they are part of the same project and they both depend on some shared crates for communication (that are also part of this workspace). |
In the interim, would it be possible just to warn the user that if both RUSTFLAGS is set and .cargo/config exists, "WARN: $RUSTFLAGS overrides anything set in .cargo/config when it exists"? This would've save me and the #rust-embedded Matrix room a good eight hours today due to my footgun. |
#6338 contains some additional discussion of this issue. |
I ran into this problem again just now. I have a [target.aarch64-unknown-linux-musl]
linker = "aarch64-linux-musl-gcc"
rustflags = ["-Lnative=/usr/aarch64-linux-musl/lib"] And everything built fine except in a CI environment with While hacking around it, I noticed I hacked around a similar problem before where I had a [build]
target = "thumbv7em-none-eabihf"
[target.thumbv7em-none-eabihf]
rustflags = ['-Clink-arg=-Tlink.x', '-Clink-arg=-s'] which was also ignored in CI because of |
A Clippy contributor also just hit this issue, where their I can see the overriding the
This seems not to be the case if the config value is specified under two different keys ( So would a patch that merges the |
I think at the very least it's pretty reasonable to merge target-specific rustflags and "bland rustflags". I suspect that can be mostly just done through a PR. For |
This also potentially interacts with #7722 — if I specify |
From a basic experiment it looks like #!/bin/bash
set -euo pipefail
rm -rf cargo-rustflags
mkdir cargo-rustflags
cd cargo-rustflags
mkdir cargo-home
cat >cargo-home/config.toml <<EOF
[build]
rustflags = ["--cfg=cargo_home"]
EOF
cargo new --lib project
cd project
mkdir .cargo
cat >.cargo/config.toml <<EOF
[build]
rustflags = ["--cfg=dot_cargo_config"]
EOF
cat >build.rs <<EOF
fn main() {
let dash_cfgs: Vec<_> = std::env::var("CARGO_ENCODED_RUSTFLAGS")
.unwrap()
.split('\\x1f')
.filter_map(|flag| flag.starts_with("--cfg").then(|| flag))
.map(String::from)
.collect();
assert!(false, "\n{}\n", dash_cfgs.join("\n"));
}
EOF
function cfgs() {
(env CARGO_HOME="$PWD/../cargo-home" cargo "$@" check 2>&1 || true) | sed 's/^ *//' | grep -E '^--cfg'
}
echo "rustc cfg flags with straight build"
cfgs
echo "rustc cfg flags with --config"
cfgs +nightly -Z unstable-options --config='build.rustflags = ["--cfg=cli"]'
echo "rustc cfg flags with RUSTFLAGS"
(
export RUSTFLAGS="--cfg=rustflags"
cfgs
)
|
I've just been hit by |
I hit this issue due to having a global [target.x86_64-unknown-linux-gnu]
linker = "clang"
rustflags = ["-C", "link-arg=-fuse-ld=/usr/bin/mold"] and trying to follow tokio_console's instructions for enabling the [build]
rustflags = ["--cfg", "tokio_unstable"] I tried swapping the two configs, and it seems that Cargo will always prefer the target flags over the build ones, which in cases like this leads to a confusing situation where global flags override local ones. I didn't see this mentioned in the discussion so far so I thought it'd be good to bring it up. My current solution is to add the global rustflags to the local config and to comment out the rustflags line from the global config when working on this project, which is a pretty awkward workflow. |
This is indeed very confusing behavior #[cargo_test]
fn build_flags_and_target_flags() {
let config = format!(
r#"
[build]
rustflags = ["-Wunused"]
[target.'cfg(target_arch = "{}")']
rustflags = ["-Wunsafe-code"]
"#,
std::env::consts::ARCH
);
let p = project()
.file(".cargo/config.toml", config.as_str())
.file("src/lib.rs", r#""#)
.build();
p.cargo("build -vv")
.with_stderr_contains("[..]-Wunsafe-code[..]")
.with_stderr_contains("[..]-Wunused[..]")
.run();
} A possible solution would be changing let mut all_rustflags = Vec::new();
if let Some(rustflags) = rustflags_from_env(flags) {
all_rustflags.extend(rustflags);
}
if let Some(rustflags) = rustflags_from_target(config, host_triple, target_cfg, kind, flags)? {
all_rustflags.extend(rustflags);
}
if let Some(rustflags) = rustflags_from_build(config, flags)? {
all_rustflags.extend(rustflags);
}
Ok(all_rustflags) |
I believe that project-local # ~/.cargo/config.toml
[target.x86_64-unknown-linux-gnu]
rustflags = ["-C", "link-arg=-fuse-ld=mold", "-Zshare-generics=y"] # $PROJECT/ .cargo/config.toml
[target.x86_64-unknown-linux-gnu]
rustflags = [] |
This is a big pain point. I have a docker image that I use for CI runs. In that docker image I have |
@kirawi I think that could be configurable via additional option like: # $PROJECT/ .cargo/config.toml
[target.x86_64-unknown-linux-gnu]
clean_env = true
rustflags = [] Or # $PROJECT/ .cargo/config.toml
[target.x86_64-unknown-linux-gnu]
clean_env = [ "rustflags" ]
rustflags = [] Or setting flags to |
Interestingly, This is the exact opposite of what you'd want, I think: |
From the doc:
Most of the arrays in Cargo configuration are cumulative. Even |
Hi all! Would this be a correct summary of the current behaviour?
When we define [target.x86_64-pc-windows-msvc]
linker = "lld"
rustflags = [
"-Lnative=$HOME/.xwin/crt/lib/x86_64",
"-Lnative=$HOME/.xwin/sdk/lib/um/x86_64",
"-Lnative=$HOME/.xwin/sdk/lib/ucrt/x86_64"
] and in [build]
target = "x86_64-pc-windows-msvc"
[target.x86_64-pc-windows-msvc]
rustflags = ["-C", "target-feature=+crt-static"] We get:
However, if we change We get:
If both specify |
Since it hasn't been mentioned in this thread yet, as a workaround you can do this instead: [target.'cfg(all())']
rustflags = ["--cfg", "tokio_unstable"] since target-specific rustflags are cumulative already. |
Example
.cargo/config
:When running for example
cargo build --target armv7-linux-androideabi
I’d expect both sets of flags to be passed to rustc, but only the former is.When running
RUSTFLAGS="-C link-args=-fuse-ld=gold" cargo build --target armv7-linux-androideabi
I’d expect all three sets of flags, but only the environment variable one is used and both configs are ignored.The intra-config-file case can be worked around by duplicating some config, but the environment variable is still useful for wrapper scripts like Servo’s
mach
to dynamically choose to use some flags or not. (In this case depending on testing the presence of ald.gold
executable.) Setting some flags through a config file is useful whencargo build
is used directly without going through the wrapper script. (CC https://www.mail-archive.com/dev-servo@lists.mozilla.org/msg02703.html.)The text was updated successfully, but these errors were encountered: