Posted on :: Tags: , , , ,

Rust allows you to define feature flags to compile certain parts of a binary conditionally. The Cargo Book has an extensive section on them.

The Cargo.toml file can have a [features] section. In this section, features can be defined, and they can enable other features.

[features]
my-feature = []
another-feature = ["my-feature"]

These markers are used in the code as follows:


#[cfg(feature = "my-feature")]
pub mod my_module;

The default features are listed under the default key of the [features] section. If it’s not defined, it’s considered empty, so cargo build supplies no features to the build system by default.

If you don’t want default features added automatically, you can use the --no-default-features option with cargo.

Starting from Rust 1.60, dependencies can be tied to features. When you define a dependency in the [dependencies] section, add optional = true to its options. Then, in [features], use the dep:package syntax.


[dependencies]

pack = { version = "1.0", optional = true }

[features]

my-feature = ["dep:pack"]

This way, Cargo doesn’t compile pack if my-feature is not enabled.

A caveat to using features is that they should be additive. There shouldn’t be a no-std feature to remove the standard library dependency; instead, you should define a std feature and enable it by default. The reason behind this is that Cargo ensures there is a single copy of a package with all the requested features enabled for the entire dependency graph. If you have a no-x feature that removes functionality, it breaks the additive logic of Cargo’s feature resolution.