From dfed68810738eb437ec55dec3d29b6d341b839c9 Mon Sep 17 00:00:00 2001 From: Seth Junot Date: Thu, 6 Nov 2025 23:00:35 -0800 Subject: [PATCH 1/5] bootstrap: respect `build.python` on macOS The `python()` method was hardcoded to return `/usr/bin/python3` on macOS, ignoring the `build.python` config option. This change respects the config while maintaining the system Python as the default. --- src/bootstrap/src/lib.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index d646e3badb415..dfee211c2ab66 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -1525,10 +1525,11 @@ impl Build { /// Path to the python interpreter to use fn python(&self) -> &Path { if self.config.host_target.ends_with("apple-darwin") { - // Force /usr/bin/python3 on macOS for LLDB tests because we're loading the - // LLDB plugin's compiled module which only works with the system python - // (namely not Homebrew-installed python) - Path::new("/usr/bin/python3") + // LLDB tests require the Python version the LLDB plugin was built for. + // On macOS, the system Python/LLDB are compatible. Many users install + // Homebrew Python but not Homebrew LLVM, so default to system Python. + // Can be overridden via `build.python` for custom LLVM installations. + self.config.python.as_deref().unwrap_or_else(|| Path::new("/usr/bin/python3")) } else { self.config .python From 95a4fa5ddbcef78f9342c47aeddb19e7f8ded6a6 Mon Sep 17 00:00:00 2001 From: Seth Junot Date: Fri, 7 Nov 2025 02:39:45 -0800 Subject: [PATCH 2/5] The default on macOS is clarified in bootstrap.example.toml --- bootstrap.example.toml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/bootstrap.example.toml b/bootstrap.example.toml index 6f37e51a47de2..1fa28ece62c96 100644 --- a/bootstrap.example.toml +++ b/bootstrap.example.toml @@ -322,7 +322,9 @@ # Python interpreter to use for various tasks throughout the build, notably # rustdoc tests, the lldb python interpreter, and some dist bits and pieces. # -# Defaults to the Python interpreter used to execute x.py. +# Defaults to the Python interpreter used to execute x.py, or /usr/bin/python3 +# on macOS. Note that LLDB tests require a Python version compatible with the +# LLDB plugin to be loaded. #build.python = "python" # The path to (or name of) the resource compiler executable to use on Windows. From 8295d33aa51904298002fd698d549947e6a2e29a Mon Sep 17 00:00:00 2001 From: Seth Junot Date: Fri, 7 Nov 2025 03:11:59 -0800 Subject: [PATCH 3/5] The change to bootstrap.example.toml is noted in change_tracker.rs --- src/bootstrap/src/utils/change_tracker.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/bootstrap/src/utils/change_tracker.rs b/src/bootstrap/src/utils/change_tracker.rs index 921f57eb66d6e..3766eab1f4be1 100644 --- a/src/bootstrap/src/utils/change_tracker.rs +++ b/src/bootstrap/src/utils/change_tracker.rs @@ -576,4 +576,9 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[ severity: ChangeSeverity::Info, summary: "`llvm.enzyme` now works with `download-ci-llvm=true`.", }, + ChangeInfo { + change_id: 148636, + severity: ChangeSeverity::Info, + summary: "The `build.python` option is now respected on macOS (previously ignored).", + }, ]; From 4f6d373bc0544bcf40823a7d11ad8032dab9252d Mon Sep 17 00:00:00 2001 From: Seth Junot Date: Fri, 7 Nov 2025 13:00:29 -0800 Subject: [PATCH 4/5] Move default Python selection to sanity.rs --- src/bootstrap/src/core/sanity.rs | 48 ++++++++++++++++++++++---------- 1 file changed, 34 insertions(+), 14 deletions(-) diff --git a/src/bootstrap/src/core/sanity.rs b/src/bootstrap/src/core/sanity.rs index ed63b2aae452c..7e88759da22ef 100644 --- a/src/bootstrap/src/core/sanity.rs +++ b/src/bootstrap/src/core/sanity.rs @@ -1,9 +1,10 @@ -//! Sanity checking performed by bootstrap before actually executing anything. +//! Sanity checking and tool selection performed by bootstrap. //! -//! This module contains the implementation of ensuring that the build -//! environment looks reasonable before progressing. This will verify that -//! various programs like git and python exist, along with ensuring that all C -//! compilers for cross-compiling are found. +//! This module ensures that the build environment is correctly set up before +//! executing any build tasks. It verifies that required programs exist (like +//! git and cmake when needed), selects appropriate tools based on the environment +//! and platform requirements (like choosing the correct Python interpreter), +//! and validates that C compilers for cross-compiling are available. //! //! In theory if we get past this phase it's a bug if a build fails, but in //! practice that's likely not true! @@ -165,15 +166,34 @@ than building it. crate::exit!(1); } - build.config.python = build - .config - .python - .take() - .map(|p| cmd_finder.must_have(p)) - .or_else(|| env::var_os("BOOTSTRAP_PYTHON").map(PathBuf::from)) // set by bootstrap.py - .or_else(|| cmd_finder.maybe_have("python")) - .or_else(|| cmd_finder.maybe_have("python3")) - .or_else(|| cmd_finder.maybe_have("python2")); + // Select the Python interpreter to use throughout the build. + // + // On macOS, LLDB tests require the Python version the LLDB plugin was built for. + // The system Python/LLDB are compatible, and many users install Homebrew Python + // but not Homebrew LLVM, so we default to the system Python (/usr/bin/python3). + // This can be overridden via the `build.python` config option for custom LLVM installations. + // + // On other platforms, we prefer the Python interpreter that invoked bootstrap.py + // (available via the BOOTSTRAP_PYTHON env var), then fall back to searching PATH + // for python, python3, or python2. + build.config.python = if build.host_target.ends_with("apple-darwin") { + build + .config + .python + .take() + .map(|p| cmd_finder.must_have(p)) + .or_else(|| Some(PathBuf::from("/usr/bin/python3"))) + } else { + build + .config + .python + .take() + .map(|p| cmd_finder.must_have(p)) + .or_else(|| env::var_os("BOOTSTRAP_PYTHON").map(PathBuf::from)) // set by bootstrap.py + .or_else(|| cmd_finder.maybe_have("python")) + .or_else(|| cmd_finder.maybe_have("python3")) + .or_else(|| cmd_finder.maybe_have("python2")) + }; build.config.nodejs = build .config From 3904658574f707e54cf76d67e15866fb5cedf98f Mon Sep 17 00:00:00 2001 From: Seth Junot Date: Fri, 7 Nov 2025 13:07:06 -0800 Subject: [PATCH 5/5] Inline the .expect() from bootstrap::python() and remove it The choice of default for macOS was moved to sanity::check() --- src/bootstrap/src/core/build_steps/test.rs | 12 ++++++++++-- src/bootstrap/src/lib.rs | 16 ---------------- 2 files changed, 10 insertions(+), 18 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index b66f965cd555b..57a349c2bf997 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -2075,7 +2075,13 @@ Please disable assertions with `rust.debug-assertions = false`. cmd.arg("--target-rustcflags").arg(flag); } - cmd.arg("--python").arg(builder.python()); + cmd.arg("--python").arg( + builder + .config + .python + .as_ref() + .expect("python is required for running LLDB or rustdoc tests"), + ); // FIXME(#148099): Currently we set these Android-related flags in all // modes, even though they should only be needed in "debuginfo" mode, @@ -3359,7 +3365,9 @@ impl Step for BootstrapPy { } fn run(self, builder: &Builder<'_>) -> Self::Output { - let mut check_bootstrap = command(builder.python()); + let mut check_bootstrap = command( + builder.config.python.as_ref().expect("python is required for running bootstrap tests"), + ); check_bootstrap .args(["-m", "unittest", "bootstrap_test.py"]) // Forward command-line args after `--` to unittest, for filtering etc. diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index dfee211c2ab66..093db739e6cb2 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -1522,22 +1522,6 @@ impl Build { self.config.target_config.get(&target).and_then(|t| t.qemu_rootfs.as_ref()).map(|p| &**p) } - /// Path to the python interpreter to use - fn python(&self) -> &Path { - if self.config.host_target.ends_with("apple-darwin") { - // LLDB tests require the Python version the LLDB plugin was built for. - // On macOS, the system Python/LLDB are compatible. Many users install - // Homebrew Python but not Homebrew LLVM, so default to system Python. - // Can be overridden via `build.python` for custom LLVM installations. - self.config.python.as_deref().unwrap_or_else(|| Path::new("/usr/bin/python3")) - } else { - self.config - .python - .as_ref() - .expect("python is required for running LLDB or rustdoc tests") - } - } - /// Temporary directory that extended error information is emitted to. fn extended_error_dir(&self) -> PathBuf { self.out.join("tmp/extended-error-metadata")