`cfg_aliases`: A New Crate For Creating #[cfg] Aliases

Hey everybody!

I just made the first 0.1.0 release of cfg_aliases, a new crate that allows you to create aliases for cfg checks:

cfg_aliases can help greatly simplify the cfg attribute checks in code that has to do a lot of platform or feature checking. It was developed due to the needs I had while working on gfx and was intentionally designed as a macro_rules! macro with absolutely no dependencies so that it won't increase your compile times noticeably.

Here's a tour:


You use the the cfg_aliases! macro in your build.rs script to define aliases such as x11 that could then be used in the cfg attribute or macro for conditional compilation: #[cfg(x11)] .

Example

Cargo.toml:

[build-dependencies]
cfg_aliases = "0.1.0-alpha.1"

build.rs:

use cfg_aliases::cfg_aliases;

fn main() {
    // Setup cfg aliases
    cfg_aliases! {
        // Platforms
        wasm: { target_arch = "wasm32" },
        android: { target_os = "android" },
        macos: { target_os = "macos" },
        linux: { target_os = "linux" },
        // Backends
        surfman: { all(unix, feature = "surfman", not(wasm)) },
        glutin: { all(feature = "glutin", not(wasm)) },
        wgl: { all(windows, feature = "wgl", not(wasm)) },
        dummy: { not(any(wasm, glutin, wgl, surfman)) },
    }
}

Now that we have our aliases setup we can use them just like you would expect:

#[cfg(wasm)]
println!("This is running in WASM");

#[cfg(surfman)]
{
    // Do stuff related to surfman
}

#[cfg(dummy)]
println!("We're in dummy mode, specify another feature if you want a smarter app!");

This greatly improves what would otherwise look like this without the aliases:

#[cfg(target_arch = "wasm32")]
println!("We're running in WASM");

#[cfg(all(unix, feature = "surfman", not(target_arch = "22")))]
{
    // Do stuff related to surfman
}

#[cfg(not(any(
    target_arch = "wasm32",
    all(unix, feature = "surfman", not(target_arch = "wasm32")),
    all(windows, feature = "wgl", not(target_arch = "wasm32")),
    all(feature = "glutin", not(target_arch = "wasm32")),
)))]
println!("We're in dummy mode, specify another feature if you want a smarter app!");

You can also use the cfg! macro or combine your aliases with other checks using all() , not() , and any() . Your aliases are genuine cfg flags now!

if cfg!(glutin) {
    // use glutin
} else {
    // Do something else
}

#[cfg(all(glutin, surfman))]
compile_error!("You cannot specify both `glutin` and `surfman` features");
6 Likes

When I first read the title I was expecting this to do some sort of proc macro hackery, but I really like the approach you've taken here.

It's quite elegant in that you can figure out how it works by simply skimming through the "getting started" examples and the cfg_aliases!{} macro gives you a really expressive DSL for defining aliases.

Nice! :+1:

2 Likes

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