Rollup merge of #114069 - cuviper:profiler-path, r=Mark-Simulacrum

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.
This commit is contained in:
Guillaume Gomez 2023-08-13 21:00:45 +02:00 committed by GitHub
commit 99144c3f04
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 38 additions and 8 deletions

View File

@ -758,8 +758,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)

View File

@ -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();

View File

@ -325,6 +325,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

View File

@ -534,7 +534,7 @@ pub struct Target {
pub linker: Option<PathBuf>,
pub ndk: Option<PathBuf>,
pub sanitizers: Option<bool>,
pub profiler: Option<bool>,
pub profiler: Option<StringOrBool>,
pub rpath: Option<bool>,
pub crt_static: Option<bool>,
pub musl_root: Option<PathBuf>,
@ -863,9 +863,9 @@ define_config! {
}
}
#[derive(Debug, Deserialize)]
#[derive(Clone, Debug, Deserialize)]
#[serde(untagged)]
enum StringOrBool {
pub enum StringOrBool {
String(String),
Bool(bool),
}
@ -876,6 +876,12 @@ impl Default for StringOrBool {
}
}
impl StringOrBool {
fn is_string_or_true(&self) -> bool {
matches!(self, Self::String(_) | Self::Bool(true))
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum RustOptimize {
String(String),
@ -1038,7 +1044,7 @@ define_config! {
llvm_libunwind: Option<String> = "llvm-libunwind",
android_ndk: Option<String> = "android-ndk",
sanitizers: Option<bool> = "sanitizers",
profiler: Option<bool> = "profiler",
profiler: Option<StringOrBool> = "profiler",
rpath: Option<bool> = "rpath",
crt_static: Option<bool> = "crt-static",
musl_root: Option<String> = "musl-root",
@ -1957,12 +1963,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 rpath_enabled(&self, target: TargetSelection) -> bool {