From: Josh Stone Date: Tue, 25 Jul 2023 20:11:50 +0000 (-0700) Subject: [PATCH] Allow using external builds of the compiler-rt profile lib X-Git-Tag: archive/raspbian/1.70.0+dfsg1-5+rpi1^2~35 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=f9106602723dde23dba37d4cc52cdcc84aebb3ae;p=rustc.git [PATCH] Allow using external builds of the compiler-rt profile lib This changes the bootstrap config `target.*.profiler` from a plain bool to also allow a string, which will be used as a path to the pre-built profiling runtime for that target. Then `profiler_builtins/build.rs` reads that in a `LLVM_PROFILER_RT_LIB` environment variable. Gbp-Pq: Name u-profiler.patch --- diff --git a/config.example.toml b/config.example.toml index 6d9c762cec..c70c574c28 100644 --- a/config.example.toml +++ b/config.example.toml @@ -745,8 +745,10 @@ changelog-seen = 2 # This option will override the same option under [build] section. #sanitizers = build.sanitizers (bool) -# Build the profiler runtime for this target(required when compiling with options that depend -# on this runtime, such as `-C profile-generate` or `-C instrument-coverage`). +# When true, build the profiler runtime for this target(required when compiling +# with options that depend on this runtime, such as `-C profile-generate` or +# `-C instrument-coverage`). This may also be given a path to an existing build +# of the profiling runtime library from LLVM's compiler-rt. # This option will override the same option under [build] section. #profiler = build.profiler (bool) diff --git a/library/profiler_builtins/build.rs b/library/profiler_builtins/build.rs index 1b1f11798d..d14d0b8222 100644 --- a/library/profiler_builtins/build.rs +++ b/library/profiler_builtins/build.rs @@ -6,6 +6,12 @@ use std::env; use std::path::Path; fn main() { + println!("cargo:rerun-if-env-changed=LLVM_PROFILER_RT_LIB"); + if let Ok(rt) = env::var("LLVM_PROFILER_RT_LIB") { + println!("cargo:rustc-link-lib=static:+verbatim={rt}"); + return; + } + let target = env::var("TARGET").expect("TARGET was not set"); let cfg = &mut cc::Build::new(); diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 4a4e7adcbf..ea6da47ceb 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -314,6 +314,10 @@ pub fn std_cargo(builder: &Builder<'_>, target: TargetSelection, stage: u32, car cargo.env("MACOSX_DEPLOYMENT_TARGET", target); } + if let Some(path) = builder.config.profiler_path(target) { + cargo.env("LLVM_PROFILER_RT_LIB", path); + } + // Determine if we're going to compile in optimized C intrinsics to // the `compiler-builtins` crate. These intrinsics live in LLVM's // `compiler-rt` repository, but our `src/llvm-project` submodule isn't diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index 3c740de8a7..01bef7ce06 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -454,7 +454,7 @@ pub struct Target { pub linker: Option, pub ndk: Option, pub sanitizers: Option, - pub profiler: Option, + pub profiler: Option, pub crt_static: Option, pub musl_root: Option, pub musl_libdir: Option, @@ -715,9 +715,9 @@ define_config! { } } -#[derive(Debug, Deserialize)] +#[derive(Clone, Debug, Deserialize)] #[serde(untagged)] -enum StringOrBool { +pub enum StringOrBool { String(String), Bool(bool), } @@ -728,6 +728,12 @@ impl Default for StringOrBool { } } +impl StringOrBool { + fn is_string_or_true(&self) -> bool { + matches!(self, Self::String(_) | Self::Bool(true)) + } +} + define_config! { /// TOML representation of how the Rust build is configured. struct Rust { @@ -799,7 +805,7 @@ define_config! { llvm_libunwind: Option = "llvm-libunwind", android_ndk: Option = "android-ndk", sanitizers: Option = "sanitizers", - profiler: Option = "profiler", + profiler: Option = "profiler", crt_static: Option = "crt-static", musl_root: Option = "musl-root", musl_libdir: Option = "musl-libdir", @@ -1616,12 +1622,24 @@ impl Config { self.target_config.values().any(|t| t.sanitizers == Some(true)) || self.sanitizers } + pub fn profiler_path(&self, target: TargetSelection) -> Option<&str> { + match self.target_config.get(&target)?.profiler.as_ref()? { + StringOrBool::String(s) => Some(s), + StringOrBool::Bool(_) => None, + } + } + pub fn profiler_enabled(&self, target: TargetSelection) -> bool { - self.target_config.get(&target).map(|t| t.profiler).flatten().unwrap_or(self.profiler) + self.target_config + .get(&target) + .and_then(|t| t.profiler.as_ref()) + .map(StringOrBool::is_string_or_true) + .unwrap_or(self.profiler) } pub fn any_profiler_enabled(&self) -> bool { - self.target_config.values().any(|t| t.profiler == Some(true)) || self.profiler + self.target_config.values().any(|t| matches!(&t.profiler, Some(p) if p.is_string_or_true())) + || self.profiler } pub fn llvm_enabled(&self) -> bool {