-
-
Notifications
You must be signed in to change notification settings - Fork 0
Syntax
1. Simplified syntax
2. Legacy syntax
3. Macros
target_cfg!
match_cfg!
meta_cfg
4. Predicates
5. Aliases
6. Modifiers
Activate (+)
Deactivate (-)
Panic (@)
7. Customization
Simplified syntax uses aliases and predicates separated by &
and |
instead of all()
and any()
. Negation is done via !
instead of not()
. You can also group them with parenthesis ()
.
That means that
#[cfg(all(not(windows), any(target_architecture="x86", feature="myfeature")))]
becomes
!windows & (x86:ar | myfeature:ft)
Notes:
-
x86:ar
is a predicate shortcut.ar
meanstarget_architecture
whilex86
is the value targeted. You can get a list of predefined shortcut here. -
windows
is an alias. Aliases don't have predicate shortcuts. You can get a list of predefined aliases here. - Negation
!
can also be used before parenthesis()
. Ex. :windows | !(x86:ar | myfeature:ft)
is valid.
You can also use legacy syntax instead of simplified syntax. The #[cfg()]
part is mandatory.
Notes:
- Legacy and simplified syntax can't be mixed on the same arm.
This macro is used exclusively in the item declaration part of your code. It will panic!
if used inside a function. Contrary to match_cfg!
, any matching arm WILL be included and not all cases are covered with a wildcard(_)
.
target_cfg! {
`simplified or legacy` => {
... [0..N] items ...
},
`simplified or legacy` => {},
}
Notes:
-
The right hand side
{}
braces can be ignored for just 1 item. -
target_cfg! always wrap arm with
doc | (arm)
ifdoc
is not defined in the arm (even for legacy syntax). This allowcargo doc
to always generate documentation for each arm. This feature can be deactivated. More details here
This macro is used exclusively inside functions. The first matching arm is evaluated and all possible values must be covered with a wildcard.
fn foo() {
match_cfg! {
`simplified or legacy` => {
... [0..N] ...
},
`simplified or legacy` => {},
_ => {} // Mandatory wildcard arm.
}
}
// This also works
fn foo() {
let os = match_cfg! {
linux => "linux",
#[cfg(windows)] => "windows",
_ => "unknown"
};
println!("Your operating system is {}", os);
}
meta_cfg is an attribute proc macro and work exactly like cfg but with support of simplified syntax or legacy syntax.
#[meta_cfg(`simplified or legacy`)]
// Legacy
#[meta_cfg(#[cfg(all(not(windows), target_architecture="x86", feature="myfeature")])]
// Simplified
#[meta_cfg(!windows & x86:ar & myfeature:ft)]
Notes:
- Like
target_cfg!
,meta_cfg
always wrap arm withdoc | (arm)
ifdoc
is not defined in the arm (even for legacy syntax). This allowcargo doc
to always generate documentation targeted item. This feature can be deactivated. More details here
Below is the list of predefined aliases with their respective value.
Predicate | Target | Description | Examples |
---|---|---|---|
ar | target_arch | Option set once with the target's CPU architecture. | x86_64:ar arm:ar |
tf | target_feature | Option set for each platform feature available for the current compilation target. | sse4.1:tf avx2:tf |
os | target_os | Option set once with the target's operating system. | ios:os android:os |
fm | target_family | Option providing a more generic description of a target. | unix:fm wasm:fm |
ev | target_env | Option set with further disambiguating information about the target platform. | gnu:ev msvc:ev |
ed | target_endian | Option set once with either a value of "little" or "big" depending on the endianness of the target's CPU. | little:ed big:ed |
pw | target_pointer_width | Option set once with the target's pointer width in bits. | 32:pw 64:pw |
vn | target_vendor | Option set once with the vendor of the target. | apple:vn fortanix:vn |
at | target_has_atomic | Option set for each bit width that the target supports atomic loads, stores, and compare-and-swap operations. | 64:at ptr:at |
ft | feature | Mechanism to express conditional compilation and optional dependencies. | webp:ft std:ft |
pn | panic | Option set depending on the panic strategy. | abort:pn unwind:pn |
_ | n/a | Wildcard is used to write value as is. Ex. : windows:_ become #[cfg(windows)]
|
windows:_ unix:_ |
You can also define your own predicates. See here
Below is the list of predefined aliases with their respective value.
Alias | Value |
---|---|
linux | linux:os |
unix | unix:_ |
windows | windows:_ |
macos | macos:os |
android | android:os |
ios | ios:os |
wasm | wasm:_ |
doc | doc:_ |
test | test:_ |
debug | debug_assertions:_ |
desktop | linux:os | windows: | macos:os_ |
mobile | android:os | ios:os |
You can also define your own aliases. See here
cfg_boost provides 3 arm modifier that must be written as the first character of an arm. They are used for debug testing and will panic! on release compilation.
This behaviour can be changed by inserting
cfg_boost_release_modifier_behaviour = { value = "ignore", force = true }
in the [env]
section of your config.toml
. By doing so, modifiers will be ignored at compile time instead of panic!.
Inserting +
before an arm will activate it.
// First arm will be activated even if the operating system `foo` doesn't exists.
target_cfg!{
+ foo:os => ...,
foo:os => ...,
}
Note : match_cfg! macro can only have 1 +
modifier.
Inserting -
before an arm will deactivate it, even if condition happen to be true.
// #[cfg(all())] is always true but won't activate because of `-`
target_cfg!{
- #[cfg(all())] => ...,
desktop => ...,
}
Note : match_cfg! wildcard arm _
cannot have -
modifier.
Inserting @
before one or many arms will cause the macro to panic! with the details of those arms. This allow you to see what cfg_boost write in the TokenStream. Of course they need to be removed to resume execution.
target_cfg! {
@ desktop => mod desktop_only;,
@ mobile => mod mobile_only;,
}
will panic! with the message
proc macro panicked
message:
*** Macro panicked because some arm have the `@` modifier ***
Arm : desktop
Syntax : Simplified
Modifier : Panic
Predicates : any(target_os = "linux", any(windows, target_os = "macos"))
#[cfg()] : #[cfg(any(doc, any(target_os = "linux", any(windows, target_os = "macos"))))]
#[cfg_attr()] : #[cfg_attr(docsrs, doc(cfg(any(target_os = "linux", any(windows, target_os = "macos")))))]
Content : mod desktop_only
Arm : mobile
Syntax : Simplified
Modifier : Panic
Predicates : any(target_os = "android", target_os = "ios")
#[cfg()] : #[cfg(any(doc, any(target_os = "android", target_os = "ios")))]
#[cfg_attr()] : #[cfg_attr(docsrs, doc(cfg(any(target_os = "android", target_os = "ios"))))]
Content : mod mobile_only
Ready to customize? See here