6个版本
0.2.1 | 2024年5月10日 |
---|---|
0.2.0 | 2023年12月19日 |
0.1.1 | 2020年10月20日 |
0.1.0 | 2020年4月8日 |
0.1.0-alpha.1 | 2020年4月5日 |
54 在 Rust模式
3,308,665 每月下载量
在 6,198 个crate中(86个直接使用)
20KB
202 行(不含注释)
CFG Aliases
CFG Aliases是一个小巧的工具,可以帮助您在冗长的 #[cfg()]
检查上节省大量精力。此crate提供了一个没有依赖项的单一 cfg_aliases!
宏,并且特别避免了引入 syn
或 quote
,因此对您的编译时间的影响应该可以忽略不计。
您可以在您的 build.rs
脚本中使用 cfg_aliases!
宏来定义别名,例如 x11
,然后可以在 cfg
属性或宏中进行条件编译: #[cfg(x11)]
。
示例
Cargo.toml
[build-dependencies]
cfg_aliases = "0.1.0"
build.rs
use cfg_aliases::cfg_aliases;
fn main() {
// Setup cfg aliases
cfg_aliases! {
// Platforms
wasm: { target_arch = "wasm32" },
android: { target_os = "android" },
macos: { target_os = "macos" },
linux: { target_os = "linux" },
// Backends
surfman: { all(unix, feature = "surfman", not(wasm)) },
glutin: { all(feature = "glutin", not(wasm)) },
wgl: { all(windows, feature = "wgl", not(wasm)) },
dummy: { not(any(wasm, glutin, wgl, surfman)) },
}
}
现在我们已经设置了别名,我们可以像预期的那样使用它们
#[cfg(wasm)]
println!("This is running in WASM");
#[cfg(surfman)]
{
// Do stuff related to surfman
}
#[cfg(dummy)]
println!("We're in dummy mode, specify another feature if you want a smarter app!");
这大大提高了没有使用别名时的样子
#[cfg(target_arch = "wasm32")]
println!("We're running in WASM");
#[cfg(all(unix, feature = "surfman", not(target_arch = "wasm32")))]
{
// Do stuff related to surfman
}
#[cfg(not(any(
target_arch = "wasm32",
all(unix, feature = "surfman", not(target_arch = "wasm32")),
all(windows, feature = "wgl", not(target_arch = "wasm32")),
all(feature = "glutin", not(target_arch = "wasm32")),
)))]
println!("We're in dummy mode, specify another feature if you want a smarter app!");
您还可以使用 cfg!
宏,或者将您的别名与其他检查组合使用 all()
、not()
和 any()
。您的别名现在是真正的 cfg
标志了!
if cfg!(glutin) {
// use glutin
} else {
// Do something else
}
#[cfg(all(glutin, surfman))]
compile_error!("You cannot specify both `glutin` and `surfman` features");
语法和错误信息
别名名称受限于与 Rust 标识符相同的规则,这意味着它们不能包含破折号( -
)。另外,如果您在别名名称等某些语法元素上犯了错误,宏将错误地表示达到递归限制,而不是明确指出实际出了什么问题。这是由于宏解析器的一个细微差别,可能在后续版本的 crate 中得到修复。也有可能在后续版本中支持包含破折号的别名名称。如果您想实现这一点,请提出一个问题。
最后,您还可以通过具有相互引用的规则来诱导无限递归,但这并不是真正的限制,因为这样做在逻辑上本来就没有意义
// This causes an error!
cfg_aliases! {
test1: { not(test2) },
test2: { not(test1) },
}
致谢
- 感谢我的上帝和父亲,是他引导我解决这个问题,我所有的一切都归功于他。
- 感谢 Rust 论坛上的 @Yandros,他 向我展示了 一些疯狂的宏技巧!
- 感谢 @sfackler,他 指出了 使 cargo 添加 cfg 标志的方法。
- 感谢
tectonic_cfg_support::target_cfg
宏的作者,该宏的大部分 cfg 属性解析逻辑都从中借鉴而来。还要感谢 @ratmice 在 Rust 论坛上 提出 了这个问题。