When a Rust binary (executable or dylib) is built, the version information configured in Cargo.toml
has no effect on the binary built, meaning the configured version is not stored inside the binary file.
In Linux, when I use readelf -V
for a .so file, you can see the supported interface (SO Name) is stored under the Version definition section '.gnu.version_d' of the ELF file. For example, the output of 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
The /lib/libnss_files-2.12.so
file is implementing interface version libnss_files.so.2
The readelf -V
output for a Rust or Cargo generated dylib or executable has no such version information. The version config in Cargo.toml
is only used by crates.io.
Moreover, Windows DLLs support storing the version information, not the SONAME interface version name like Linux. A cross-compiled Windows DLL also has no version info. Perhaps this is another question, but I thought I'd raise the point here first.
While I don't think there is an immediate way to use ELF facilities for versioning (they are not cross-platform anyway), it is possible to use version information from Cargo:
const VERSION: &'static str = env!("CARGO_PKG_VERSION");
VERSION
will now be equal to the version specified in the manifest when cargo build
is run. Alternatively, you can use env_opt!()
if you want to build your program without Cargo:
const VERSION: Option<&'static str> = env_opt!("CARGO_PKG_VERSION");
To give an update on the accepted answer. In Rust 2021 the 2nd macro mentioned in the answer (env_opt
) is now accessible via std::option_env
const CARGO_PKG_VERSION: Option<&'static str> = option_env!("CARGO_PKG_VERSION");
And afterwards, you may use it as like
info!("Booting up... VERSION={}", CARGO_PKG_VERSION.unwrap_or("NOT_FOUND"));
Furthermore, as a note, if you want to include, for example, a default config in the binary, the macro std::include_str
might be of interest.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With