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. 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/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 diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index d646e3badb415..093db739e6cb2 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -1522,21 +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") { - // 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") - } 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") 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).", + }, ];