Documentation index

Rust

Rust is a general-purpose programming language with emphasis on performance, type safety, concurrency, and memory safety. It references build dependencies through cryptographic hashes recorded in dependency lockfiles. Programs written in Rust are often already reproducible by default, given the original build toolchain is version-matched and build paths are normalized, but this page documents some common issues you may encounter.

Dependency Lockfiles

Some distributions (like Arch Linux, Alpine and Homebrew) rely on the upstream project to commit a dependency lockfile into the repository. In the Rust ecosystem, this file is called Cargo.lock.

Usually this file is automatically respected by cargo build and cargo build --release, but if it can’t satisfy the dependencies in the corresponding Cargo.toml, cargo may re-resolve the dependency tree using the latest semver-compatible versions available, which are going to be different in the future.

To disable this behavior and instead insist on an error, use:

cargo build --locked

Not all distributions use the dependency lockfile, the Debian project is using their own dependency resolver and .buildinfo files.

Diffing the Build Directory

If you encounter an unreproducible binary, you can usually track down the problem to a specific binary by running diffoscope on the target/ directory1.

cargo build --release && mv target target.1
cargo build --release && mv target target.2
diffoscope --html diff.html --exclude-directory-metadata=yes target.1/ target.2/

You can ignore the file .rustc_info.json as well as the files in .fingerprint/2.

If you see a difference in e.g. target.1/release/libfoo.rlib that is a strong indicator the problem is in the foo crate and you can focus your investigation there.

Build Scripts (build.rs)

See stable outputs3.

Embedded Build Time

It is very uncommon for Rust programs to record the date and time the binary has been compiled. If you still need the current time for some reason during the compile, it is recommended to check if the SOURCE_DATE_EPOCH environment variable is set, and only read the current system time if it is not set.

The SOURCE_DATE_EPOCH environment variable has it’s own documentation page that also contains Rust example code.

rust-embed

The popular crate rust-embed contains macros to embed additional files into the compiled binary. This is often used to bundle web assets. By default, it also records the filesystem metadata of those files, including the modification time.

This can be turned off using the deterministic-timestamps feature.

[dependencies]
rust-embed = { version = "8.5.0", features = ["deterministic-timestamps"] }

Footnotes


Documentation index