Skip to content

Reproducible Builds: Make target/.fingerprint/.../dep-... dep-info files deterministic#16691

Open
kpcyrd wants to merge 1 commit intorust-lang:masterfrom
kpcyrd:repro-fingerprints
Open

Reproducible Builds: Make target/.fingerprint/.../dep-... dep-info files deterministic#16691
kpcyrd wants to merge 1 commit intorust-lang:masterfrom
kpcyrd:repro-fingerprints

Conversation

@kpcyrd
Copy link

@kpcyrd kpcyrd commented Mar 2, 2026

What does this PR try to resolve?

When debugging unreproducible Rust binaries it's common to diff the build directory contents with something like:

diffoscope --html diff.html --exclude-directory-metadata=yes target.1 target.2

I noticed there's files in target/*/.fingerprint/ that vary each time they are generated. This is because iterating over a HashMap causes the order to be undefined, when using a BTreeMap they are going to be sorted by key. Alternatively there could be an explicit sort() step.

I'm not sure if this is actually a valid source of non-determinism in release binaries (I somewhat doubt this), but making the contents of this folder deterministic makes it easier to diff build directories.

How to test and review this PR?

There's two ways to test this:

  1. Run a regular build, inspect the binary in target/*/.fingerprint/*/dep-* and note that all paths are in alphabetical order
  2. Use the following script:
cargo new --lib foo
for x in foo bar abc xyz; do touch "foo/src/$x.rs"; echo "mod $x;" >> foo/src/lib.rs; done
(cd foo; cargo build && mv target target.1)
(cd foo; cargo build && mv target target.2)
sha256sum foo/target.*/*/.fingerprint/*/dep-*

With my current cargo:

cargo 1.93.1 (083ac5135 2025-12-15)

I get two different files:

c3602b336de8d377331038de8ff588e7c0f0f30f29b7dad83b8aa5f5da4ad6c4  foo/target.1/debug/.fingerprint/foo-6fa3e7cf9a282a7d/dep-lib-foo
3c3f0d3392998d9c0e8a97d5ffbdfe79147383b9065a602d871b952fef6781b6  foo/target.2/debug/.fingerprint/foo-6fa3e7cf9a282a7d/dep-lib-foo

Running diffoscope on those two files gives me this diff:

--- foo/target.1/debug/.fingerprint/foo-6fa3e7cf9a282a7d/dep-lib-foo
+++ foo/target.2/debug/.fingerprint/foo-6fa3e7cf9a282a7d/dep-lib-foo
@@ -1,6 +1,6 @@
 00000000: 0100 0000 ff01 0500 0000 000a 0000 0073  ...............s
-00000010: 7263 2f61 6263 2e72 7300 000a 0000 0073  rc/abc.rs......s
-00000020: 7263 2f6c 6962 2e72 7300 000a 0000 0073  rc/lib.rs......s
+00000010: 7263 2f6c 6962 2e72 7300 000a 0000 0073  rc/lib.rs......s
+00000020: 7263 2f62 6172 2e72 7300 000a 0000 0073  rc/bar.rs......s
 00000030: 7263 2f78 797a 2e72 7300 000a 0000 0073  rc/xyz.rs......s
 00000040: 7263 2f66 6f6f 2e72 7300 000a 0000 0073  rc/foo.rs......s
-00000050: 7263 2f62 6172 2e72 7300 0000 0000       rc/bar.rs.....
+00000050: 7263 2f61 6263 2e72 7300 0000 0000       rc/abc.rs.....

With my patch applied I now get identical files:

% sha256sum foo/target.*/*/.fingerprint/*/dep-*
1f5b2b3d47c6950bedcefc52bb4d5ff17d010570e22c1f48eaf59823b113b6e1  foo/target.1/debug/.fingerprint/foo-6fa3e7cf9a282a7d/dep-lib-foo
1f5b2b3d47c6950bedcefc52bb4d5ff17d010570e22c1f48eaf59823b113b6e1  foo/target.2/debug/.fingerprint/foo-6fa3e7cf9a282a7d/dep-lib-foo

@rustbot rustbot added A-rebuild-detection Area: rebuild detection and fingerprinting S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Mar 2, 2026
@rustbot
Copy link
Collaborator

rustbot commented Mar 2, 2026

r? @ehuss

rustbot has assigned @ehuss.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

Why was this reviewer chosen?

The reviewer was selected based on:

  • Owners of files modified in this PR: @ehuss, @epage, @weihanglo
  • @ehuss, @epage, @weihanglo expanded to ehuss, epage, weihanglo
  • Random selection from ehuss, epage, weihanglo

@epage
Copy link
Contributor

epage commented Mar 2, 2026

Note that our contrib process asks for people to create issues and get agreement before moving onto PRs.

This might seem like a simple change and move straight onto a PR but the question is if it is the right change as changing data structures can have other impacts.

@kpcyrd
Copy link
Author

kpcyrd commented Mar 2, 2026

@epage is it ok to have this discussion here or should I open an issue to discuss? :)

@kpcyrd kpcyrd changed the title Reproducible Builds: Make target/.fingerprint/.../... dep-info files deterministic Reproducible Builds: Make target/.fingerprint/.../dep-... dep-info files deterministic Mar 2, 2026
@kpcyrd
Copy link
Author

kpcyrd commented Mar 3, 2026

fwiw I have a second patch that would make the target/ folder fully deterministic. :)

If you run cargo build, then rm -r target/, and run cargo build again, the build directory would be in a bit-for-bit identical state.

@weihanglo
Copy link
Member

fwiw I have a second patch that would make the target/ folder fully deterministic. :)

If you run cargo build, then rm -r target/, and run cargo build again, the build directory would be in a bit-for-bit identical state.

Awesome!

It would be appreciated if we can have an issue listing your findings :)

@epage
Copy link
Contributor

epage commented Mar 3, 2026

There can be many PR attempts for a topic, either becaus the contributor tries multiple ideas or multiple contributors make attempts over time, etc. Having one Issue consolidates the requirements gathering and design discussion rather than splitting the across multiple PRs.

We're also more likely to search in Issues than PRs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-rebuild-detection Area: rebuild detection and fingerprinting S-waiting-on-review Status: Awaiting review from the assignee but also interested parties.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants