Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions compiler/rustc_session/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1754,6 +1754,21 @@ fn parse_jobs_all(
},
};

// If reproducible compilation is enabled we lower frontend parallelism to 1,
// hopefully we'll be able to do better in the future.
let reproducible = match parse_reproducible(matches.opt_str("reproducible").as_deref()) {
Ok(reproducible) => reproducible,
Err(()) => {
let msg = "`--reproducible`: expected of of `none`, `binaries`, `diagnostics`, \
or `binaries,diagnostics`";
early_dcx.early_fatal(msg);
}
};
let frontend = match frontend {
Some(n) if !reproducible || n.get() == 1 => Some(n), // respect `sync`
_ => None,
};

Jobs { frontend, backend, linker }
}

Expand Down Expand Up @@ -1788,6 +1803,16 @@ fn parse_jobs_one(
(n > 1).then_some(NonZero::new(usize::from(n)).unwrap())
}

fn parse_reproducible(s: Option<&str>) -> Result<bool, ()> {
match s {
None | Some("none") => Ok(false),
Some("binaries" | "diagnostics" | "binaries,diagnostics" | "diagnostics,binaries") => {
Ok(true)
}
_ => Err(()),
}
}

pub fn build_configuration(sess: &Session, mut user_cfg: Cfg) -> Cfg {
// First disallow some configuration given on the command line
cfg::disallow_cfgs(sess, &user_cfg);
Expand Down Expand Up @@ -2128,6 +2153,14 @@ pub fn rustc_optgroups() -> Vec<RustcOptGroup> {
"Limit on the number of parallel jobs used by linker",
"<N>",
),
opt(
Unstable,
Opt,
"",
"reproducible",
"Try making some of the compiler outputs reproducible, possibly at cost of compilation speed",
"BOOL",
),
];
options.extend(verbose_only.into_iter().map(|mut opt| {
opt.is_verbose_help_only = true;
Expand Down
29 changes: 29 additions & 0 deletions src/doc/rustc/src/command-line-arguments.md
Original file line number Diff line number Diff line change
Expand Up @@ -531,6 +531,35 @@ then we cannot limit it.

Currently only LLD supports controlling parallelism.

<a id="reproducible"></a>
## `--reproducible`: request reproducible output

By reproducible or deterministic compilation here we'll understand obtaining identical binaries
or other compiler outputs when rustc is run multiple times on the same source code with the same
options and environment.

The reproducibility may be needed in a number of scenarios:
- When compiler outputs are compared to some existing snapshots for testing
(e.g. rustc's own UI test suite).
- When compiler outputs are cached between multiple compilations using tools like sccache.
In this case different outputs will break the caching even if they are functionally equivalent.
- Other scenarios, including security-oriented.

However, in many other scenarios the reproducibility is not an issue, for example:
- Building and running the project to check whether the tests pass, on CI or locally.
- Compiling the project with cargo check to see and fix the reported errors.

This option accepts the following values - `none`, `binaries`, `diagnostics`,
`binaries,diagnostics`, or `diagnostics,binaries`.

The default is `binaries,diagnostics`, unless rustc frontend parallelism is enabled with
`--jobs` or `--jobs-frontend`.

Currently `--reproducible=value` for any value except `none` will just reduce the frontend
parallelism to 1, but we hope to do something better in the future. For example keeping at least
some parallelism in `--reproducible=binaries,diagnostics` cases, or enabling more optimizations for
`--reproducible=none`, even in single-threaded mode.

<a id="at-path"></a>
## `@path`: load command-line flags from a path

Expand Down
2 changes: 2 additions & 0 deletions tests/ui/compile-flags/jobs/jobs-fail-conflict.h.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
error: Option 'reproducible' given more than once

5 changes: 4 additions & 1 deletion tests/ui/compile-flags/jobs/jobs-fail-conflict.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//@ revisions: a b c d e f g
//@ revisions: a b c d e f g h
//@ ignore-parallel-frontend option conflicts
//@ compile-flags: -Z unstable-options

Expand All @@ -21,4 +21,7 @@
//@[g] compile-flags: --jobs 1 --jobs 2
//[g]~? RAW Option 'jobs' given more than once

//@[h] compile-flags: --reproducible true --reproducible false
//[h]~? RAW Option 'reproducible' given more than once

fn main() {}
2 changes: 2 additions & 0 deletions tests/ui/compile-flags/jobs/jobs-fail-gate.g.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
error: the `-Z unstable-options` flag must also be passed to enable the flag `reproducible`

5 changes: 4 additions & 1 deletion tests/ui/compile-flags/jobs/jobs-fail-gate.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//@ revisions: a b c d e f
//@ revisions: a b c d e f g

//@[a] compile-flags: -j 2
//@[b] compile-flags: --jobs 2
Expand All @@ -14,4 +14,7 @@
//@[f] compile-flags: --jobs-linker 2
//[f]~? RAW the `-Z unstable-options` flag must also be passed to enable the flag `jobs-linker`

//@[g] compile-flags: --reproducible=yes
//[g]~? RAW the `-Z unstable-options` flag must also be passed to enable the flag `reproducible`

fn main() {}
5 changes: 5 additions & 0 deletions tests/ui/compile-flags/jobs/jobs-fail-range.m.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
error: Argument to option 'reproducible' missing

@petrochenkov petrochenkov Aug 3, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

enum OptionKind doesn't currently support optional arguments for top level options (i.e. both --reproducible and --reproducible=yes are supported).
It can be added later if it becomes necessary, but for now I just kept things as is.

View changes since the review

Usage:
--reproducible BOOL Try making some of the compiler outputs reproducible,
possibly at cost of compilation speed

2 changes: 2 additions & 0 deletions tests/ui/compile-flags/jobs/jobs-fail-range.n.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
error: `--reproducible`: expected of of `none`, `binaries`, `diagnostics`, or `binaries,diagnostics`

6 changes: 5 additions & 1 deletion tests/ui/compile-flags/jobs/jobs-fail-range.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//@ revisions: a b c d e f g h i j k l
//@ revisions: a b c d e f g h i j k l m n
//@ compile-flags: -Z unstable-options

//@[a] compile-flags: -j 256
Expand All @@ -23,9 +23,13 @@
//@[j] compile-flags: --jobs
//@[k] compile-flags: -Zthreads
//@[l] compile-flags: -Zno-parallel-backend
//@[m] compile-flags: --reproducible
//@[n] compile-flags: --reproducible nonsense
//[i]~? RAW Argument to option 'j' missing
//[j]~? RAW Argument to option 'jobs' missing
//[k]~? ERROR unstable option `threads` requires a string
//[l]~? ERROR `-Zno-parallel-backend` is removed, use `--jobs-backend=1` instead
//[m]~? RAW Argument to option 'reproducible' missing
//[n]~? ERROR `--reproducible`: expected of of `none`, `binaries`, `diagnostics`, or `binaries,diagnostics`

fn main() {}
3 changes: 2 additions & 1 deletion tests/ui/compile-flags/jobs/jobs-pass.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
//@[c] compile-flags: -j 255
//@[d] compile-flags: --jobs 16 --jobs-frontend 8 --jobs-backend 4 --jobs-linker 2
//@[e] compile-flags: --jobs 16 -Zthreads=8 --jobs-backend 4
//@[g] compile-flags: -Zthreads=1 -Zthreads=2
//@[f] compile-flags: -Zthreads=1 -Zthreads=2
//@[g] compile-flags: --jobs 16 --reproducible=binaries,diagnostics

fn main() {}
Loading