From e04e3fb45689d94dd8b5aa7363f05dbc7c4295e5 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Mon, 19 Aug 2024 23:00:37 +1000 Subject: [PATCH] Build `library/profiler_builtins` from `ci-llvm` if appropriate --- library/profiler_builtins/build.rs | 12 +++-- src/bootstrap/src/core/build_steps/compile.rs | 50 ++++++++++++++----- src/bootstrap/src/utils/change_tracker.rs | 5 ++ 3 files changed, 51 insertions(+), 16 deletions(-) diff --git a/library/profiler_builtins/build.rs b/library/profiler_builtins/build.rs index 177b027e4f175..c1e0e5c1c8975 100644 --- a/library/profiler_builtins/build.rs +++ b/library/profiler_builtins/build.rs @@ -3,7 +3,7 @@ //! See the build.rs for libcompiler_builtins crate for details. use std::env; -use std::path::Path; +use std::path::PathBuf; fn main() { println!("cargo:rerun-if-env-changed=LLVM_PROFILER_RT_LIB"); @@ -79,9 +79,13 @@ fn main() { cfg.define("COMPILER_RT_HAS_ATOMICS", Some("1")); } - // Note that this should exist if we're going to run (otherwise we just - // don't build profiler builtins at all). - let root = Path::new("../../src/llvm-project/compiler-rt"); + // Get the LLVM `compiler-rt` directory from bootstrap. + println!("cargo:rerun-if-env-changed=RUST_COMPILER_RT_FOR_PROFILER"); + let root = PathBuf::from(env::var("RUST_COMPILER_RT_FOR_PROFILER").unwrap_or_else(|_| { + let path = "../../src/llvm-project/compiler-rt"; + println!("RUST_COMPILER_RT_FOR_PROFILER was not set; falling back to {path:?}"); + path.to_owned() + })); let src_root = root.join("lib").join("profile"); assert!(src_root.exists(), "profiler runtime source directory not found: {src_root:?}"); diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index 4353cfadd8d35..dba95231338cf 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -199,16 +199,6 @@ impl Step for Std { builder.require_submodule("library/stdarch", None); - // Profiler information requires LLVM's compiler-rt - if builder.config.profiler { - builder.require_submodule( - "src/llvm-project", - Some( - "The `build.profiler` config option requires `compiler-rt` sources from LLVM.", - ), - ); - } - let mut target_deps = builder.ensure(StartupObjects { compiler, target }); let compiler_to_use = builder.compiler_for(compiler.stage, compiler.host, target); @@ -466,6 +456,35 @@ pub fn std_crates_for_run_make(run: &RunConfig<'_>) -> Vec { } } +/// Tries to find LLVM's `compiler-rt` source directory, for building `library/profiler_builtins`. +/// +/// Normally it lives in the `src/llvm-project` submodule, but if that submodule +/// is absent and we have downloaded a copy of CI LLVM, then we try to use the +/// `compiler-rt` sources from there instead, which lets us avoid checking out +/// the LLVM submodule. +fn compiler_rt_for_profiler(builder: &Builder<'_>) -> PathBuf { + // If the LLVM submodule is already active, just update it and use that. + builder.update_existing_submodule("src/llvm-project"); + let submodule_compiler_rt = builder.src.join("src/llvm-project/compiler-rt"); + if submodule_compiler_rt.exists() { + return submodule_compiler_rt; + } + + // Try to use `compiler-rt` sources from downloaded CI LLVM, if possible. + if builder.config.llvm_from_ci { + let ci_llvm_compiler_rt = builder.config.ci_llvm_root().join("compiler-rt"); + if ci_llvm_compiler_rt.exists() { + return ci_llvm_compiler_rt; + } + } + + // Otherwise, fall back to requiring the LLVM submodule. + builder.require_submodule("src/llvm-project", { + Some("The `build.profiler` config option requires `compiler-rt` sources from LLVM.") + }); + submodule_compiler_rt +} + /// Configure cargo to compile the standard library, adding appropriate env vars /// and such. pub fn std_cargo(builder: &Builder<'_>, target: TargetSelection, stage: u32, cargo: &mut Cargo) { @@ -473,8 +492,15 @@ pub fn std_cargo(builder: &Builder<'_>, target: TargetSelection, stage: u32, car cargo.env("MACOSX_DEPLOYMENT_TARGET", target); } + // Paths needed by `library/profiler_builtins/build.rs`. if let Some(path) = builder.config.profiler_path(target) { cargo.env("LLVM_PROFILER_RT_LIB", path); + } else if builder.config.profiler_enabled(target) { + let compiler_rt = compiler_rt_for_profiler(builder); + // Currently this is separate from the env var used by `compiler_builtins` + // (below) so that adding support for CI LLVM here doesn't risk breaking + // the compiler builtins. But they could be unified if desired. + cargo.env("RUST_COMPILER_RT_FOR_PROFILER", compiler_rt); } // Determine if we're going to compile in optimized C intrinsics to @@ -507,8 +533,8 @@ pub fn std_cargo(builder: &Builder<'_>, target: TargetSelection, stage: u32, car ); let compiler_builtins_root = builder.src.join("src/llvm-project/compiler-rt"); assert!(compiler_builtins_root.exists()); - // Note that `libprofiler_builtins/build.rs` also computes this so if - // you're changing something here please also change that. + // The path to `compiler-rt` is also used by `profiler_builtins` (above), + // so if you're changing something here please also change that as appropriate. cargo.env("RUST_COMPILER_RT_ROOT", &compiler_builtins_root); " compiler-builtins-c" } else { diff --git a/src/bootstrap/src/utils/change_tracker.rs b/src/bootstrap/src/utils/change_tracker.rs index c629f04c00ecd..51a25104e4cfb 100644 --- a/src/bootstrap/src/utils/change_tracker.rs +++ b/src/bootstrap/src/utils/change_tracker.rs @@ -230,4 +230,9 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[ severity: ChangeSeverity::Warning, summary: "./x test --rustc-args was renamed to --compiletest-rustc-args as it only applies there. ./x miri --rustc-args was also removed.", }, + ChangeInfo { + change_id: 129295, + severity: ChangeSeverity::Info, + summary: "The `build.profiler` option now tries to use source code from `download-ci-llvm` if possible, instead of checking out the `src/llvm-project` submodule.", + }, ];