如何从包中的 Rust 代码访问 Cargo 包的元数据(例如版本)?就我而言,我正在构建一个命令行工具,我希望它有一个标准--version
标志,并且我希望实现从中读取包的版本,Cargo.toml
这样我就不必在两个地方维护它。我可以想象还有其他原因可能有人想要从程序中访问 Cargo 元数据。
问问题
27192 次
3 回答
301
Cargo 通过环境变量将一些元数据传递给编译器,其列表可以在Cargo 文档页面中找到。
编译器环境由fill_env
Cargo 的代码填充。自早期版本以来,此代码变得更加复杂,并且整个变量列表不再明显,因为它可以是动态的。但是,至少在此处设置了以下变量(来自文档中的列表):
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"));
于 2015-01-08T13:32:29.873 回答
18
内置的-crate 有助于在没有所有样板的情况下序列化大量 Cargo 的环境。
于 2017-04-22T12:31:22.093 回答
2
在构建时(如 中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;
...
于 2021-10-27T16:02:03.827 回答