Skip to content

CI for deterministic / reproducible builds #75362

@infinity0

Description

@infinity0
Contributor

#34902 was finally closed as we got a positive result on tests.r-b.org for rustc 1.44.1 on Debian Unstable, where we test for build-path-independent reproducibility. However for rustc 1.45.0 the test turned negative again. (The codenamed suites e.g. "bullseye", "buster", only test for build-path-dependent reproducibility, i.e. are less strict / less ideal)

On the same bug report, @jgalenson had reported build-path-independent reproducibility for a configuration closer to rust's own builds, but this also occasionally regresses e.g. #69352.

The Debian builds and rust's own builds are slightly different; the probably-most-significant one being that Debian uses the system LLVM, so that part is excluded from reproducibility tests. Other than that, it is important to set remap-debuginfo in config.toml as well as -ffile-prefix-map and -fdebug-prefix-map for the C parts of the build, including in CFLAGS / CXXFLAGS.

Since many/most contributors are not aware of all of the details needed to retain build-path-independent reproducibility, it would be good to have some CI to ensure this property in the long run. Running a full build twice is costly, but perhaps some other solution would be just as effective, e.g. running a stage1 build twice, or running it for the beta channel, and/or running with a pre-built LLVM.

Activity

added
A-testsuiteArea: The testsuite used to check the correctness of rustc
C-enhancementCategory: An issue proposing an enhancement or a PR with one.
A-reproducibilityArea: Reproducible / deterministic builds
on Aug 10, 2020
added
T-infraRelevant to the infrastructure team, which will review and decide on the PR/issue.
on Aug 10, 2020
joshtriplett

joshtriplett commented on Aug 10, 2020

@joshtriplett
Member

@infinity0 I would love to see this. Yes, it'll require some extra CI time, but it's worth doing. Reproducible builds are important.

Right now, the critical path in bors is actually macOS builds. I think we could do two builds on every other platform in the time it takes to do one on macOS, without slowing down CI.

In an ideal world, if this test fails, we'd provide diffoscope output as part of the CI log.

Mark-Simulacrum

Mark-Simulacrum commented on Aug 10, 2020

@Mark-Simulacrum
Member

I don't think we can afford to double build on every other platform -- even just doubling CI time on the linux builders would be pretty unfortunate, even though they're not currently the ones blocking auto builds, having them run longer reduces spaces in the pool for PR builders and such too. (Unfortunately we don't currently have metrics to know how much space we have on average).

That said, I do think we can do this on at least some of the dist builders to start. I would pick ones we deem most important (e.g., perhaps x86_64 linux to start).

With regards to implementation, dist builders should already have most of the remapping etc turned on, I believe, and anything that isn't should be reasonable to add (though could be hard, we'd have to see, especially because most dist builders use fairly old toolchains).

Before commenting on how I would suggest going about implementing this in our CI, I would like to hear more about "the details needed to retain build-path-independent reproducibility" -- what would this mean for us? What sort of tooling, environment differences, etc, would we want?

I would also suggest that we start by checking in CI that a smaller crate's reproducibility holds, e.g., std built by the stage 2 compiler. Building std is fast -- usually only 2-3 minutes. But maybe in practice reproducibility in std is rarely broken? Do we have some idea of what we would need/want to test in the long run (e.g., rustc and std only? Cargo and the other tools as well?)

mati865

mati865 commented on Aug 10, 2020

@mati865
Member

What about job that would run biweekly or similar when Homu queue is empty?

Mark-Simulacrum

Mark-Simulacrum commented on Aug 10, 2020

@Mark-Simulacrum
Member

We have no precedent for such and personally I think it's much less useful, nor would that need to be in-tree necessarily.

I also don't think it's out of the picture to double up or builds or so, I just want a better understanding of the requirements before (possibly) agreeing to such.

RalfJung

RalfJung commented on Aug 12, 2020

@RalfJung
Member

An alternative, at least initially, would be to do something like https://github.com/RalfJung/miri-test-libstd: out-of-tree CI which tests the latest nightly every morning.

But I am not sure if there is a free CI service that actually provides enough time budge for building rustc twice.

pietroalbini

pietroalbini commented on Aug 12, 2020

@pietroalbini
Member

During this week's infrastructure team meeting we agreed to dedicate a builder for this! The builder will replace the existing full-bootstrap one. The main requirement we have is that this builder shouldn't take longer than the current slowest builder.

infinity0

infinity0 commented on Aug 14, 2020

@infinity0
ContributorAuthor

I would like to hear more about "the details needed to retain build-path-independent reproducibility" -- what would this mean for us?

It really depends on what feature someone is adding. It's much harder to track it down after the fact, as the debugging on #59542 shows. Off the top of my head, some issues that have affected rustc reproducibility in the past:

To re-iterate, I expect there will be other issues in the future completely unrelated to those in the above list. It really has to be done on a case-by-case basis for each PR.

It's important also to record what input dependencies (crates, build tools) and their versions. For example #59542 was a bug in cargo not rustc itself.

Mark-Simulacrum

Mark-Simulacrum commented on Aug 14, 2020

@Mark-Simulacrum
Member

Hm so that's not quite what I meant but is still helpful.

I guess the right question is - would you (or someone else) be up for submitting a PR with config for testing reproducible builds? If not, what would need to be done to make that possible?

I think the infra team doesn't have anyone who has the background knowledge to actually implement these tests properly, but we'd love to help someone do it.

infinity0

infinity0 commented on Aug 17, 2020

@infinity0
ContributorAuthor

@Mark-Simulacrum a basic test that just builds in two different paths, then compares the resulting artifacts, would already be useful and cover most regressions. The two top-level source directories should have different names - very occasionally builds could depend on that inappropriately.

To get more sophisticated you can vary things like system time, username, timezone, locale, hostname, etc. An in-depth list is here. Many of these are just simple envvar changes; some of them can be done with libc interceptors like libfaketime, or via superuser access, or if running the builds in separate VMs.

22 remaining items

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-reproducibilityArea: Reproducible / deterministic buildsA-testsuiteArea: The testsuite used to check the correctness of rustcC-enhancementCategory: An issue proposing an enhancement or a PR with one.T-infraRelevant to the infrastructure team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      Participants

      @infinity0@joshtriplett@jonhoo@RalfJung@mati865

      Issue actions

        CI for deterministic / reproducible builds · Issue #75362 · rust-lang/rust