You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Multiple rustflags configs should be cumulative #5376
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 a ld.gold executable.) Setting some flags through a config file is useful when cargo build is used directly without going through the wrapper script. (CC https://www.mail-archive.com/dev-servo@lists.mozilla.org/msg02703.html.)
Reacted by Jonas Schievink, Jonas Bushart, Jon Gjengset, Andy Li, Ivan Aksamentov, Lily, Khyber Sen, a_p_u_r_o, Martinez, Dan Lapid and 38 more
This seems like a reasonable interpretation of RUSTFLAGS to me, @matklad do you think we should be worried about breakage if we implemented these semantics?
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 .cargo/config at various directory levels, I certainly expect the overriding behavior. It also seems reasonable and sometimes useful that env-var overrides config...
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?
RUSTFLAGS="+ -C link-args=-fuse-ld=gold"
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.
Reacted by Jiji Freya Daniel Maslowski and Quentin Santos
But in one of the subcrates (my app's yew wasm frontend), I have
[build]
rustflags = ""# clear the rustflags from the parent configtarget = "wasm32-unknown-unknown"
Is this the correct way to prevent the parent config from affecting the subcrate?
I wish there was a better way that wouldn't require me to manually overwrite all the keys I set in the parent config in every subcrate's config where I don't want to inherit the config..
@Boscop I believe that Cargo’s "config" is determined once per run of the cargo command, you cannot have a different config in different crates that are compiled together.
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.
Reacted by Anders Musikka, Lu, Wangshan, Christopher Serr, Imbris, marieell, Daniel Henry-Mantilla, Jakub Beránek, Darren Kaste, Łukasz Jan Niemier, Seyyed Morteza Moosavi and 14 more
And everything built fine except in a CI environment with RUSTFLAGS=-Dwarnings set. It turns out that overrides the rustflags setting from the target settings, resulting in missing libraries.
While hacking around it, I noticed I hacked around a similar problem before where I had a $project/.cargo/config containing:
A Clippy contributor also just hit this issue, where their ~/.cargo/config file overrides the Clippy .cargo/config file, where we define rustflags.
I can see the overriding the build.rustflags with the env var RUSTFLAGS might be debatable. But from the Configuration documentation:
If a key is specified in multiple config files, the values will get merged together.
This seems not to be the case if the config value is specified under two different keys (target.<taget>.rustflags in ~/.cargo/config and build.rustflags in $PROJECT/.cargo/config)
So would a patch that merges the rustflags config no matter the origin be acceptable as a first step?
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 build.rustflags and RUSTFLAGS we now also have CARGO_ENCODED_RUSTFLAGS so it's a bit tricky. We have precedent for env vars overriding what's in the config file but that's typically for one-off settings rather than settings that are lists like RUSTFLAGS is. Personally I feel like the use cases for not appending are few and far between and would be ok taking a PR to implement it, but I'd want others to weigh in first before a PR is actually sent.
Reacted by Philipp Krones, Khyber Sen and Arvid Norlander
This also potentially interacts with #7722 — if I specify --config build.rustflags, should that be merged with [build] rustflags = ".." (and if so, with which ones if [build] rustflags is set in multiple config files) or should it completely override it?
I believe that project-local config.toml should override the global config. Currently this isn't the case, and there is no way for me to get around it without creating a project-local config for every other project just to handle issues with this one project.
This is a big pain point. I have a docker image that I use for CI runs. In that docker image I have mold linker installed, but I can't just configure cargo to use that linker by default in my image, because all config files get overridden by occasional RUSTFLAGS env var setup in the CI .yml template (e.g. to set --deny warnings). So I have to copy-paste the mold configs everywhere where RUSTFLAGS are set.
Reacted by Kristof Mattei, Łukasz Jan Niemier, Vitalii Kryvenko and Quentin Santos
Or setting flags to [] could have special meaning (though I do not know whether TOML supports repeated keys, so that could be tricky). Systemd uses that approach, but they use custom configuration format.
Interestingly, target.runner seems to be appended, not overwriting? At least that's what #10893 looks like. But maybe there's some other relevant factor here.
This is the exact opposite of what you'd want, I think: target.runner is usually a binary with some flags, concatenating multiple of these basically never makes sense. rustflags is a list of flags passed to rustc, concatenating them is usually what you want.
What would be the next concrete step towards solving this? I'm potentially interested in implementing something as long as it doesn't mean spending years bikeshedding what that solution should be.
Activity
alexcrichton commentedon Apr 17, 2018
This seems like a reasonable interpretation of
RUSTFLAGSto me, @matklad do you think we should be worried about breakage if we implemented these semantics?matklad commentedon Apr 17, 2018
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
.cargo/configat various directory levels, I certainly expect the overriding behavior. It also seems reasonable and sometimes useful that env-var overrides config...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.
SimonSapin commentedon Apr 17, 2018
For what it’s worth I would also expect accumulation in this case, not overriding.
That sounds remarkably obscure.
alexcrichton commentedon Apr 18, 2018
@matklad true yeah, in any case that sequence of events sounds reasonable to me!
Boscop commentedon Jul 16, 2018
In my use case I have a workspace whose toplevel crate has a
.cargo/configofBut in one of the subcrates (my app's yew wasm frontend), I have
Is this the correct way to prevent the parent config from affecting the subcrate?
I wish there was a better way that wouldn't require me to manually overwrite all the keys I set in the parent config in every subcrate's config where I don't want to inherit the config..
SimonSapin commentedon Jul 16, 2018
@Boscop I believe that Cargo’s "config" is determined once per run of the
cargocommand, you cannot have a different config in different crates that are compiled together.Boscop commentedon Jul 17, 2018
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).
jac-cbi commentedon Mar 3, 2020
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.
ehuss commentedon Apr 13, 2021
#6338 contains some additional discussion of this issue.
m-ou-se commentedon Sep 23, 2021
I ran into this problem again just now.
I have a
~/.cargo/configcontaining:And everything built fine except in a CI environment with
RUSTFLAGS=-Dwarningsset. It turns out that overrides therustflagssetting from the target settings, resulting in missing libraries.While hacking around it, I noticed I hacked around a similar problem before where I had a
$project/.cargo/configcontaining:which was also ignored in CI because of
RUSTFLAGS=-Dwarnings.flip1995 commentedon Sep 23, 2021
A Clippy contributor also just hit this issue, where their
~/.cargo/configfile overrides the Clippy.cargo/configfile, where we definerustflags.I can see the overriding the
build.rustflagswith the env varRUSTFLAGSmight be debatable. But from the Configuration documentation:This seems not to be the case if the config value is specified under two different keys (
target.<taget>.rustflagsin~/.cargo/configandbuild.rustflagsin$PROJECT/.cargo/config)So would a patch that merges the
rustflagsconfig no matter the origin be acceptable as a first step?alexcrichton commentedon Sep 23, 2021
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
build.rustflagsandRUSTFLAGSwe now also haveCARGO_ENCODED_RUSTFLAGSso it's a bit tricky. We have precedent for env vars overriding what's in the config file but that's typically for one-off settings rather than settings that are lists likeRUSTFLAGSis. Personally I feel like the use cases for not appending are few and far between and would be ok taking a PR to implement it, but I'd want others to weigh in first before a PR is actually sent.jonhoo commentedon Nov 23, 2021
This also potentially interacts with #7722 — if I specify
--config build.rustflags, should that be merged with[build] rustflags = ".."(and if so, with which ones if[build] rustflagsis set in multiple config files) or should it completely override it?5 remaining items
kirawi commentedon Nov 6, 2023
I believe that project-local
config.tomlshould override the global config. Currently this isn't the case, and there is no way for me to get around it without creating a project-local config for every other project just to handle issues with this one project.Veetaha commentedon Dec 3, 2023
This is a big pain point. I have a docker image that I use for CI runs. In that docker image I have
moldlinker installed, but I can't just configure cargo to use that linker by default in my image, because all config files get overridden by occasionalRUSTFLAGSenv var setup in the CI.ymltemplate (e.g. to set--deny warnings). So I have to copy-paste the mold configs everywhere whereRUSTFLAGSare set.hauleth commentedon Jan 14, 2024
@kirawi I think that could be configurable via additional option like:
Or
Or setting flags to
[]could have special meaning (though I do not know whether TOML supports repeated keys, so that could be tricky). Systemd uses that approach, but they use custom configuration format.RalfJung commentedon Mar 27, 2024
Interestingly,
target.runnerseems to be appended, not overwriting? At least that's what #10893 looks like. But maybe there's some other relevant factor here.This is the exact opposite of what you'd want, I think:
target.runneris usually a binary with some flags, concatenating multiple of these basically never makes sense.rustflagsis a list of flags passed to rustc, concatenating them is usually what you want.weihanglo commentedon Mar 27, 2024
From the doc:
Most of the arrays in Cargo configuration are cumulative. Even
[alias]is, which is a bit odd. However, rustflags is one of them not.garyttierney commentedon Mar 30, 2024
Hi all! Would this be a correct summary of the current behaviour?
RUSTFLAGSdefined on the environment completely overrides any rustflags derived by Cargo configrustflagsdefined under the same TOML section from multiple Cargo config.toml files will be concatenatedrustflagsdefined under different TOML sections from multiple Cargo config.toml files will take the one with highest precedence, see example below.When we define
rustflagsunder a target section globally (i.e. $HOME/.cargo/config.toml)and in
<project>/.cargo/config.tomlat the target level:We get:
However, if we change
<project>/.cargo/config.tomlto specifyrustflagsunder[build]We get:
If both specify
rustflagsunder[build]then as in the[target]case they get concatenated.svix-jplatte commentedon Jun 12, 2024
Since it hasn't been mentioned in this thread yet, as a workaround you can do this instead:
since target-specific rustflags are cumulative already.
Move `--cfg=web_sys_unstable_apis` to Cargo config
VorpalBlade commentedon Aug 31, 2025
What would be the next concrete step towards solving this? I'm potentially interested in implementing something as long as it doesn't mean spending years bikeshedding what that solution should be.
musjj commentedon Apr 4, 2026
CARGO_TARGET_<triple>_RUSTFLAGSis a nice workaround, but unfortunately there's no equivalent forRUSTDOCFLAGS.EDIT: Never mind, it does exist? #13197
But it's not documented in https://doc.rust-lang.org/cargo/reference/environment-variables.html#configuration-environment-variables, but it is mentioned in https://doc.rust-lang.org/cargo/reference/config.html#targettriplerustdocflags
weihanglo commentedon Apr 5, 2026
PR welcome :)
Move rustflags configuration from cargo config file to a rustc wrapper.