Conditional compilation issue

Hello,
I want to run a specific command only if it's compile on windows like that :

 if cfg!(target_os = "windows") {
         ansi_term::enable_ansi_support();
 }

But on Linux when i run "cargo run" or "cargo build" I get the following error :

error[E0425]: cannot find function enable_ansi_support in crate ansi_term

I know I can make a setup function with #[cfg(target_os = "windows")] but I would like to know how to use the cfg! method.
Thank you

If you use cfg! as a boolean then all platforms must compile when they see the contents. If you need conditional compilation you must do this:

#[cfg(target_os = "windows")]
ansi_term::enable_ansi_support();

Oh ok ! Thank you !
I thought that this syntax was usable only before function declaration.

If it happens to be a block of code you want to attach the cfg on, then you can do this as follows:

  • instead of:

    if cfg!(...) {
        stuff();
        other_stuff()
    } else {
        else_body()
    }
    
  • you should do:

    #[cfg(...)] {
        stuff();
        other_stuff()
    } #[cfg(not(...))] {
        else_body()
    }
    

Example

#[cfg(debug_assertions)]
const DEBUG: &'static str = "debug";

#[cfg(not(debug_assertions))]
const RELEASE: &'static str = "release";

fn debug_or_release ()
  -> &'static str
{
    #[cfg(debug_assertions)] {
        DEBUG
    } #[cfg(not(debug_assertions))] {
        RELEASE
    }
}

Or if you don't like the repetition in the #[cfg(not(...))] branch, with a macro you can get this:

fn debug_or_release ()
  -> &'static str
{
    if_cfg!([debug_assertions] {
        DEBUG
    } else {
        RELEASE
    })
}

Also, you might want to take a look at cfg_if crate, which is amazing when you have more than one item to apply a cfg to.

Thank you for your help !
@Yandros I don't understand how your code is better than : playground
Could you explain me please ?
I don't find the macro really useful but i'm new to rust so you're explanation would be really nice !

It isn't really better. There are a lot of crates that provide various macros for all sorts of things, but if you're just doing it once or twice, it doesn't make much sense to hide it behind a macro.

Ok ! Thank you for your help !
Have a good day !

The difference lies in that you can have multiple statements affected by a single #[cfg(...)]; my example illustrated that poorly with a block of a single expression, but it can be useful.

For the sake of having DRY code, having to write twice the target of the #[cfg(...)] (+ #[cfg(not(...))]) is suboptimal, hence a macro that let's you write else instead.

If you are new to Rust this is clearly not the most important, so you can skip this detail (especially given that macros use their own "language" / syntax), but later on, macros can be a great tool to avoid code repetition, leading to more maintainable code :slight_smile:

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.