3 个版本
使用旧的 Rust 2015
0.1.2 | 2024 年 3 月 15 日 |
---|---|
0.1.1 | 2022 年 10 月 25 日 |
0.1.0 | 2022 年 3 月 23 日 |
#133 in 构建工具
32 每月下载量
用于 6 个crate (3 直接)
37KB
400 行
cfg_rust_features
一个构建脚本辅助工具,用于根据探测您选择的哪些功能在 Rust 编译器、语言和库中启用来设置 cfg
选项,而不参考 Rust 的版本。
主要目的是检测之前不稳定的功能何时变得稳定,基于功能的存在而不是 Rust 版本。这有助于设计条件编译代码,使其能够根据 Rust 未知未来的任何版本中功能何时变得稳定而进行调整。
设置的 cfg
选项是键值形式的,例如:rust_lib_feature = "iter_zip"
,rust_lang_feature = "never_type"
等。
探测不使用 #![feature(...)]
,因此设置的选项表示与 nightly
或 stable
编译器一致稳定的特性。仍然可以使用 rust_comp_feature = "unstable_features"
选项条件性地启用不稳定的功能,该选项可以在使用 nightly
(或 dev
)编译器时检测和设置。
注意
-
在设计围绕可能在不稳定之前发生变化的功能的代码时,必须非常小心。
-
目前,这个crate只支持一小部分特性(包括不稳定和稳定版本)。您可以通过在以下位置打开问题请求支持更多特性:https://github.com/DerickEddington/cfg_rust_features/issues。
示例
-
您的构建脚本,通常是
build.rs
,可以非常简单:fn main() { let of_interest = ["iter_zip", /* Or: "unstable_features", etc ... */]; cfg_rust_features::emit!(of_interest).unwrap(); }
-
要处理稳定Rust版本,您实现了一个绕过方案,以解决您希望使用但尚未稳定的不稳定特性,您不知道它将在哪个未来的版本中成为稳定(如果会的话),但您确信在它稳定之前该特性的API不会改变。因此,借助这个crate,您设计了条件编译,如果该特性变为稳定,则将绕过方案标记为已弃用,并使用该特性。
如果您的绕过方案是在
Result<T, Infallible>
上添加一个into_ok
方法,则这种检测可以像这样完成:#[cfg_attr(rust_lib_feature = "unwrap_infallible", deprecated)] trait IntoOk { /* ... */ } #[cfg(not(rust_lib_feature = "unwrap_infallible"))] impl<T> IntoOk for Result<T, Infallible> { /* ... */ }
-
仅在使用
nightly
(或dev
)编译器时启用不稳定特性#![cfg_attr(rust_comp_feature = "unstable_features", feature(step_trait))] #[cfg(rust_comp_feature = "unstable_features")] fn maybe_use_step_trait() { /* ... */ }
这避免了需要一些Cargo包特性(例如
"unstable"
),这可能是一些项目所希望的。或者,只有在特性尚未稳定时才能启用不稳定特性,并且当特性成为稳定时不再启用,例如
#![cfg_attr(not(rust_lib_feature = "step_trait"), feature(step_trait))] fn assume_step_trait_is_available() { /* ... */ }
-
要具有(截至2022-10-23需要
nightly
编译器)不会干扰使用stable
编译器的基准测试,而无需额外的包特性。这允许使用Cargo选项--all-targets
(包括--benches
),而无需错误地使用stable
编译器,这对于使用该工具特别有帮助。这是在benches/
的顶部完成的,例如#![cfg(rust_comp_feature = "unstable_features")] /* ... */
因此,在
stable
编译器下,benches/
目标实际上是空的,但在nightly
下是非空的,无需记住提供--features
。此外,当Rust的某个未来版本稳定一个特性时,例如基准测试的
test
特性,以及如果这个crate的未来版本增加了对该特性的支持时,目标可以进行调整;并且即使在特性不稳定并且这个crate没有支持时,目标仍然可以工作,例如// If provided by either stable or unstable feature, have this target // be non-empty. #![cfg(any( // Only set/true when the currently-used version of the // cfg_rust_features crate supports it and it is stable in the // currently-used version of Rust. rust_lib_feature = "test", // Only set/true when a nightly (or dev) compiler is being used. rust_comp_feature = "unstable_features" ))] // Else, a stable compiler version without the feature is being used, // so have this target be empty to cause all the below items to be // ignored as if they do not exist. #![cfg_attr( // If the feature is still unstable not(rust_lib_feature = "test"), // then it needs to be specially enabled. feature(test) )] // Else if the feature is stable, #![feature(test)] is not needed. // Valid whenever the feature is enabled, whether stable or unstable. extern crate test; /* ... */
因此,至少在文件顶部,此代码在特性不稳定和后来变为稳定时都不需要更改(除非特性在不稳定时本身发生变化,当然);此外,此代码在Rust的较旧版本中也将继续有效,即使较新版本稳定了该特性。
稳定性策略
API遵循正常的Cargo SemVer策略,但有资格说明,未来版本的错误行为允许有一定的变化
-
未来版本可能改为支持更多的特性名称,因此不再为这些名称报错。但是,一旦支持了特性名称,就不会将其删除,因此未来版本将永远不会报错。
-
未来版本可能改变,在创建
CfgRustFeatures
实例时,在dyn Error
后面返回不同的Error
类型,这是由于探测方式内部的变化以及所使用的依赖项的变化。但是,Box<dyn Error>
类型的使用将保持稳定。
最低支持的Rust版本
Rust 1.0.0
将始终得到支持,因此这个crate可以被支持该旧版本的其它crate使用。
文档
源代码包含文档注释,这些注释将被渲染为API文档。
在线查看: http://docs.rs/cfg_rust_features
或者,您可以通过以下方式自己生成并本地查看:
cargo doc --open
依赖
~48KB