Skip to content

Commit d0b58f4

Browse files
committed
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.
1 parent 4fc6b33 commit d0b58f4

File tree

4 files changed

+38
-8
lines changed

4 files changed

+38
-8
lines changed

config.example.toml

+4-2
Original file line numberDiff line numberDiff line change
@@ -762,8 +762,10 @@ changelog-seen = 2
762762
# This option will override the same option under [build] section.
763763
#sanitizers = build.sanitizers (bool)
764764

765-
# Build the profiler runtime for this target(required when compiling with options that depend
766-
# on this runtime, such as `-C profile-generate` or `-C instrument-coverage`).
765+
# When true, build the profiler runtime for this target(required when compiling
766+
# with options that depend on this runtime, such as `-C profile-generate` or
767+
# `-C instrument-coverage`). This may also be given a path to an existing build
768+
# of the profiling runtime library from LLVM's compiler-rt.
767769
# This option will override the same option under [build] section.
768770
#profiler = build.profiler (bool)
769771

library/profiler_builtins/build.rs

+6
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@ use std::env;
66
use std::path::Path;
77

88
fn main() {
9+
println!("cargo:rerun-if-env-changed=LLVM_PROFILER_RT_LIB");
10+
if let Ok(rt) = env::var("LLVM_PROFILER_RT_LIB") {
11+
println!("cargo:rustc-link-lib=static:+verbatim={rt}");
12+
return;
13+
}
14+
915
let target = env::var("TARGET").expect("TARGET was not set");
1016
let cfg = &mut cc::Build::new();
1117

src/bootstrap/compile.rs

+4
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,10 @@ pub fn std_cargo(builder: &Builder<'_>, target: TargetSelection, stage: u32, car
323323
cargo.env("MACOSX_DEPLOYMENT_TARGET", target);
324324
}
325325

326+
if let Some(path) = builder.config.profiler_path(target) {
327+
cargo.env("LLVM_PROFILER_RT_LIB", path);
328+
}
329+
326330
// Determine if we're going to compile in optimized C intrinsics to
327331
// the `compiler-builtins` crate. These intrinsics live in LLVM's
328332
// `compiler-rt` repository, but our `src/llvm-project` submodule isn't

src/bootstrap/config.rs

+24-6
Original file line numberDiff line numberDiff line change
@@ -533,7 +533,7 @@ pub struct Target {
533533
pub linker: Option<PathBuf>,
534534
pub ndk: Option<PathBuf>,
535535
pub sanitizers: Option<bool>,
536-
pub profiler: Option<bool>,
536+
pub profiler: Option<StringOrBool>,
537537
pub rpath: Option<bool>,
538538
pub crt_static: Option<bool>,
539539
pub musl_root: Option<PathBuf>,
@@ -862,9 +862,9 @@ define_config! {
862862
}
863863
}
864864

865-
#[derive(Debug, Deserialize)]
865+
#[derive(Clone, Debug, Deserialize)]
866866
#[serde(untagged)]
867-
enum StringOrBool {
867+
pub enum StringOrBool {
868868
String(String),
869869
Bool(bool),
870870
}
@@ -875,6 +875,12 @@ impl Default for StringOrBool {
875875
}
876876
}
877877

878+
impl StringOrBool {
879+
fn is_string_or_true(&self) -> bool {
880+
matches!(self, Self::String(_) | Self::Bool(true))
881+
}
882+
}
883+
878884
#[derive(Clone, Debug, PartialEq, Eq)]
879885
pub enum RustOptimize {
880886
String(String),
@@ -1038,7 +1044,7 @@ define_config! {
10381044
llvm_libunwind: Option<String> = "llvm-libunwind",
10391045
android_ndk: Option<String> = "android-ndk",
10401046
sanitizers: Option<bool> = "sanitizers",
1041-
profiler: Option<bool> = "profiler",
1047+
profiler: Option<StringOrBool> = "profiler",
10421048
rpath: Option<bool> = "rpath",
10431049
crt_static: Option<bool> = "crt-static",
10441050
musl_root: Option<String> = "musl-root",
@@ -1951,12 +1957,24 @@ impl Config {
19511957
self.target_config.values().any(|t| t.sanitizers == Some(true)) || self.sanitizers
19521958
}
19531959

1960+
pub fn profiler_path(&self, target: TargetSelection) -> Option<&str> {
1961+
match self.target_config.get(&target)?.profiler.as_ref()? {
1962+
StringOrBool::String(s) => Some(s),
1963+
StringOrBool::Bool(_) => None,
1964+
}
1965+
}
1966+
19541967
pub fn profiler_enabled(&self, target: TargetSelection) -> bool {
1955-
self.target_config.get(&target).map(|t| t.profiler).flatten().unwrap_or(self.profiler)
1968+
self.target_config
1969+
.get(&target)
1970+
.and_then(|t| t.profiler.as_ref())
1971+
.map(StringOrBool::is_string_or_true)
1972+
.unwrap_or(self.profiler)
19561973
}
19571974

19581975
pub fn any_profiler_enabled(&self) -> bool {
1959-
self.target_config.values().any(|t| t.profiler == Some(true)) || self.profiler
1976+
self.target_config.values().any(|t| matches!(&t.profiler, Some(p) if p.is_string_or_true()))
1977+
|| self.profiler
19601978
}
19611979

19621980
pub fn rpath_enabled(&self, target: TargetSelection) -> bool {

0 commit comments

Comments
 (0)