Avoid complete recompilation when using `.cargo/config.toml` and setting `[build.rustflags]`

Assume that I have a .cargo/config.toml file in my ROOT_DIR (ROOT_DIR contains my cargo.toml file), with the following content:

.cargo/config.toml

[build]
rustflags = ["--cfg", "MAINNET"]

Consider my src/main.rs file:

src/main.rs

fn main() {
    
    #[cfg(MAINNET)]
    println("This is `MAINNET`");
    
    #[cfg(TESTNET)]
    println!("This is `TESTNET`");
}

I can use cargo check --config 'build.rustflags=["--cfg", "TESTNET"]' to override the "MAINNET" config flag within .cargo/config.toml if I want to specifically do cargo check with the "TESTNET" flag set.

However, whenever I try to do anything, e.g. cargo check, cargo test, with different compilation build.rustflags, e.g. ["--cfg", "TESTNET"] or ["--cfg", "MAINNET"], cargo will recompile from the beginning. It seems that nothing was cached from the previous compilations.

For example, suppose I run these commands in this order

  1. cargo check --config 'build.rustflags=["--cfg", "TESTNET"]' - Compiles all the dependencies from scratch.

  2. cargo check --config 'build.rustflags=["--cfg", "TESTNET"]' - Does NOT compile all the dependencies from scratch.

  3. cargo check --config 'build.rustflags=["--cfg", "MAINNET"]' - Compiles all the dependencies from scratch.

  4. cargo check --config 'build.rustflags=["--cfg", "MAINNET"]' - Does NOT compile all the dependencies from scratch.

  5. cargo check --config 'build.rustflags=["--cfg", "TESTNET"]' - COMPILES all the dependencies from scratch.

Note that there are zero code changes between each of these commands.

Is there a way to force cargo to cache the dependencies when building with different [build.rustflags]?

As far as I know, Cargo never caches distinct RUSTFLAGS separately, so any change will cause everything from the previous build to be overwritten — you can’t get what you’re looking for.

Ideally, you should design your application to avoid use of RUSTFLAGS/build.rustflags entirely, such as by making this configuration run-time configuration instead.

If necessary, you can dedicate two different target directories to the two different builds (perhaps by running your commands from two directories with separate config files that specify both build.rustflags and build.target-dir).

Thank you for your reply.

To your suggestion, do you then mean that if I specify these two parameters within the .cargo/config-mainnet.toml and .cargo/config-testnet.toml, I should expect cargo to cache the compilations?

No, I mean that your two configuration files can specify two different target-dirs, so that there are two caches that cannot overwrite each other.

1 Like