Skip to content

Commit 07dae5a

Browse files
author
Jon Gjengset
committed
bootstrap: make LLVM build respect *FLAGS envvars
This tidies up the logic in `src/bootstrap/native.rs` such that: - `CMAKE_*_LINKER_FLAGS` is not overridden if we add to it twice. - `CMAKE_*_FLAGS` also include the standard `*FLAGS` environment variables, which CMake respects when we _don't_ set `CMAKE_*_FLAGS`. - `llvm.ldflags` from `config.toml` appends to the ldflags Rust's bootstrap logic adds, rather than replacing them. Fixes #93880.
1 parent 78450d2 commit 07dae5a

File tree

1 file changed

+63
-22
lines changed

1 file changed

+63
-22
lines changed

src/bootstrap/native.rs

+63-22
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,29 @@ pub struct Meta {
3131
root: String,
3232
}
3333

34+
// Linker flags to pass to LLVM's CMake invocation.
35+
#[derive(Debug, Clone, Default)]
36+
struct LdFlags {
37+
// CMAKE_EXE_LINKER_FLAGS
38+
exe: OsString,
39+
// CMAKE_SHARED_LINKER_FLAGS
40+
shared: OsString,
41+
// CMAKE_MODULE_LINKER_FLAGS
42+
module: OsString,
43+
}
44+
45+
impl LdFlags {
46+
fn push_all(&mut self, s: impl AsRef<OsStr>) {
47+
let s = s.as_ref();
48+
self.exe.push(" ");
49+
self.exe.push(s);
50+
self.shared.push(" ");
51+
self.shared.push(s);
52+
self.module.push(" ");
53+
self.module.push(s);
54+
}
55+
}
56+
3457
// This returns whether we've already previously built LLVM.
3558
//
3659
// It's used to avoid busting caches during x.py check -- if we've already built
@@ -146,6 +169,7 @@ impl Step for Llvm {
146169

147170
// https://llvm.org/docs/CMake.html
148171
let mut cfg = cmake::Config::new(builder.src.join(root));
172+
let mut ldflags = LdFlags::default();
149173

150174
let profile = match (builder.config.llvm_optimize, builder.config.llvm_release_debuginfo) {
151175
(false, _) => "Debug",
@@ -242,9 +266,9 @@ impl Step for Llvm {
242266
if builder.config.llvm_tools_enabled {
243267
if !target.contains("msvc") {
244268
if target.contains("apple") {
245-
cfg.define("CMAKE_EXE_LINKER_FLAGS", "-static-libstdc++");
269+
ldflags.exe.push(" -static-libstdc++");
246270
} else {
247-
cfg.define("CMAKE_EXE_LINKER_FLAGS", "-Wl,-Bsymbolic -static-libstdc++");
271+
ldflags.exe.push(" -Wl,-Bsymbolic -static-libstdc++");
248272
}
249273
}
250274
}
@@ -258,11 +282,11 @@ impl Step for Llvm {
258282
// provides no libatomic in its base system so does
259283
// not want this.
260284
if !builder.config.llvm_tools_enabled {
261-
cfg.define("CMAKE_EXE_LINKER_FLAGS", "-latomic");
285+
ldflags.exe.push(" -latomic");
262286
} else {
263-
cfg.define("CMAKE_EXE_LINKER_FLAGS", "-latomic -static-libstdc++");
287+
ldflags.exe.push(" -latomic -static-libstdc++");
264288
}
265-
cfg.define("CMAKE_SHARED_LINKER_FLAGS", "-latomic");
289+
ldflags.shared.push(" -latomic");
266290
}
267291

268292
if target.contains("msvc") {
@@ -309,7 +333,7 @@ impl Step for Llvm {
309333

310334
// Workaround for ppc32 lld limitation
311335
if target == "powerpc-unknown-freebsd" {
312-
cfg.define("CMAKE_EXE_LINKER_FLAGS", "-fuse-ld=bfd");
336+
ldflags.exe.push(" -fuse-ld=bfd");
313337
}
314338

315339
// https://llvm.org/docs/HowToCrossCompileLLVM.html
@@ -351,7 +375,7 @@ impl Step for Llvm {
351375
cfg.define("LLVM_TEMPORARILY_ALLOW_OLD_TOOLCHAIN", "YES");
352376
}
353377

354-
configure_cmake(builder, target, &mut cfg, true);
378+
configure_cmake(builder, target, &mut cfg, true, ldflags);
355379

356380
for (key, val) in &builder.config.llvm_build_config {
357381
cfg.define(key, val);
@@ -399,6 +423,7 @@ fn configure_cmake(
399423
target: TargetSelection,
400424
cfg: &mut cmake::Config,
401425
use_compiler_launcher: bool,
426+
mut ldflags: LdFlags,
402427
) {
403428
// Do not print installation messages for up-to-date files.
404429
// LLVM and LLD builds can produce a lot of those and hit CI limits on log size.
@@ -507,31 +532,41 @@ fn configure_cmake(
507532
}
508533

509534
cfg.build_arg("-j").build_arg(builder.jobs().to_string());
510-
let mut cflags = builder.cflags(target, GitRepo::Llvm).join(" ");
535+
let mut cflags: OsString = builder.cflags(target, GitRepo::Llvm).join(" ").into();
511536
if let Some(ref s) = builder.config.llvm_cflags {
512-
cflags.push_str(&format!(" {}", s));
537+
cflags.push(" ");
538+
cflags.push(s);
513539
}
514540
// Some compiler features used by LLVM (such as thread locals) will not work on a min version below iOS 10.
515541
if target.contains("apple-ios") {
516542
if target.contains("86-") {
517-
cflags.push_str(" -miphonesimulator-version-min=10.0");
543+
cflags.push(" -miphonesimulator-version-min=10.0");
518544
} else {
519-
cflags.push_str(" -miphoneos-version-min=10.0");
545+
cflags.push(" -miphoneos-version-min=10.0");
520546
}
521547
}
522548
if builder.config.llvm_clang_cl.is_some() {
523-
cflags.push_str(&format!(" --target={}", target))
549+
cflags.push(&format!(" --target={}", target));
550+
}
551+
if let Some(flags) = env::var_os("CFLAGS") {
552+
cflags.push(" ");
553+
cflags.push(flags);
524554
}
525555
cfg.define("CMAKE_C_FLAGS", cflags);
526-
let mut cxxflags = builder.cflags(target, GitRepo::Llvm).join(" ");
556+
let mut cxxflags: OsString = builder.cflags(target, GitRepo::Llvm).join(" ").into();
527557
if builder.config.llvm_static_stdcpp && !target.contains("msvc") && !target.contains("netbsd") {
528-
cxxflags.push_str(" -static-libstdc++");
558+
cxxflags.push(" -static-libstdc++");
529559
}
530560
if let Some(ref s) = builder.config.llvm_cxxflags {
531-
cxxflags.push_str(&format!(" {}", s));
561+
cxxflags.push(" ");
562+
cxxflags.push(s);
532563
}
533564
if builder.config.llvm_clang_cl.is_some() {
534-
cxxflags.push_str(&format!(" --target={}", target))
565+
cxxflags.push(&format!(" --target={}", target));
566+
}
567+
if let Some(flags) = env::var_os("CXXFLAGS") {
568+
cxxflags.push(" ");
569+
cxxflags.push(flags);
535570
}
536571
cfg.define("CMAKE_CXX_FLAGS", cxxflags);
537572
if let Some(ar) = builder.ar(target) {
@@ -550,12 +585,18 @@ fn configure_cmake(
550585
}
551586
}
552587

553-
if let Some(ref s) = builder.config.llvm_ldflags {
554-
cfg.define("CMAKE_SHARED_LINKER_FLAGS", s);
555-
cfg.define("CMAKE_MODULE_LINKER_FLAGS", s);
556-
cfg.define("CMAKE_EXE_LINKER_FLAGS", s);
588+
if let Some(ref flags) = builder.config.llvm_ldflags {
589+
ldflags.push_all(flags);
557590
}
558591

592+
if let Some(flags) = env::var_os("LDFLAGS") {
593+
ldflags.push_all(&flags);
594+
}
595+
596+
cfg.define("CMAKE_SHARED_LINKER_FLAGS", &ldflags.shared);
597+
cfg.define("CMAKE_MODULE_LINKER_FLAGS", &ldflags.module);
598+
cfg.define("CMAKE_EXE_LINKER_FLAGS", &ldflags.exe);
599+
559600
if env::var_os("SCCACHE_ERROR_LOG").is_some() {
560601
cfg.env("RUSTC_LOG", "sccache=warn");
561602
}
@@ -598,7 +639,7 @@ impl Step for Lld {
598639
t!(fs::create_dir_all(&out_dir));
599640

600641
let mut cfg = cmake::Config::new(builder.src.join("src/llvm-project/lld"));
601-
configure_cmake(builder, target, &mut cfg, true);
642+
configure_cmake(builder, target, &mut cfg, true, LdFlags::default());
602643

603644
// This is an awful, awful hack. Discovered when we migrated to using
604645
// clang-cl to compile LLVM/LLD it turns out that LLD, when built out of
@@ -788,7 +829,7 @@ impl Step for Sanitizers {
788829
// Unfortunately sccache currently lacks support to build them successfully.
789830
// Disable compiler launcher on Darwin targets to avoid potential issues.
790831
let use_compiler_launcher = !self.target.contains("apple-darwin");
791-
configure_cmake(builder, self.target, &mut cfg, use_compiler_launcher);
832+
configure_cmake(builder, self.target, &mut cfg, use_compiler_launcher, LdFlags::default());
792833

793834
t!(fs::create_dir_all(&out_dir));
794835
cfg.out_dir(out_dir);

0 commit comments

Comments
 (0)