有没有办法将版本信息存储在 Rust 编译的可执行文件或库中?

Is there a way to store the version information in a Rust compiled executable or library?

构建 Rust 二进制文件(可执行文件或 dylib)时,Cargo.toml 中配置的版本信息对构建的二进制文件没有影响,这意味着配置的版本不存储在二进制文件中。

在Linux中,当我对.so文件使用readelf -V时,您可以看到支持的接口(SO名称)存储在版本定义部分'。 ELF文件的gnu.version_d'。例如readelf -V /lib/libnss_files-2.12.so的输出:

Version definition section '.gnu.version_d' contains 2 entries:
   Addr: 0x0000000000001540  Offset: 0x001540  Link: 5 (.dynstr)
   000000: Rev: 1  Flags: BASE   Index: 1  Cnt: 1  Name: libnss_files.so.2
   0x001c: Rev: 1  Flags: none  Index: 2  Cnt: 1  Name: GLIBC_PRIVATE

/lib/libnss_files-2.12.so 文件正在实现接口版本 libnss_files.so.2

Rust 或 Cargo 生成的 dylib 或可执行文件的 readelf -V 输出没有此类版本信息。 Cargo.toml中的版本配置仅供crates.io使用。

此外、Windows DLL 支持存储版本信息,而不是像Linux 那样的SONAME 接口版本名称。交叉编译的 Windows DLL 也没有版本信息。也许这是另一个问题,但我想我会先在这里提出这一点。

虽然我认为没有立即使用 ELF 工具进行版本控制的方法(它们不是 cross-platform),但可以使用来自 Cargo 的版本信息:

const VERSION: &'static str = env!("CARGO_PKG_VERSION");
cargo build 为 运行 时,

VERSION 现在将等于清单中指定的版本。或者,如果你想在没有 Cargo 的情况下构建你的程序,你可以使用 env_opt!():

const VERSION: Option<&'static str> = env_opt!("CARGO_PKG_VERSION");

使用 winres(https://github.com/mxre/winres) 可以设置 CARGO_PKG_VERSION 到 dll 文件版本,也许对其他人有帮助

更新已接受的答案。在 Rust 2021 中,答案 (env_opt) 中提到的第二个宏现在可以通过 std::option_env

访问
const CARGO_PKG_VERSION: Option<&'static str> = option_env!("CARGO_PKG_VERSION");

之后,您可以像这样使用它

info!("Booting up... VERSION={}", CARGO_PKG_VERSION.unwrap_or("NOT_FOUND"));

此外,请注意,如果您想在二进制文件中包含默认配置,宏 std::include_str 可能会很有趣。