Search code examples
rustrust-cargoconditional-compilationcargo-features

How do add a conditional key to an attribute, based on a Cargo feature?


I'm writing a Windows library with FFI to C code, and I'm using the link attribute:

#[link(name = "foo")]

The above works perfectly.

Now, I want to provide a cargo feature which, when included by the user, will enable the raw-dylib key:

[features]
use-raw-dylib = []
#[link(name = "foo")] // without "use-raw-dylib" feature

#[link(name = "foo", kind = "raw-dylib")] // with "use-raw-dylib" feature

This is not the same of conditionally including a whole attribute. I just want to include one key.

How can I implement this conditional?


Solution

  • Rust does not have a built-in way to conditionally transform an attribute, so the easiest way is to duplicate the attribute with and without the key:

    #[cfg_attr(not(feature = "use-raw-dylib"), link(name = "foo"))]
    #[cfg_attr(feature = "use-raw-dylib", link(name = "foo", kind = "raw-dylib"))]
    

    You can create a macro for this, but it's going to be pretty complicated, probably worth a proc macro.