Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bootstrap: tidy up flag handling for llvm build #93918

Merged
merged 2 commits into from
Feb 15, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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