Search code examples
testingrustconditional-compilation

What is the proper way to define custom attributes for conditional compilation?


I'd like to be able to pass a flag to cargo test to enable logging in my tests, when I need to debug them.

I've come up with something like:

#[cfg(logging)]
// An internal module where I define some helper to configure logging
// I use `tracing` internally.
use crate::logging;

#[test]
fn mytest() {
    #[cfg(logging)]
    logging::enable();
    // ..
    assert!(true);
}

Then I can enable the logs with

RUSTFLAGS="--cfg logging" cargo test

It works but it feels like I'm abusing the rustc flag system. It also has the side effect of recompiling all the crates with my logging flag, which (besides the fact that it takes ages) may be an issue if this flag is used by one of my dependency some day.

Is there a better way to define and use custom attributes? I could add a feature to my cargo manifest, but this is not really a feature since it's just for the tests.


Solution

  • You wouldn't usually recompile your application, there's no need to: you can use an environment variable. For example:

    if std::env::var("MY_LOG").is_ok() {
        logging::enable();
    }
    

    You can then dynamically decide to log by calling your application with

    MY_LOG=true cargo run
    

    or, when already compiled,

    MY_LOG=true myapp
    

    You would usually configure more than just whether the log is on, for example the log level or the level destination. Here's a real example: https://github.com/Canop/broot/blob/master/src/main.rs#L20