Description
The Compiled Binary Files Are Inconsistent After the Directory of the Rust Package Is Changed.
It is important to have reproducible builds.
Let's say I have two crate in my project, crate mangle2 depends on crate mangle1 and they are located in directory1.
root -> /usr1/directory1 $ tree
.
├── mangle1
│ ├── Cargo.toml
│ └── src
│ └── lib.rs
└── mangle2
├── Cargo.toml
└── src
└── lib.rs
mangle1/Cargo.toml file:
[package]
name = "mangle1"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
mangle1/src/lib.rs file:
pub fn sjhadd(left: usize, right: usize) -> usize {
left + right
}
in mangle2/Cargo.toml file, we see mangle2 depends on mangle1.
[package]
name = "mangle2"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
mangle1 = { path = "../mangle1" }
in mangle2/src/lib.rs file
use mangle1::sjhadd;
#[inline(never)]
pub fn super_add(left: usize, right: usize) -> usize {
sjhadd(left, right)
}
Then I went into the mangle2 directory and compiled the whole project.
root -> /usr1/directory1/mangle2 $ cargo build --release -v
Compiling mangle1 v0.1.0 (/usr1/s00659936/rust_program/mangle_disambiguator_test/test2/mangle1)
Running `/root/.rustup/toolchains/nightly-aarch64-unknown-linux-gnu/bin/rustc --crate-name mangle1 --edition=2021 /usr1/s00659936/rust_program/mangle_disambiguator_test/test2/mangle1/src/lib.rs --error-format=json --json=diagnostic-rendered-ansi,artifacts,future-incompat --diagnostic-width=187 --crate-type lib --emit=dep-info,metadata,link -C opt-level=3 -C embed-bitcode=no -C metadata=feabc6ec5051cf34 -C extra-filename=-feabc6ec5051cf34 --out-dir /usr1/s00659936/rust_program/mangle_disambiguator_test/test2/mangle2/target/release/deps -L dependency=/usr1/s00659936/rust_program/mangle_disambiguator_test/test2/mangle2/target/release/deps`
Compiling mangle2 v0.1.0 (/usr1/s00659936/rust_program/mangle_disambiguator_test/test2/mangle2)
Running `/root/.rustup/toolchains/nightly-aarch64-unknown-linux-gnu/bin/rustc --crate-name mangle2 --edition=2021 src/lib.rs --error-format=json --json=diagnostic-rendered-ansi,artifacts,future-incompat --diagnostic-width=187 --crate-type lib --emit=dep-info,metadata,link -C opt-level=3 -C embed-bitcode=no -C metadata=b27aeebcd77b3cf1 -C extra-filename=-b27aeebcd77b3cf1 --out-dir /usr1/s00659936/rust_program/mangle_disambiguator_test/test2/mangle2/target/release/deps -L dependency=/usr1/s00659936/rust_program/mangle_disambiguator_test/test2/mangle2/target/release/deps --extern mangle1=/usr1/s00659936/rust_program/mangle_disambiguator_test/test2/mangle2/target/release/deps/libmangle1-feabc6ec5051cf34.rmeta`
Finished release [optimized] target(s) in 0.19s
when compiling mangle2, we see -C metadata=b27aeebcd77b3cf1.
Then I copied the directory1 directory to another location directory2.
root -> /usr1 $ cp directory1 directory2 -rf
root -> /usr1 $ cd directory2
root -> /usr1/directory2 $ tree
.
├── mangle1
│ ├── Cargo.toml
│ └── src
│ └── lib.rs
└── mangle2
├── Cargo.toml
└── src
└── lib.rs
As before, I went into the mangle2 directory and compiled the whole project.
root -> /usr1/directory2/mangle2 $ cargo build --release -v
Compiling mangle1 v0.1.0 (/usr1/s00659936/rust_program/mangle_disambiguator_test/test2_ba/mangle1)
Running `/root/.rustup/toolchains/nightly-aarch64-unknown-linux-gnu/bin/rustc --crate-name mangle1 --edition=2021 /usr1/s00659936/rust_program/mangle_disambiguator_test/test2_ba/mangle1/src/lib.rs --error-format=json --json=diagnostic-rendered-ansi,artifacts,future-incompat --diagnostic-width=187 --crate-type lib --emit=dep-info,metadata,link -C opt-level=3 -C embed-bitcode=no -C metadata=4bd5b689377ef005 -C extra-filename=-4bd5b689377ef005 --out-dir /usr1/s00659936/rust_program/mangle_disambiguator_test/test2_ba/mangle2/target/release/deps -L dependency=/usr1/s00659936/rust_program/mangle_disambiguator_test/test2_ba/mangle2/target/release/deps`
Compiling mangle2 v0.1.0 (/usr1/s00659936/rust_program/mangle_disambiguator_test/test2_ba/mangle2)
Running `/root/.rustup/toolchains/nightly-aarch64-unknown-linux-gnu/bin/rustc --crate-name mangle2 --edition=2021 src/lib.rs --error-format=json --json=diagnostic-rendered-ansi,artifacts,future-incompat --diagnostic-width=187 --crate-type lib --emit=dep-info,metadata,link -C opt-level=3 -C embed-bitcode=no -C metadata=6bc8f0dbcefdbca3 -C extra-filename=-6bc8f0dbcefdbca3 --out-dir /usr1/s00659936/rust_program/mangle_disambiguator_test/test2_ba/mangle2/target/release/deps -L dependency=/usr1/s00659936/rust_program/mangle_disambiguator_test/test2_ba/mangle2/target/release/deps --extern mangle1=/usr1/s00659936/rust_program/mangle_disambiguator_test/test2_ba/mangle2/target/release/deps/libmangle1-4bd5b689377ef005.rmeta`
Finished release [optimized] target(s) in 0.21s
this time when compiling mangle2, we see -C metadata=6bc8f0dbcefdbca3.
The metadata of the two compilations is different. Therefore, the symbol table names in the generated binary files are different.
_ZN7mangle29super_add17heef584606885c889E change to _ZN7mangle29super_add17h7cd0a6fdff1a3985E
I just copied the project to a different directory and didn't change any code. Compiling in different directories caused binary inconsistencies.
If a single crate is copied to another directory for compilation, this problem does not occur. Binary inconsistency occurs when two crates depend on each other and both crates are copied to another directory.
rustc --version --verbose
:
rustc 1.76.0-nightly (f5dc2653f 2023-11-25)
binary: rustc
commit-hash: f5dc2653fdd8b5d177b2ccbd84057954340a89fc
commit-date: 2023-11-25
host: aarch64-unknown-linux-gnu
release: 1.76.0-nightly
LLVM version: 17.0.5