How to modify profile.release only for a target?

Indeed, there is no clean / direct way to achieve this. There is a hacky-ish way though: do not directly call cargo build, but call something that will perform some platform detection setting to only then tweak profile.release.

Let's say cargo smart.

cargo smart

First, make sure to add the following files:

.
├── .cargo  // <--
│   └── config  // <--
├── Cargo.toml
├── build.rs  // <-- (Optional)
├── smart  // <--
│   ├── Cargo.toml  // <--
│   └── main.rs  // <--
└── src
    └── lib.rs
    ...
  • .cargo/config

    [alias]
    smart = ["r", "-q", "--manifest-path", "smart/Cargo.toml", "--"]
    
  • smart/Cargo.toml

    [package]
    name = "smart"
    version = "0.0.0"
    edition = "2018"
    
    [[bin]]
    name = "smart"
    path = "main.rs"
    
    [workspace]
    
  • smart/main.rs

    use ::std::{env, ops::Not, process};
    
    fn main ()
    {
        let mut cmd = process::Command::new(::std::env::var("CARGO").unwrap());
        cmd.env("CARGO_SMART", "1");  // Optional, if used with the `build.rs`
        let ref args = env::args().skip(1).collect::<Vec<_>>();
        // dbg!(args); cmd.arg("-vv"); /* Uncomment when debugging this hack */
        cmd.args(args);
        // if args...contains... "--target" "...windows..." ...
        if cfg!(windows) {
            // See https://doc.rust-lang.org/cargo/reference/environment-variables.html#configuration-environment-variables
            cmd.env("CARGO_PROFILE_RELEASE_OPT_LEVEL", "0");
        }
        if cmd.status().ok().map_or(false, |it| it.success()).not() {
            process::exit(-1);
        }
    }
    
  • build.rs (Optional, to make sure we don't forget to call cargo using smart)

    use ::std::{env, ops::Not};
    
    fn main ()
    {
        if env::var("CARGO_SMART").ok().map_or(false, |s| s == "1").not() {
            panic!("Do not run `cargo ...`, run `cargo smart ...` instead")
        }
    }
    

With these changes, cargo smart <usual command> ought to work, such as cargo smart build --release

Feel free to rename smart to something else, and of course to tweak smart/main.rs to correctly handle things like the windows case if cross-compiling (since cfg!(windows) on a build script will only be enabled when running cargo from a Windows environment, not when compiling to one).

2 Likes