条件编译
语法
ConfigurationPredicate :
ConfigurationOption
| ConfigurationAll
| ConfigurationAny
| ConfigurationNotConfigurationOption :
IDENTIFIER (=
(STRING_LITERAL | RAW_STRING_LITERAL))?ConfigurationAll
all
(
ConfigurationPredicateList?)
ConfigurationAny
any
(
ConfigurationPredicateList?)
ConfigurationNot
not
(
ConfigurationPredicate)
ConfigurationPredicateList
ConfigurationPredicate (,
ConfigurationPredicate)*,
?
条件编译源代码是指仅在特定条件下编译的源代码。
可以使用 cfg
和 cfg_attr
属性以及内置的 cfg
宏来有条件地编译源代码。
是否编译可以取决于已编译 crate 的目标架构、传递给编译器的任意值以及下文进一步描述的其他内容。
每种形式的条件编译都采用一个配置谓词,该谓词评估为 true 或 false。该谓词是以下之一
- 配置选项。如果设置了该选项,则谓词为 true;如果未设置,则为 false。
all()
带有逗号分隔的配置谓词列表。如果所有给定的谓词都为 true,或者列表为空,则为 true。
any()
带有逗号分隔的配置谓词列表。如果至少一个给定的谓词为 true,则为 true。如果没有谓词,则为 false。
not()
带有配置谓词。如果其谓词为 false,则为 true;如果其谓词为 true,则为 false。
配置选项可以是名称或键值对,并且可以设置为已设置或未设置。
名称写为单个标识符,例如 unix
。
键值对写为标识符、=
,然后是字符串,例如 target_arch = "x86_64"
。
注意:
=
周围的空格将被忽略,因此foo="bar"
和foo = "bar"
是等效的。
键不需要是唯一的。例如,可以同时设置 feature = "std"
和 feature = "serde"
。
设置配置选项
哪些配置选项被设置是在 crate 编译期间静态确定的。
某些选项是编译器设置的,基于有关编译的数据。
其他选项是任意设置的,基于代码外部传递给编译器的输入。
无法从正在编译的 crate 的源代码中设置配置选项。
注意: 对于
rustc
,任意设置的配置选项使用--cfg
标志设置。可以使用rustc --print cfg --target $TARGET
显示指定目标的配置值。
注意: 键为
feature
的配置选项是 Cargo 使用的约定,用于指定编译时选项和可选依赖项。
警告: 任意设置的配置选项可能会与编译器设置的配置选项冲突。例如,可以执行
rustc --cfg "unix" program.rs
同时编译到 Windows 目标,并同时设置unix
和windows
配置选项。这样做是不明智的。
target_arch
键值选项,使用目标的 CPU 架构设置一次。该值类似于平台目标三元组的第一个元素,但并非完全相同。
示例值
"x86"
"x86_64"
"mips"
"powerpc"
"powerpc64"
"arm"
"aarch64"
target_feature
键值选项,为当前编译目标可用的每个平台功能设置。
示例值
"avx"
"avx2"
"crt-static"
"rdrand"
"sse"
"sse2"
"sse4.1"
有关可用功能的更多详细信息,请参见 target_feature
属性。
crt-static
的附加功能可用于 target_feature
选项,以指示 静态 C 运行时可用。
target_os
键值选项,使用目标操作系统设置一次。此值类似于平台目标三元组的第二和第三个元素。
示例值
"windows"
"macos"
"ios"
"linux"
"android"
"freebsd"
"dragonfly"
"openbsd"
"netbsd"
"none"
(嵌入式目标的典型值)
target_family
键值选项,提供目标的更通用描述,例如目标通常所属的操作系统或架构系列。可以设置任意数量的 target_family
键值对。
示例值
"unix"
"windows"
"wasm"
"unix"
和"wasm"
两者
unix
和 windows
如果设置了 target_family = "unix"
,则设置 unix
。
如果设置了 target_family = "windows"
,则设置 windows
。
target_env
键值选项,使用有关 ABI 或使用的 libc
的信息进一步消除目标平台的歧义。由于历史原因,仅当实际需要消除歧义时,此值才被定义为非空字符串。因此,例如,在许多 GNU 平台上,此值将为空。此值类似于平台目标三元组的第四个元素。一个不同之处在于,诸如 gnueabihf
之类的嵌入式 ABI 将简单地将 target_env
定义为 "gnu"
。
示例值
""
"gnu"
"msvc"
"musl"
"sgx"
target_abi
键值选项,设置为使用有关目标 ABI 的信息进一步消除 target_env
的歧义。
由于历史原因,仅当实际需要消除歧义时,此值才被定义为非空字符串。因此,例如,在许多 GNU 平台上,此值将为空。
示例值
""
"llvm"
"eabihf"
"abi64"
"sim"
"macabi"
target_endian
键值选项,根据目标 CPU 的字节序设置为 “little” 或 “big” 值一次。
target_pointer_width
键值选项,使用目标的指针宽度(以位为单位)设置一次。
示例值
"16"
"32"
"64"
target_vendor
键值选项,使用目标的供应商设置一次。
示例值
"apple"
"fortanix"
"pc"
"unknown"
target_has_atomic
键值选项,为目标支持原子加载、存储和比较并交换操作的每个位宽度设置。
当存在此 cfg 时,所有稳定的 core::sync::atomic
API 都可用于相关的原子宽度。
可能的值
"8"
"16"
"32"
"64"
"128"
"ptr"
test
在编译测试 harness 时启用。通过使用 --test
标志通过 rustc
完成。有关测试支持的更多信息,请参见 测试。
debug_assertions
默认情况下,在不进行优化的情况下编译时启用。这可以用于在开发中启用额外的调试代码,但在生产环境中不启用。例如,它控制标准库的 debug_assert!
宏的行为。
proc_macro
当正在编译的 crate 使用 proc_macro
crate 类型进行编译时设置。
panic
键值选项,根据 panic 策略设置。请注意,将来可能会添加更多值。
示例值
"abort"
"unwind"
条件编译的形式
cfg
属性
语法
CfgAttrAttribute :
cfg
(
ConfigurationPredicate)
cfg
属性根据配置谓词有条件地包含它所附加的事物。
它写为 cfg
,(
,配置谓词,最后是 )
。
如果谓词为 true,则该事物将被重写为不具有 cfg
属性。如果谓词为 false,则该事物将从源代码中删除。
当 crate 级别的 cfg
具有 false 谓词时,行为略有不同:任何在 cfg
之前的 crate 属性都将被保留,并且任何在 cfg
之后的 crate 属性都将被删除。这允许 #![no_std]
和 #![no_core]
crates 避免链接 std
/core
,即使 #![cfg(...)]
删除了整个 crate。
关于函数的示例
cfg
属性允许在任何允许属性的地方使用。
cfg_attr
属性
语法
CfgAttrAttribute :
cfg_attr
(
ConfigurationPredicate,
CfgAttrs?)
当配置谓词为 true 时,此属性将扩展为谓词之后列出的属性。例如,以下模块将根据目标在 linux.rs
或 windows.rs
中找到。
#[cfg_attr(target_os = "linux", path = "linux.rs")]
#[cfg_attr(windows, path = "windows.rs")]
mod os;
可以列出零个、一个或多个属性。多个属性将分别扩展为单独的属性。例如
#[cfg_attr(feature = "magic", sparkles, crackles)]
fn bewitched() {}
// When the `magic` feature flag is enabled, the above will expand to:
#[sparkles]
#[crackles]
fn bewitched() {}
注意:
cfg_attr
可以扩展为另一个cfg_attr
。例如,#[cfg_attr(target_os = "linux", cfg_attr(feature = "multithreaded", some_other_attribute))]
是有效的。此示例等效于#[cfg_attr(all(target_os = "linux", feature ="multithreaded"), some_other_attribute)]
。
cfg_attr
属性允许在任何允许属性的地方使用。
crate_type
和 crate_name
属性不能与 cfg_attr
一起使用。
cfg
宏
内置的 cfg
宏接受单个配置谓词,并在谓词为 true 时求值为 true
字面量,在谓词为 false 时求值为 false
字面量。
例如