Skip to content

Commit

Permalink
Auto merge of #93918 - jonhoo:bootstrap-native-envflags, r=Mark-Simul…
Browse files Browse the repository at this point in the history
…acrum

bootstrap: tidy up flag handling for llvm build

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.

It also takes a second stab at #89983 by moving `-static-libstdc++` to just be passed as a linker flag, since that's what it is.

Fixes #93880. Fixes #70468. Closes #89983.
  • Loading branch information
bors committed Feb 15, 2022
2 parents 8d163e6 + 3669274 commit 6655109
Showing 1 changed file with 66 additions and 31 deletions.
97 changes: 66 additions & 31 deletions src/bootstrap/native.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -146,6 +169,7 @@ impl Step for Llvm {

// 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",
Expand Down Expand Up @@ -238,31 +262,28 @@ impl Step for Llvm {
cfg.define("LLVM_LINK_LLVM_DYLIB", "ON");
}

// For distribution we want the LLVM tools to be *statically* linked to libstdc++
if builder.config.llvm_tools_enabled {
if !target.contains("msvc") {
// For distribution we want the LLVM tools to be *statically* linked to libstdc++.
// We also do this if the user explicitly requested static libstdc++.
if builder.config.llvm_tools_enabled || builder.config.llvm_static_stdcpp {
if !target.contains("msvc") && !target.contains("netbsd") {
if target.contains("apple") {
cfg.define("CMAKE_EXE_LINKER_FLAGS", "-static-libstdc++");
ldflags.push_all("-static-libstdc++");
} else {
cfg.define("CMAKE_EXE_LINKER_FLAGS", "-Wl,-Bsymbolic -static-libstdc++");
ldflags.push_all("-Wl,-Bsymbolic -static-libstdc++");
}
}
}

if !target.contains("freebsd") && target.starts_with("riscv") {
if target.starts_with("riscv") && !target.contains("freebsd") {
// RISC-V GCC erroneously requires linking against
// `libatomic` when using 1-byte and 2-byte C++
// atomics but the LLVM build system check cannot
// detect this. Therefore it is set manually here.
// FreeBSD uses Clang as its system compiler and
// 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");
} else {
cfg.define("CMAKE_EXE_LINKER_FLAGS", "-latomic -static-libstdc++");
}
cfg.define("CMAKE_SHARED_LINKER_FLAGS", "-latomic");
ldflags.exe.push(" -latomic");
ldflags.shared.push(" -latomic");
}

if target.contains("msvc") {
Expand Down Expand Up @@ -309,7 +330,7 @@ impl Step for Llvm {

// 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
Expand Down Expand Up @@ -351,7 +372,7 @@ impl Step for Llvm {
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);
Expand Down Expand Up @@ -399,6 +420,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.
Expand Down Expand Up @@ -507,31 +529,38 @@ 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));
}
cfg.define("CMAKE_C_FLAGS", cflags);
let mut cxxflags = builder.cflags(target, GitRepo::Llvm).join(" ");
if builder.config.llvm_static_stdcpp && !target.contains("msvc") && !target.contains("netbsd") {
cxxflags.push_str(" -static-libstdc++");
if let Some(flags) = env::var_os("CFLAGS") {
cflags.push(" ");
cflags.push(flags);
}
cfg.define("CMAKE_C_FLAGS", cflags);
let mut cxxflags: OsString = builder.cflags(target, GitRepo::Llvm).join(" ").into();
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) {
Expand All @@ -550,12 +579,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");
}
Expand Down Expand Up @@ -598,7 +633,7 @@ impl Step for Lld {
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
Expand Down Expand Up @@ -788,7 +823,7 @@ impl Step for Sanitizers {
// 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);
Expand Down

0 comments on commit 6655109

Please sign in to comment.