Cargo fails to detect environment variable is newly set and rebuild if the environment variable is set in `config.toml`
Problem
The problem can be only reproduced if the environment variable is "not set" in the first run, and "set" in the second run.
Steps
Incorrect behaivor
.cargo/config.toml:
[env]
Z = "0"
src/main.rs:
fn main() {
println!("{:?}", option_env!("Z"));
}
run these commands:
cargo run # first build, output Some("0")
Z=1 cargo run # cargo does not notice the environment variable is set and runs it, output Some("0")
Correct behaivor if we do not use a config.toml
src/main.rs:
fn main() {
println!("{:?}", option_env!("Z"));
}
run these commands:
cargo run # first build, output None
Z=1 cargo run # cargo does know the environment variable is set and rebuilds it, output Some("1")
Correct behaivor if we change the environment variable from a value to another value
.cargo/config.toml:
[env]
Z = "0"
src/main.rs:
fn main() {
println!("{:?}", option_env!("Z"));
}
run these commands:
Z=2 cargo run # first build, output Some("2")
Z=1 cargo run # cargo does know the environment variable changes and rebuilds it, output Some("1")
Possible Solution(s)
No response
Notes
No response
Version
cargo 1.77.0-nightly (ac6bbb332 2023-12-26)
cargo 1.75.0 (1d8b05cdd 2023-11-20)
By the way, it may be related to question #10358 & #12434.
By the way, it may be related to question #10358 & #12434.
Hmm… I don't quite think so. It is related to cargo's own dep-info file failed to track env vars from [env] table. Cargo removes those here:
https://github.com/rust-lang/cargo/blob/0c98d6ec3a3fc72683fe00963b8a55ffaa204d2a/src/cargo/core/compiler/fingerprint/mod.rs#L2017-L2019
env vars from [env] were applied to rustc_cmd in fill_env() earlier before this call.
Note: #13596 was an attempt of addressing this issue. In that PR, maintainers expected that kind of environment variable detection to be in the fingerprint code, where Cargo's dep-info logic is located.
#14154 is another case that Cargo's depinfo strips internal set environment variables (such as CARGO_PKG_README) causing the rebuild detection failure.
#14154 is another case that Cargo's depinfo strips internal set environment variables (such as
CARGO_PKG_README) causing the rebuild detection failure.
If the user just wants the environment variables in the [env] table to trigger recompilation, can we just fix that
This is a likely solution, env_keys is a HashSet contains the key defined in [env] table
on_disk_info.env.retain(|(key, _)| {
!rustc_cmd.get_envs().contains_key(key) || key == CARGO_ENV || env_keys.contains(key)
});
@linyihai
That seems worth a try!
For #14154 we could reopen if a fix doesn't cover it.