const_env icon indicating copy to clipboard operation
const_env copied to clipboard

Only works if the code changes

Open NickLarsenNZ opened this issue 3 years ago • 2 comments

I've noticed this only appears to work when the code changes.

For example, if you have this:

#[const_env::from_env]
static SWITCH: bool = false;

fn main() {
   ...
}

On first compile, you can change the value to true with:

SWITCH=true cargo build

However, if you change the env var and rebuild like so:

SWITCH=false cargo build

The value is still set to true until the code is changed and recompiled as per last command.

NickLarsenNZ avatar Jun 11 '22 23:06 NickLarsenNZ

Maybe try adding

println!("cargo:rerun-if-env-changed=SWITCH");

inside build.rs?

haata avatar Oct 20 '22 06:10 haata

Thanks @haata. I'll give it a try if/when I use it (I can't recall what I was working on, but I'm sure I'll need this feature again).

NickLarsenNZ avatar Nov 04 '22 10:11 NickLarsenNZ

The tracked feature of this crate is intended to solve this problem. Enabling it requires using an unstable Rust compiler due to the dependency on https://github.com/rust-lang/rust/issues/99515.

EkardNT avatar Nov 10 '25 19:11 EkardNT

Going to close this as the unstable proc_macro::tracked_env::var is the best way to do this that I'm aware of, and the tracked feature of this crate allows users to opt-in to using that if they're on a nightly compiler.

EkardNT avatar Nov 10 '25 20:11 EkardNT

If a proc-macro emits the tokens for a call to env! or option_env!, then the proc-macro's caller automatically gets an "env-dep" build dependency on that variable.

As far as I can tell this works as well as the unstable tracked_env feature. For example:

// Hack: when compiled by the proc-macro caller it will register a build dependency
// on this environment variable, and cargo will rebuild the crate when the var changes.
// This is otherwise unused.
static __ENV_DEP_HACK: Option<&str> = option_env!("SOME_VAR");

ericseppanen avatar Nov 17 '25 18:11 ericseppanen

That's interesting, I'll reopen this to track adding that workaround to the code.

EkardNT avatar Nov 19 '25 02:11 EkardNT

I've also tried using this, which I think should be optimized away to nothing (but keeps the env-dep side effect), and doesn't risk symbol name collisions if it gets emitted multiple times:

const _: () = {
    let _ = option_env!("SOME_VAR");
};

ericseppanen avatar Nov 19 '25 03:11 ericseppanen

I implemented your suggested approach and tested that it does allow tracking to work even when using a stable compiler. I've published version 0.1.5 with the improvement. Thanks for the suggestion @ericseppanen.

EkardNT avatar Nov 19 '25 06:11 EkardNT