From 20cb59be6449224b1418200a245a63bd2fd1302c Mon Sep 17 00:00:00 2001 From: Harmen Stoppels Date: Tue, 3 Feb 2026 16:30:22 +0100 Subject: [PATCH] bootstrap: respect modern jobserver When bootstrapping Rust, the `-j N` flag was passed to CMake, which was then forwarded to Ninja. This prevents the jobserver from being used, and as a result leads to oversubscription when Rust is just one of the many packages built as part of a larger software stack. Since Cargo and the Rust compiler have long supported the jobserver, it would be good if also bootstrapping Rust itself would participate in the protocol, leading to composable parallelism. This change allows bootstrapping to respect an existing FIFO based jobserver. Old pipe based jobservers are not supported, because they are brittle: currently the Python scripts in bootstrap do not inherit the file descriptors, but do pass on `MAKEFLAGS`. Because Ninja only supports FIFO based jobservers, it's better to focus on new jobservers only. In summary: * Bootstrap Cargo passes `MAKEFLAGS` verbatim to subprocesses if it advertises a FIFO style jobserver, otherwise it unsets it. * `llvm.rs` does not pass `-j` to `cmake` when a FIFO style jobserver is set in `MAKEFLAGS. * Bootstrap Cargo no longer unsets `MKFLAGS`: from git blame, GNU Make considered it a historical artifact back in 1992, and it is never read by GNU Make, it's only set for backwards compatibility. Signed-off-by: Harmen Stoppels --- src/bootstrap/src/core/build_steps/llvm.rs | 10 +++++++++- src/bootstrap/src/core/builder/cargo.rs | 14 +++++++++++--- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/llvm.rs b/src/bootstrap/src/core/build_steps/llvm.rs index dbd4f1c814055..ae86874cc99ae 100644 --- a/src/bootstrap/src/core/build_steps/llvm.rs +++ b/src/bootstrap/src/core/build_steps/llvm.rs @@ -773,7 +773,15 @@ fn configure_cmake( .define("CMAKE_CXX_COMPILER", sanitize_cc(&cxx)) .define("CMAKE_ASM_COMPILER", sanitize_cc(&cc)); - cfg.build_arg("-j").build_arg(builder.jobs().to_string()); + // If we are running under a FIFO jobserver, we should not pass -j to CMake; otherwise it + // overrides the jobserver settings and can lead to oversubscription. + let has_modern_jobserver = env::var("MAKEFLAGS") + .map(|flags| flags.contains("--jobserver-auth=fifo:")) + .unwrap_or(false); + + if !has_modern_jobserver { + cfg.build_arg("-j").build_arg(builder.jobs().to_string()); + } let mut cflags = ccflags.cflags.clone(); // FIXME(madsmtm): Allow `cmake-rs` to select flags by itself by passing // our flags via `.cflag`/`.cxxflag` instead. diff --git a/src/bootstrap/src/core/builder/cargo.rs b/src/bootstrap/src/core/builder/cargo.rs index 7150b2b0d59f2..f08632d979051 100644 --- a/src/bootstrap/src/core/builder/cargo.rs +++ b/src/bootstrap/src/core/builder/cargo.rs @@ -547,9 +547,17 @@ impl Builder<'_> { assert_eq!(target, compiler.host); } - // Remove make-related flags to ensure Cargo can correctly set things up - cargo.env_remove("MAKEFLAGS"); - cargo.env_remove("MFLAGS"); + // Bootstrap only supports modern FIFO jobservers. Older pipe-based jobservers can run into + // "invalid file descriptor" errors, as the jobserver file descriptors are not inherited by + // scripts like bootstrap.py, while the environment variable is propagated. So, we pass + // MAKEFLAGS only if we detect a FIFO jobserver, otherwise we clear it. + let has_modern_jobserver = env::var("MAKEFLAGS") + .map(|flags| flags.contains("--jobserver-auth=fifo:")) + .unwrap_or(false); + + if !has_modern_jobserver { + cargo.env_remove("MAKEFLAGS"); + } cargo }