Else case in conditional compile in rust

Viewed 1276

How can I have some code being compiled only when no cfg block match? For example something like this:

#IF NUM == 1
//something
#ELSE IF NUM == 2
// something
#ELSE
// no case match, panic!
#ENDIF
2 Answers

By hand e.g.

#[cfg(thing1)]
// something
#[cfg(all(not(thing1), thing2))]
// something
#[cfg(all(not(thing1), not(thing2)))]
// no case

Alternatively, within a function and if your "something"s are compilable in every case, you can use cfg!. Since it evaluates to a literal there's a good chance the optimiser will strip out the bits which don't match:

if cfg!(thing1) {
    // something
} else if cfg!(thing2) {
    // something
} else {
    panic!();
}

although compile_error would make more sense than panic.

There is also a cfg-if crate for something more ergonomic.

For more on the topic, see the article Yak shaving conditional compilation in Rust which expands on and discusses the various approaches.

You can use not in the conditional part of a cfg block. You can see an example in the docs for cfg

// This function only gets compiled if the target OS is linux
#[cfg(target_os = "linux")]
fn are_you_on_linux() {
    println!("You are running linux!");
}

// And this function only gets compiled if the target OS is *not* linux
#[cfg(not(target_os = "linux"))]
fn are_you_on_linux() {
    println!("You are *not* running linux!");
}

If you need something more complicated you can also use any and all, something like:

#[cfg(target_os="linux")]
fn get_os() -> &str { return "Linux"; }

#[cfg(target_os="windows")]
fn get_os() -> &str { return "Windows"; }

#[cfg(not(any(target_os="linux", target_os="windows")))]
fn get_os() -> &str { return "Unknown"; }

Further details are available in the reference.

Related