diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:19:03 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:19:03 +0000 |
commit | 64d98f8ee037282c35007b64c2649055c56af1db (patch) | |
tree | 5492bcf97fce41ee1c0b1cc2add283f3e66cdab0 /src/bootstrap/native.rs | |
parent | Adding debian version 1.67.1+dfsg1-1. (diff) | |
download | rustc-64d98f8ee037282c35007b64c2649055c56af1db.tar.xz rustc-64d98f8ee037282c35007b64c2649055c56af1db.zip |
Merging upstream version 1.68.2+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/bootstrap/native.rs')
-rw-r--r-- | src/bootstrap/native.rs | 153 |
1 files changed, 77 insertions, 76 deletions
diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs index f6c453ebe..e0d1504c9 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs @@ -24,9 +24,20 @@ use crate::util::get_clang_cl_resource_dir; use crate::util::{self, exe, output, t, up_to_date}; use crate::{CLang, GitRepo}; +use build_helper::ci::CiEnv; + +#[derive(Clone)] +pub struct LlvmResult { + /// Path to llvm-config binary. + /// NB: This is always the host llvm-config! + pub llvm_config: PathBuf, + /// Path to LLVM cmake directory for the target. + pub llvm_cmake_dir: PathBuf, +} + pub struct Meta { stamp: HashStamp, - build_llvm_config: PathBuf, + res: LlvmResult, out_dir: PathBuf, root: String, } @@ -54,17 +65,17 @@ impl LdFlags { } } -// This returns whether we've already previously built LLVM. -// -// It's used to avoid busting caches during x.py check -- if we've already built -// LLVM, it's fine for us to not try to avoid doing so. -// -// This will return the llvm-config if it can get it (but it will not build it -// if not). +/// This returns whether we've already previously built LLVM. +/// +/// It's used to avoid busting caches during x.py check -- if we've already built +/// LLVM, it's fine for us to not try to avoid doing so. +/// +/// This will return the llvm-config if it can get it (but it will not build it +/// if not). pub fn prebuilt_llvm_config( builder: &Builder<'_>, target: TargetSelection, -) -> Result<PathBuf, Meta> { +) -> Result<LlvmResult, Meta> { builder.config.maybe_download_ci_llvm(); // If we're using a custom LLVM bail out here, but we can only use a @@ -72,7 +83,14 @@ pub fn prebuilt_llvm_config( if let Some(config) = builder.config.target_config.get(&target) { if let Some(ref s) = config.llvm_config { check_llvm_version(builder, s); - return Ok(s.to_path_buf()); + let llvm_config = s.to_path_buf(); + let mut llvm_cmake_dir = llvm_config.clone(); + llvm_cmake_dir.pop(); + llvm_cmake_dir.pop(); + llvm_cmake_dir.push("lib"); + llvm_cmake_dir.push("cmake"); + llvm_cmake_dir.push("llvm"); + return Ok(LlvmResult { llvm_config, llvm_cmake_dir }); } } @@ -84,8 +102,9 @@ pub fn prebuilt_llvm_config( llvm_config_ret_dir.push("build"); } llvm_config_ret_dir.push("bin"); - let build_llvm_config = llvm_config_ret_dir.join(exe("llvm-config", builder.config.build)); + let llvm_cmake_dir = out_dir.join("lib/cmake/llvm"); + let res = LlvmResult { llvm_config: build_llvm_config, llvm_cmake_dir }; let stamp = out_dir.join("llvm-finished-building"); let stamp = HashStamp::new(stamp, builder.in_tree_llvm_info.sha()); @@ -96,7 +115,7 @@ pub fn prebuilt_llvm_config( Using a potentially stale build of LLVM; \ This may not behave well.", ); - return Ok(build_llvm_config); + return Ok(res); } if stamp.is_done() { @@ -110,10 +129,10 @@ pub fn prebuilt_llvm_config( stamp.path.display() )); } - return Ok(build_llvm_config); + return Ok(res); } - Err(Meta { stamp, build_llvm_config, out_dir, root: root.into() }) + Err(Meta { stamp, res, out_dir, root: root.into() }) } /// This retrieves the LLVM sha we *want* to use, according to git history. @@ -200,7 +219,7 @@ pub(crate) fn is_ci_llvm_available(config: &Config, asserts: bool) -> bool { return false; } - if crate::util::CiEnv::is_ci() { + if CiEnv::is_ci() { // We assume we have access to git, so it's okay to unconditionally pass // `true` here. let llvm_sha = detect_llvm_sha(config, true); @@ -223,7 +242,7 @@ pub struct Llvm { } impl Step for Llvm { - type Output = PathBuf; // path to llvm-config + type Output = LlvmResult; const ONLY_HOSTS: bool = true; @@ -236,7 +255,7 @@ impl Step for Llvm { } /// Compile LLVM for `target`. - fn run(self, builder: &Builder<'_>) -> PathBuf { + fn run(self, builder: &Builder<'_>) -> LlvmResult { let target = self.target; let target_native = if self.target.starts_with("riscv") { // RISC-V target triples in Rust is not named the same as C compiler target triples. @@ -252,11 +271,10 @@ impl Step for Llvm { target.to_string() }; - let Meta { stamp, build_llvm_config, out_dir, root } = - match prebuilt_llvm_config(builder, target) { - Ok(p) => return p, - Err(m) => m, - }; + let Meta { stamp, res, out_dir, root } = match prebuilt_llvm_config(builder, target) { + Ok(p) => return p, + Err(m) => m, + }; builder.update_submodule(&Path::new("src").join("llvm-project")); if builder.llvm_link_shared() && target.contains("windows") { @@ -430,7 +448,8 @@ impl Step for Llvm { // https://llvm.org/docs/HowToCrossCompileLLVM.html if target != builder.config.build { - let llvm_config = builder.ensure(Llvm { target: builder.config.build }); + let LlvmResult { llvm_config, .. } = + builder.ensure(Llvm { target: builder.config.build }); if !builder.config.dry_run() { let llvm_bindir = output(Command::new(&llvm_config).arg("--bindir")); let host_bin = Path::new(llvm_bindir.trim()); @@ -480,7 +499,7 @@ impl Step for Llvm { // tools and libs on all platforms. if builder.config.dry_run() { - return build_llvm_config; + return res; } cfg.build(); @@ -490,7 +509,7 @@ impl Step for Llvm { // for a versioned path like libLLVM-14.dylib. Manually create a symbolic // link to make llvm-config happy. if builder.llvm_link_shared() && target.contains("apple-darwin") { - let mut cmd = Command::new(&build_llvm_config); + let mut cmd = Command::new(&res.llvm_config); let version = output(cmd.arg("--version")); let major = version.split('.').next().unwrap(); let lib_name = match llvm_version_suffix { @@ -509,18 +528,18 @@ impl Step for Llvm { // LLVM after a configuration change, so to rebuild it the build files have to be removed, // which will also remove these modified files. if builder.config.llvm_bolt_profile_generate { - instrument_with_bolt_inplace(&get_built_llvm_lib_path(&build_llvm_config)); + instrument_with_bolt_inplace(&get_built_llvm_lib_path(&res.llvm_config)); } if let Some(path) = &builder.config.llvm_bolt_profile_use { optimize_library_with_bolt_inplace( - &get_built_llvm_lib_path(&build_llvm_config), + &get_built_llvm_lib_path(&res.llvm_config), &Path::new(path), ); } t!(stamp.write()); - build_llvm_config + res } } @@ -600,6 +619,9 @@ fn configure_cmake( if target.starts_with("aarch64") { // macOS uses a different name for building arm64 cfg.define("CMAKE_OSX_ARCHITECTURES", "arm64"); + } else if target.starts_with("i686") { + // macOS uses a different name for building i386 + cfg.define("CMAKE_OSX_ARCHITECTURES", "i386"); } else { cfg.define("CMAKE_OSX_ARCHITECTURES", target.triple.split('-').next().unwrap()); } @@ -803,7 +825,21 @@ impl Step for Lld { } let target = self.target; - let llvm_config = builder.ensure(Llvm { target: self.target }); + let LlvmResult { llvm_config, llvm_cmake_dir } = builder.ensure(Llvm { target }); + + // The `dist` step packages LLD next to LLVM's binaries for download-ci-llvm. The root path + // we usually expect here is `./build/$triple/ci-llvm/`, with the binaries in its `bin` + // subfolder. We check if that's the case, and if LLD's binary already exists there next to + // `llvm-config`: if so, we can use it instead of building LLVM/LLD from source. + let ci_llvm_bin = llvm_config.parent().unwrap(); + if ci_llvm_bin.is_dir() && ci_llvm_bin.file_name().unwrap() == "bin" { + let lld_path = ci_llvm_bin.join(exe("lld", target)); + if lld_path.exists() { + // The following steps copying `lld` as `rust-lld` to the sysroot, expect it in the + // `bin` subfolder of this step's out dir. + return ci_llvm_bin.parent().unwrap().to_path_buf(); + } + } let out_dir = builder.lld_out(target); let done_stamp = out_dir.join("lld-finished-building"); @@ -834,22 +870,6 @@ impl Step for Lld { configure_cmake(builder, target, &mut cfg, true, ldflags); configure_llvm(builder, target, &mut cfg); - // This is an awful, awful hack. Discovered when we migrated to using - // clang-cl to compile LLVM/LLD it turns out that LLD, when built out of - // tree, will execute `llvm-config --cmakedir` and then tell CMake about - // that directory for later processing. Unfortunately if this path has - // forward slashes in it (which it basically always does on Windows) - // then CMake will hit a syntax error later on as... something isn't - // escaped it seems? - // - // Instead of attempting to fix this problem in upstream CMake and/or - // LLVM/LLD we just hack around it here. This thin wrapper will take the - // output from llvm-config and replace all instances of `\` with `/` to - // ensure we don't hit the same bugs with escaping. It means that you - // can't build on a system where your paths require `\` on Windows, but - // there's probably a lot of reasons you can't do that other than this. - let llvm_config_shim = env::current_exe().unwrap().with_file_name("llvm-config-wrapper"); - // Re-use the same flags as llvm to control the level of debug information // generated for lld. let profile = match (builder.config.llvm_optimize, builder.config.llvm_release_debuginfo) { @@ -860,36 +880,17 @@ impl Step for Lld { cfg.out_dir(&out_dir) .profile(profile) - .env("LLVM_CONFIG_REAL", &llvm_config) - .define("LLVM_CONFIG_PATH", llvm_config_shim) + .define("LLVM_CMAKE_DIR", llvm_cmake_dir) .define("LLVM_INCLUDE_TESTS", "OFF"); - // While we're using this horrible workaround to shim the execution of - // llvm-config, let's just pile on more. I can't seem to figure out how - // to build LLD as a standalone project and also cross-compile it at the - // same time. It wants a natively executable `llvm-config` to learn - // about LLVM, but then it learns about all the host configuration of - // LLVM and tries to link to host LLVM libraries. - // - // To work around that we tell our shim to replace anything with the - // build target with the actual target instead. This'll break parts of - // LLD though which try to execute host tools, such as llvm-tblgen, so - // we specifically tell it where to find those. This is likely super - // brittle and will break over time. If anyone knows better how to - // cross-compile LLD it would be much appreciated to fix this! if target != builder.config.build { - cfg.env("LLVM_CONFIG_SHIM_REPLACE", &builder.config.build.triple) - .env("LLVM_CONFIG_SHIM_REPLACE_WITH", &target.triple) - .define( - "LLVM_TABLEGEN_EXE", - llvm_config.with_file_name("llvm-tblgen").with_extension(EXE_EXTENSION), - ); + // Use the host llvm-tblgen binary. + cfg.define( + "LLVM_TABLEGEN_EXE", + llvm_config.with_file_name("llvm-tblgen").with_extension(EXE_EXTENSION), + ); } - // Explicitly set C++ standard, because upstream doesn't do so - // for standalone builds. - cfg.define("CMAKE_CXX_STANDARD", "14"); - cfg.build(); t!(File::create(&done_stamp)); @@ -906,7 +907,7 @@ impl Step for TestHelpers { type Output = (); fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { - run.path("src/test/auxiliary/rust_test_helpers.c") + run.path("tests/auxiliary/rust_test_helpers.c") } fn make_run(run: RunConfig<'_>) { @@ -928,7 +929,7 @@ impl Step for TestHelpers { self.target }; let dst = builder.test_helpers_out(target); - let src = builder.src.join("src/test/auxiliary/rust_test_helpers.c"); + let src = builder.src.join("tests/auxiliary/rust_test_helpers.c"); if up_to_date(&src, &dst.join("librust_test_helpers.a")) { return; } @@ -957,7 +958,7 @@ impl Step for TestHelpers { .opt_level(0) .warnings(false) .debug(false) - .file(builder.src.join("src/test/auxiliary/rust_test_helpers.c")) + .file(builder.src.join("tests/auxiliary/rust_test_helpers.c")) .compile("rust_test_helpers"); } } @@ -991,7 +992,7 @@ impl Step for Sanitizers { return runtimes; } - let llvm_config = builder.ensure(Llvm { target: builder.config.build }); + let LlvmResult { llvm_config, .. } = builder.ensure(Llvm { target: builder.config.build }); if builder.config.dry_run() { return runtimes; } @@ -1086,12 +1087,12 @@ fn supported_sanitizers( match &*target.triple { "aarch64-apple-darwin" => darwin_libs("osx", &["asan", "lsan", "tsan"]), - "aarch64-fuchsia" => common_libs("fuchsia", "aarch64", &["asan"]), + "aarch64-unknown-fuchsia" => common_libs("fuchsia", "aarch64", &["asan"]), "aarch64-unknown-linux-gnu" => { common_libs("linux", "aarch64", &["asan", "lsan", "msan", "tsan", "hwasan"]) } "x86_64-apple-darwin" => darwin_libs("osx", &["asan", "lsan", "tsan"]), - "x86_64-fuchsia" => common_libs("fuchsia", "x86_64", &["asan"]), + "x86_64-unknown-fuchsia" => common_libs("fuchsia", "x86_64", &["asan"]), "x86_64-unknown-freebsd" => common_libs("freebsd", "x86_64", &["asan", "msan", "tsan"]), "x86_64-unknown-netbsd" => { common_libs("netbsd", "x86_64", &["asan", "lsan", "msan", "tsan"]) |