Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get profile from Cargo.toml in build.rs or at runtime

imagine I have a Cargo.toml with this in it:

[profile.performance]
inherits = "release"
opt-level = 3
debug = true
overflow-checks = false
lto = true
codegen-units = 1

[profile.cli]
inherits = "release"
debug = false
opt-level = "z"
lto = true
strip = true
codegen-units = 1

How do I get the profile name, e.g. performance or cli, in either build.rs or at runtime?

I have tried:

  • The PROFILE env var. This is only ever debug or release.
  • All of the CARGO_CFG_* env vars in build.rs.
  • Using something like cfg(profile = "cli").

None of these work. Is this information retrievable in either of these contexts?

I imagine another thing that might work is to add some custom key to each profile section in Cargo.toml, but I'm not sure if you can do that.

like image 294
Daniel Porteous Avatar asked Oct 19 '25 15:10

Daniel Porteous


1 Answers

Combining the super helpful suggestions in the comments, I was able to get the profile name like this, leveraging this behavior in cargo:

The output for each profile will be placed in a directory of the same name as the profile in the target directory. As in the example above, the output would go into the target/release-lto directory.

Code:

build.rs:

fn main() {}

Note, main can do stuff if you want, all that matters is that it exists.

main.rs:

fn get_build_profile_name() -> String {
    // The profile name is always the 3rd last part of the path (with 1 based indexing).
    // e.g. /code/core/target/cli/build/my-build-info-9f91ba6f99d7a061/out
    std::env!("OUT_DIR")
        .split(std::path::MAIN_SEPARATOR)
        .nth_back(3)
        .unwrap_or_else(|| "unknown")
        .to_string()
}

fn main() {
    let build_profile_name = get_build_profile_name(); 
    println!("Build profile name: {}", build_profile_name);
}

Run command:

cargo run --profile performance

Output:

Build profile name: performance

Note: This method does not work specifically for the dev, test, and bench pre-included build profiles:

cargo run --profile bench
/code/core/target/release/build/my-build-info-9f91ba6f99d7a061/out

The reason is this, described here:

For historical reasons, the dev and test profiles are stored in the debug directory, and the release and bench profiles are stored in the release directory. User-defined profiles are stored in a directory with the same name as the profile.

I'll leave this question open for now in case there is some other approach we haven't thought of yet.

like image 97
Daniel Porteous Avatar answered Oct 21 '25 05:10

Daniel Porteous



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!