Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 426
palazzo train Avatar asked Jan 05 '16 03:01

palazzo train


2 Answers

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");
like image 73
Vladimir Matveev Avatar answered Sep 21 '22 11:09

Vladimir Matveev


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.

like image 24
ndrsllwngr Avatar answered Sep 17 '22 11:09

ndrsllwngr