The book was located under 'src/doc/trpl' because originally, it was going to be hosted under that URL. Late in the game, before 1.0, we decided that /book was a better one, so we changed the output, but not the input. This causes confusion for no good reason. So we'll change the source directory to look like the output directory, like for every other thing in src/doc.
2.0 KiB
% Conditional Compilation
Rust has a special attribute, #[cfg]
, which allows you to compile code
based on a flag passed to the compiler. It has two forms:
#[cfg(foo)]
# fn foo() {}
#[cfg(bar = "baz")]
# fn bar() {}
They also have some helpers:
#[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:
#[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 of your Cargo.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
:
--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:
#[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
:
#[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 lets you use these kinds of flags
elsewhere in your code, too:
if cfg!(target_os = "macos") || cfg!(target_os = "ios") {
println!("Think Different!");
}
These will be replaced by a true
or false
at compile-time, depending on the
configuration settings.