2015-04-07 21:16:02 -05:00
|
|
|
|
% Conditional Compilation
|
|
|
|
|
|
2015-04-21 17:52:01 -05:00
|
|
|
|
Rust has a special attribute, `#[cfg]`, which allows you to compile code
|
|
|
|
|
based on a flag passed to the compiler. It has two forms:
|
|
|
|
|
|
|
|
|
|
```rust
|
|
|
|
|
#[cfg(foo)]
|
|
|
|
|
# fn foo() {}
|
|
|
|
|
|
|
|
|
|
#[cfg(bar = "baz")]
|
|
|
|
|
# fn bar() {}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
They also have some helpers:
|
|
|
|
|
|
|
|
|
|
```rust
|
|
|
|
|
#[cfg(any(unix, windows))]
|
|
|
|
|
# fn foo() {}
|
|
|
|
|
|
|
|
|
|
#[cfg(all(unix, target_pointer_width = "32"))]
|
|
|
|
|
# fn bar() {}
|
|
|
|
|
|
|
|
|
|
#[cfg(not(foo))]
|
|
|
|
|
# fn not_foo() {}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
These can nest arbitrarily:
|
|
|
|
|
|
|
|
|
|
```rust
|
|
|
|
|
#[cfg(any(not(unix), all(target_os="macos", target_arch = "powerpc")))]
|
|
|
|
|
# fn foo() {}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
As for how to enable or disable these switches, if you’re using Cargo,
|
|
|
|
|
they get set in the [`[features]` section][features] of your `Cargo.toml`:
|
|
|
|
|
|
2015-05-28 09:18:26 -05:00
|
|
|
|
[features]: http://doc.crates.io/manifest.html#the-%5Bfeatures%5D-section
|
2015-04-21 17:52:01 -05:00
|
|
|
|
|
|
|
|
|
```toml
|
|
|
|
|
[features]
|
|
|
|
|
# no features by default
|
|
|
|
|
default = []
|
|
|
|
|
|
|
|
|
|
# The “secure-password” feature depends on the bcrypt package.
|
|
|
|
|
secure-password = ["bcrypt"]
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
When you do this, Cargo passes along a flag to `rustc`:
|
|
|
|
|
|
2015-04-22 18:26:00 -05:00
|
|
|
|
```text
|
2015-04-21 17:52:01 -05:00
|
|
|
|
--cfg feature="${feature_name}"
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
The sum of these `cfg` flags will determine which ones get activated, and
|
|
|
|
|
therefore, which code gets compiled. Let’s take this code:
|
|
|
|
|
|
|
|
|
|
```rust
|
|
|
|
|
#[cfg(feature = "foo")]
|
|
|
|
|
mod foo {
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
If we compile it with `cargo build --features "foo"`, it will send the `--cfg
|
|
|
|
|
feature="foo"` flag to `rustc`, and the output will have the `mod foo` in it.
|
|
|
|
|
If we compile it with a regular `cargo build`, no extra flags get passed on,
|
|
|
|
|
and so, no `foo` module will exist.
|
|
|
|
|
|
|
|
|
|
# cfg_attr
|
|
|
|
|
|
|
|
|
|
You can also set another attribute based on a `cfg` variable with `cfg_attr`:
|
|
|
|
|
|
|
|
|
|
```rust
|
|
|
|
|
#[cfg_attr(a, b)]
|
|
|
|
|
# fn foo() {}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Will be the same as `#[b]` if `a` is set by `cfg` attribute, and nothing otherwise.
|
|
|
|
|
|
|
|
|
|
# cfg!
|
|
|
|
|
|
|
|
|
|
The `cfg!` [syntax extension][compilerplugins] lets you use these kinds of flags
|
|
|
|
|
elsewhere in your code, too:
|
|
|
|
|
|
|
|
|
|
```rust
|
|
|
|
|
if cfg!(target_os = "macos") || cfg!(target_os = "ios") {
|
|
|
|
|
println!("Think Different!");
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
[compilerplugins]: compiler-plugins.html
|
|
|
|
|
|
|
|
|
|
These will be replaced by a `true` or `false` at compile-time, depending on the
|
|
|
|
|
configuration settings.
|