如何从包中的Rust代码中访问Cargo包的元数据(例如版本)?在我的例子中,我正在构建一个命令行工具,我希望它有一个标准的——version标志,并且我希望实现从Cargo读取包的版本。汤姆,这样我就不用在两个地方维护它了。我可以想象,还有其他原因可能会有人想要从程序中访问Cargo元数据。
Cargo通过环境变量将一些元数据传递给编译器,可以在Cargo文档页面中找到环境变量列表。
编译器环境由Cargo代码中的fill_env填充。与早期版本相比,这段代码变得更加复杂,整个变量列表不再明显,因为它可以是动态的。但是,至少在这里设置了以下变量(来自文档中的列表):
CARGO_MANIFEST_DIR
CARGO_PKG_AUTHORS
CARGO_PKG_DESCRIPTION
CARGO_PKG_HOMEPAGE
CARGO_PKG_NAME
CARGO_PKG_REPOSITORY
CARGO_PKG_VERSION
CARGO_PKG_VERSION_MAJOR
CARGO_PKG_VERSION_MINOR
CARGO_PKG_VERSION_PATCH
CARGO_PKG_VERSION_PRE
可以使用env!()宏访问环境变量。要插入程序的版本号,您可以这样做:
const VERSION: &str = env!("CARGO_PKG_VERSION");
// ...
println!("MyProgram v{}", VERSION);
如果你想让你的程序即使没有Cargo也能编译,你可以使用option_env!():
const VERSION: Option<&str> = option_env!("CARGO_PKG_VERSION");
// ...
println!("MyProgram v{}", VERSION.unwrap_or("unknown"));
在构建时(如build.rs中),cargo_metadata可能很有用。例如:
let path = std::env::var("CARGO_MANIFEST_DIR").unwrap();
let meta = MetadataCommand::new()
.manifest_path("./Cargo.toml")
.current_dir(&path)
.exec()
.unwrap();
let root = meta.root_package().unwrap();
let option = root.metadata["my"]["option"].as_str().unwrap();
let version = &root.version;
...
推荐文章
- 字符串向量上的连接运算符等价于什么?
- Rust程序如何从它的Cargo包中访问元数据?
- 为什么在具有240个或更多元素的数组上循环时会有很大的性能影响?
- 为什么Rust中需要显式生命期?
- Rust 1.x中读写文件的实际方式是什么?
- 如何从同一项目的另一个文件中包含模块?
- 我如何创建一个全局的,可变的单例?
- 多行字符串文字的语法是什么?
- Rust的自动解引用规则是什么?
- 为什么Rust的可执行文件如此庞大?
- 我如何分裂一个字符串在Rust?
- 包与库和二进制?
- 为什么我不能在同一个结构中存储一个值和对该值的引用?
- 如何匹配字符串对字符串字面量?
- 为什么Rust编译器不优化代码假设两个可变引用不能别名?