diff options
| author | bors <bors@rust-lang.org> | 2024-06-06 12:52:06 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2024-06-06 12:52:06 +0000 |
| commit | 50297bb417dc338b475fd7cf8b706fa81df85b25 (patch) | |
| tree | e342fcf464d3af26f2c44db354ec2efc6b5b83db /src/bootstrap | |
| parent | 67caf52fbc4f10cdf427f04e6cbb35c8b9d96bb7 (diff) | |
| parent | dd9902118c0cbbcfc35c246673b381072ac5b3a8 (diff) | |
| download | rust-50297bb417dc338b475fd7cf8b706fa81df85b25.tar.gz rust-50297bb417dc338b475fd7cf8b706fa81df85b25.zip | |
Auto merge of #125411 - onur-ozkan:sanity-check-libstdc++, r=Mark-Simulacrum
check host's libstdc++ version when using ci llvm If the host's libstdc++ version is too old using ci-llvm may result in an ABI mismatch between the local libstdc++ and libLLVM.so. This PR adds a sanity check to immediately fail at the beginning of the bootstrap before starting the actual build. I am not sure if '8' is the best threshold, but it should be a good start and we can increase it anytime if needed. Fixes #123037
Diffstat (limited to 'src/bootstrap')
| -rw-r--r-- | src/bootstrap/src/core/build_steps/tool.rs | 54 | ||||
| -rw-r--r-- | src/bootstrap/src/core/sanity.rs | 35 |
2 files changed, 89 insertions, 0 deletions
diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs index 2db3f8f7936..05b19c0a6e3 100644 --- a/src/bootstrap/src/core/build_steps/tool.rs +++ b/src/bootstrap/src/core/build_steps/tool.rs @@ -10,6 +10,7 @@ use crate::core::builder::{Builder, Cargo as CargoCommand, RunConfig, ShouldRun, use crate::core::config::TargetSelection; use crate::utils::channel::GitInfo; use crate::utils::exec::BootstrapCommand; +use crate::utils::helpers::output; use crate::utils::helpers::{add_dylib_path, exe, t}; use crate::Compiler; use crate::Mode; @@ -804,6 +805,59 @@ impl Step for LlvmBitcodeLinker { } } +#[derive(Debug, Clone, Hash, PartialEq, Eq)] +pub struct LibcxxVersionTool { + pub target: TargetSelection, +} + +#[allow(dead_code)] +#[derive(Debug, Clone)] +pub enum LibcxxVersion { + Gnu(usize), + Llvm(usize), +} + +impl Step for LibcxxVersionTool { + type Output = LibcxxVersion; + const DEFAULT: bool = false; + const ONLY_HOSTS: bool = true; + + fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { + run.never() + } + + fn run(self, builder: &Builder<'_>) -> LibcxxVersion { + let out_dir = builder.out.join(self.target.to_string()).join("libcxx-version"); + let _ = fs::remove_dir_all(&out_dir); + t!(fs::create_dir_all(&out_dir)); + + let compiler = builder.cxx(self.target).unwrap(); + let mut cmd = Command::new(compiler); + + let executable = out_dir.join("libcxx-version"); + cmd.arg("-o").arg(&executable).arg(builder.src.join("src/tools/libcxx-version/main.cpp")); + + builder.run_cmd(&mut cmd); + + if !executable.exists() { + panic!("Something went wrong. {} is not present", executable.display()); + } + + let version_output = output(&mut Command::new(executable)); + + let version_str = version_output.split_once("version:").unwrap().1; + let version = version_str.trim().parse::<usize>().unwrap(); + + if version_output.starts_with("libstdc++") { + LibcxxVersion::Gnu(version) + } else if version_output.starts_with("libc++") { + LibcxxVersion::Llvm(version) + } else { + panic!("Coudln't recognize the standard library version."); + } + } +} + macro_rules! tool_extended { (($sel:ident, $builder:ident), $($name:ident, diff --git a/src/bootstrap/src/core/sanity.rs b/src/bootstrap/src/core/sanity.rs index ead38ebc6d5..e3556cb16b0 100644 --- a/src/bootstrap/src/core/sanity.rs +++ b/src/bootstrap/src/core/sanity.rs @@ -16,6 +16,10 @@ use std::path::PathBuf; use std::process::Command; #[cfg(not(feature = "bootstrap-self-test"))] +use crate::builder::Builder; +#[cfg(not(feature = "bootstrap-self-test"))] +use crate::core::build_steps::tool; +#[cfg(not(feature = "bootstrap-self-test"))] use std::collections::HashSet; use crate::builder::Kind; @@ -38,6 +42,11 @@ const STAGE0_MISSING_TARGETS: &[&str] = &[ // just a dummy comment so the list doesn't get onelined ]; +/// Minimum version threshold for libstdc++ required when using prebuilt LLVM +/// from CI (with`llvm.download-ci-llvm` option). +#[cfg(not(feature = "bootstrap-self-test"))] +const LIBSTDCXX_MIN_VERSION_THRESHOLD: usize = 8; + impl Finder { pub fn new() -> Self { Self { cache: HashMap::new(), path: env::var_os("PATH").unwrap_or_default() } @@ -102,6 +111,32 @@ pub fn check(build: &mut Build) { cmd_finder.must_have("git"); } + // Ensure that a compatible version of libstdc++ is available on the system when using `llvm.download-ci-llvm`. + #[cfg(not(feature = "bootstrap-self-test"))] + if !build.config.dry_run() && !build.build.is_msvc() && build.config.llvm_from_ci { + let builder = Builder::new(build); + let libcxx_version = builder.ensure(tool::LibcxxVersionTool { target: build.build }); + + match libcxx_version { + tool::LibcxxVersion::Gnu(version) => { + if LIBSTDCXX_MIN_VERSION_THRESHOLD > version { + eprintln!( + "\nYour system's libstdc++ version is too old for the `llvm.download-ci-llvm` option." + ); + eprintln!("Current version detected: '{}'", version); + eprintln!("Minimum required version: '{}'", LIBSTDCXX_MIN_VERSION_THRESHOLD); + eprintln!( + "Consider upgrading libstdc++ or disabling the `llvm.download-ci-llvm` option." + ); + crate::exit!(1); + } + } + tool::LibcxxVersion::Llvm(_) => { + // FIXME: Handle libc++ version check. + } + } + } + // We need cmake, but only if we're actually building LLVM or sanitizers. let building_llvm = build .hosts |
