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.
This commit is contained in:
parent
78450d2d60
commit
07dae5a97b
@ -31,6 +31,29 @@ pub struct Meta {
|
||||
root: String,
|
||||
}
|
||||
|
||||
// Linker flags to pass to LLVM's CMake invocation.
|
||||
#[derive(Debug, Clone, Default)]
|
||||
struct LdFlags {
|
||||
// CMAKE_EXE_LINKER_FLAGS
|
||||
exe: OsString,
|
||||
// CMAKE_SHARED_LINKER_FLAGS
|
||||
shared: OsString,
|
||||
// CMAKE_MODULE_LINKER_FLAGS
|
||||
module: OsString,
|
||||
}
|
||||
|
||||
impl LdFlags {
|
||||
fn push_all(&mut self, s: impl AsRef<OsStr>) {
|
||||
let s = s.as_ref();
|
||||
self.exe.push(" ");
|
||||
self.exe.push(s);
|
||||
self.shared.push(" ");
|
||||
self.shared.push(s);
|
||||
self.module.push(" ");
|
||||
self.module.push(s);
|
||||
}
|
||||
}
|
||||
|
||||
// This returns whether we've already previously built LLVM.
|
||||
//
|
||||
// It's used to avoid busting caches during x.py check -- if we've already built
|
||||
@ -146,6 +169,7 @@ fn run(self, builder: &Builder<'_>) -> PathBuf {
|
||||
|
||||
// https://llvm.org/docs/CMake.html
|
||||
let mut cfg = cmake::Config::new(builder.src.join(root));
|
||||
let mut ldflags = LdFlags::default();
|
||||
|
||||
let profile = match (builder.config.llvm_optimize, builder.config.llvm_release_debuginfo) {
|
||||
(false, _) => "Debug",
|
||||
@ -242,9 +266,9 @@ fn run(self, builder: &Builder<'_>) -> PathBuf {
|
||||
if builder.config.llvm_tools_enabled {
|
||||
if !target.contains("msvc") {
|
||||
if target.contains("apple") {
|
||||
cfg.define("CMAKE_EXE_LINKER_FLAGS", "-static-libstdc++");
|
||||
ldflags.exe.push(" -static-libstdc++");
|
||||
} else {
|
||||
cfg.define("CMAKE_EXE_LINKER_FLAGS", "-Wl,-Bsymbolic -static-libstdc++");
|
||||
ldflags.exe.push(" -Wl,-Bsymbolic -static-libstdc++");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -258,11 +282,11 @@ fn run(self, builder: &Builder<'_>) -> PathBuf {
|
||||
// provides no libatomic in its base system so does
|
||||
// not want this.
|
||||
if !builder.config.llvm_tools_enabled {
|
||||
cfg.define("CMAKE_EXE_LINKER_FLAGS", "-latomic");
|
||||
ldflags.exe.push(" -latomic");
|
||||
} else {
|
||||
cfg.define("CMAKE_EXE_LINKER_FLAGS", "-latomic -static-libstdc++");
|
||||
ldflags.exe.push(" -latomic -static-libstdc++");
|
||||
}
|
||||
cfg.define("CMAKE_SHARED_LINKER_FLAGS", "-latomic");
|
||||
ldflags.shared.push(" -latomic");
|
||||
}
|
||||
|
||||
if target.contains("msvc") {
|
||||
@ -309,7 +333,7 @@ fn run(self, builder: &Builder<'_>) -> PathBuf {
|
||||
|
||||
// Workaround for ppc32 lld limitation
|
||||
if target == "powerpc-unknown-freebsd" {
|
||||
cfg.define("CMAKE_EXE_LINKER_FLAGS", "-fuse-ld=bfd");
|
||||
ldflags.exe.push(" -fuse-ld=bfd");
|
||||
}
|
||||
|
||||
// https://llvm.org/docs/HowToCrossCompileLLVM.html
|
||||
@ -351,7 +375,7 @@ fn run(self, builder: &Builder<'_>) -> PathBuf {
|
||||
cfg.define("LLVM_TEMPORARILY_ALLOW_OLD_TOOLCHAIN", "YES");
|
||||
}
|
||||
|
||||
configure_cmake(builder, target, &mut cfg, true);
|
||||
configure_cmake(builder, target, &mut cfg, true, ldflags);
|
||||
|
||||
for (key, val) in &builder.config.llvm_build_config {
|
||||
cfg.define(key, val);
|
||||
@ -399,6 +423,7 @@ fn configure_cmake(
|
||||
target: TargetSelection,
|
||||
cfg: &mut cmake::Config,
|
||||
use_compiler_launcher: bool,
|
||||
mut ldflags: LdFlags,
|
||||
) {
|
||||
// Do not print installation messages for up-to-date files.
|
||||
// LLVM and LLD builds can produce a lot of those and hit CI limits on log size.
|
||||
@ -507,31 +532,41 @@ fn configure_cmake(
|
||||
}
|
||||
|
||||
cfg.build_arg("-j").build_arg(builder.jobs().to_string());
|
||||
let mut cflags = builder.cflags(target, GitRepo::Llvm).join(" ");
|
||||
let mut cflags: OsString = builder.cflags(target, GitRepo::Llvm).join(" ").into();
|
||||
if let Some(ref s) = builder.config.llvm_cflags {
|
||||
cflags.push_str(&format!(" {}", s));
|
||||
cflags.push(" ");
|
||||
cflags.push(s);
|
||||
}
|
||||
// Some compiler features used by LLVM (such as thread locals) will not work on a min version below iOS 10.
|
||||
if target.contains("apple-ios") {
|
||||
if target.contains("86-") {
|
||||
cflags.push_str(" -miphonesimulator-version-min=10.0");
|
||||
cflags.push(" -miphonesimulator-version-min=10.0");
|
||||
} else {
|
||||
cflags.push_str(" -miphoneos-version-min=10.0");
|
||||
cflags.push(" -miphoneos-version-min=10.0");
|
||||
}
|
||||
}
|
||||
if builder.config.llvm_clang_cl.is_some() {
|
||||
cflags.push_str(&format!(" --target={}", target))
|
||||
cflags.push(&format!(" --target={}", target));
|
||||
}
|
||||
if let Some(flags) = env::var_os("CFLAGS") {
|
||||
cflags.push(" ");
|
||||
cflags.push(flags);
|
||||
}
|
||||
cfg.define("CMAKE_C_FLAGS", cflags);
|
||||
let mut cxxflags = builder.cflags(target, GitRepo::Llvm).join(" ");
|
||||
let mut cxxflags: OsString = builder.cflags(target, GitRepo::Llvm).join(" ").into();
|
||||
if builder.config.llvm_static_stdcpp && !target.contains("msvc") && !target.contains("netbsd") {
|
||||
cxxflags.push_str(" -static-libstdc++");
|
||||
cxxflags.push(" -static-libstdc++");
|
||||
}
|
||||
if let Some(ref s) = builder.config.llvm_cxxflags {
|
||||
cxxflags.push_str(&format!(" {}", s));
|
||||
cxxflags.push(" ");
|
||||
cxxflags.push(s);
|
||||
}
|
||||
if builder.config.llvm_clang_cl.is_some() {
|
||||
cxxflags.push_str(&format!(" --target={}", target))
|
||||
cxxflags.push(&format!(" --target={}", target));
|
||||
}
|
||||
if let Some(flags) = env::var_os("CXXFLAGS") {
|
||||
cxxflags.push(" ");
|
||||
cxxflags.push(flags);
|
||||
}
|
||||
cfg.define("CMAKE_CXX_FLAGS", cxxflags);
|
||||
if let Some(ar) = builder.ar(target) {
|
||||
@ -550,12 +585,18 @@ fn configure_cmake(
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(ref s) = builder.config.llvm_ldflags {
|
||||
cfg.define("CMAKE_SHARED_LINKER_FLAGS", s);
|
||||
cfg.define("CMAKE_MODULE_LINKER_FLAGS", s);
|
||||
cfg.define("CMAKE_EXE_LINKER_FLAGS", s);
|
||||
if let Some(ref flags) = builder.config.llvm_ldflags {
|
||||
ldflags.push_all(flags);
|
||||
}
|
||||
|
||||
if let Some(flags) = env::var_os("LDFLAGS") {
|
||||
ldflags.push_all(&flags);
|
||||
}
|
||||
|
||||
cfg.define("CMAKE_SHARED_LINKER_FLAGS", &ldflags.shared);
|
||||
cfg.define("CMAKE_MODULE_LINKER_FLAGS", &ldflags.module);
|
||||
cfg.define("CMAKE_EXE_LINKER_FLAGS", &ldflags.exe);
|
||||
|
||||
if env::var_os("SCCACHE_ERROR_LOG").is_some() {
|
||||
cfg.env("RUSTC_LOG", "sccache=warn");
|
||||
}
|
||||
@ -598,7 +639,7 @@ fn run(self, builder: &Builder<'_>) -> PathBuf {
|
||||
t!(fs::create_dir_all(&out_dir));
|
||||
|
||||
let mut cfg = cmake::Config::new(builder.src.join("src/llvm-project/lld"));
|
||||
configure_cmake(builder, target, &mut cfg, true);
|
||||
configure_cmake(builder, target, &mut cfg, true, LdFlags::default());
|
||||
|
||||
// This is an awful, awful hack. Discovered when we migrated to using
|
||||
// clang-cl to compile LLVM/LLD it turns out that LLD, when built out of
|
||||
@ -788,7 +829,7 @@ fn run(self, builder: &Builder<'_>) -> Self::Output {
|
||||
// Unfortunately sccache currently lacks support to build them successfully.
|
||||
// Disable compiler launcher on Darwin targets to avoid potential issues.
|
||||
let use_compiler_launcher = !self.target.contains("apple-darwin");
|
||||
configure_cmake(builder, self.target, &mut cfg, use_compiler_launcher);
|
||||
configure_cmake(builder, self.target, &mut cfg, use_compiler_launcher, LdFlags::default());
|
||||
|
||||
t!(fs::create_dir_all(&out_dir));
|
||||
cfg.out_dir(out_dir);
|
||||
|
Loading…
Reference in New Issue
Block a user