summaryrefslogtreecommitdiffstats
path: root/debian/patches/u-profiler.patch
blob: 37f63af69a826bfd8d2c6f1beb9736f2366557a4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
From d0b58f40a0e669897fafb614299d2a989997eda7 Mon Sep 17 00:00:00 2001
From: Josh Stone <jistone@redhat.com>
Date: Tue, 25 Jul 2023 13:11:50 -0700
Subject: [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.
---
 config.example.toml                |  6 ++++--
 library/profiler_builtins/build.rs |  6 ++++++
 src/bootstrap/compile.rs           |  4 ++++
 src/bootstrap/config.rs            | 30 ++++++++++++++++++++++++------
 4 files changed, 38 insertions(+), 8 deletions(-)

--- 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)
 
--- 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();
 
--- a/src/bootstrap/compile.rs
+++ b/src/bootstrap/compile.rs
@@ -314,6 +314,10 @@ pub fn std_cargo(builder: &Builder<'_>,
         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
--- a/src/bootstrap/config.rs
+++ b/src/bootstrap/config.rs
@@ -454,7 +454,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 crt_static: Option<bool>,
     pub musl_root: Option<PathBuf>,
     pub musl_libdir: Option<PathBuf>,
@@ -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<String> = "llvm-libunwind",
         android_ndk: Option<String> = "android-ndk",
         sanitizers: Option<bool> = "sanitizers",
-        profiler: Option<bool> = "profiler",
+        profiler: Option<StringOrBool> = "profiler",
         crt_static: Option<bool> = "crt-static",
         musl_root: Option<String> = "musl-root",
         musl_libdir: Option<String> = "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 {