我正在使用一些Rust的不稳定特性,但我仍然希望能够用稳定版本的Rust编译我的库的简化版。 我很乐意只在编译器支持它们时包括这些不稳定特性,在不支持它们时排除它们。
我认为可以使用条件编译轻松实现此目标,例如#[cfg(rust_version = "nightly")]
,但似乎“stable”与“nightly”不是 cfg 选项。
你们如何根据“stable”与“nightly”或编译器版本执行条件编译?
我正在使用一些Rust的不稳定特性,但我仍然希望能够用稳定版本的Rust编译我的库的简化版。 我很乐意只在编译器支持它们时包括这些不稳定特性,在不支持它们时排除它们。
我认为可以使用条件编译轻松实现此目标,例如#[cfg(rust_version = "nightly")]
,但似乎“stable”与“nightly”不是 cfg 选项。
你们如何根据“stable”与“nightly”或编译器版本执行条件编译?
[features]
default = []
nightly-features = []
nightly-features
特性不是默认的,使用稳定版工具链编译可以直接运行。您可以使用属性 #[cfg(feature = "nightly-features")]
和 #[cfg(not(feature = "nightly-features"))]
来包含或排除来自夜间专业版本的代码。这种方法的额外好处是允许独立于编译器测试夜间特性(即回答问题:编译器是否破坏了我的代码,或者由 nightly-features
启用的代码包含错误?)。
build.rs
(放在包根目录下)use std::env;
fn main() {
let rust_toolchain = env::var("RUSTUP_TOOLCHAIN").unwrap();
if rust_toolchain.starts_with("stable") {
// do nothing
} else if rust_toolchain.starts_with("nightly") {
//enable the 'nightly-features' feature flag
println!("cargo:rustc-cfg=feature=\"nightly-features\"");
} else {
panic!("Unexpected value for rustc toolchain")
}
}
src/main.rs
fn main() {
#[cfg(feature = "nightly-features")]
println!("Hello, nightly!");
#[cfg(not(feature = "nightly-features"))]
println!("Hello, stable!");
}
现在运行中
➜ cargo +stable run
Hello, stable!
➜ cargo +nightly run
Hello, nightly!
据我所知,不行。运行cargo +nightly run --no-default-features
仍会保留该功能,因为cargo如何将标志传递给rustc。程序员可以创建一个特定的环境变量,供 build.rs 检查以跳过自动版本检测,但这比没有构建脚本的替代方案更加复杂-cargo build --features=nightly-features
您可以使用rustversion包来代替提议的解决方案,它的工作方式非常相似(但解析rustc --version
的输出)。
fn main() {
#[rustversion(nightly)]
println!("Hello, nightly!");
#[rustversion::not(nightly)]
println!("Hello, stable! (or beta)");
}