From f1e3d40456ad9d9b508439d828dac14c0670455b Mon Sep 17 00:00:00 2001 From: Tyler Mandry Date: Wed, 2 Feb 2022 22:48:09 +0000 Subject: [PATCH] Make llvm-libunwind a per-target option --- config.toml.example | 25 +++++++++++++++---------- src/bootstrap/compile.rs | 2 +- src/bootstrap/config.rs | 23 ++++++++++++++++++----- src/bootstrap/lib.rs | 2 +- 4 files changed, 35 insertions(+), 17 deletions(-) diff --git a/config.toml.example b/config.toml.example index a7968bca7be..a810e8c0e12 100644 --- a/config.toml.example +++ b/config.toml.example @@ -605,16 +605,9 @@ changelog-seen = 2 # development of NLL #test-compare-mode = false -# Use LLVM libunwind as the implementation for Rust's unwinder. -# Accepted values are 'in-tree' (formerly true), 'system' or 'no' (formerly false). -# This option only applies for Linux and Fuchsia targets. -# On Linux target, if crt-static is not enabled, 'no' means dynamic link to -# `libgcc_s.so`, 'in-tree' means static link to the in-tree build of llvm libunwind -# and 'system' means dynamic link to `libunwind.so`. If crt-static is enabled, -# the behavior is depend on the libc. On musl target, 'no' and 'in-tree' both -# means static link to the in-tree build of llvm libunwind, and 'system' means -# static link to `libunwind.a` provided by system. Due to the limitation of glibc, -# it must link to `libgcc_eh.a` to get a working output, and this option have no effect. +# Global default for llvm-libunwind for all targets. See the target-specific +# documentation for llvm-libunwind below. Note that the target-specific +# option will override this if set. #llvm-libunwind = 'no' # Enable Windows Control Flow Guard checks in the standard library. @@ -671,6 +664,18 @@ changelog-seen = 2 # not, you can specify an explicit file name for it. #llvm-filecheck = "/path/to/llvm-version/bin/FileCheck" +# Use LLVM libunwind as the implementation for Rust's unwinder. +# Accepted values are 'in-tree' (formerly true), 'system' or 'no' (formerly false). +# This option only applies for Linux and Fuchsia targets. +# On Linux target, if crt-static is not enabled, 'no' means dynamic link to +# `libgcc_s.so`, 'in-tree' means static link to the in-tree build of llvm libunwind +# and 'system' means dynamic link to `libunwind.so`. If crt-static is enabled, +# the behavior is depend on the libc. On musl target, 'no' and 'in-tree' both +# means static link to the in-tree build of llvm libunwind, and 'system' means +# static link to `libunwind.a` provided by system. Due to the limitation of glibc, +# it must link to `libgcc_eh.a` to get a working output, and this option have no effect. +#llvm-libunwind = 'no' if Linux, 'in-tree' if Fuchsia + # If this target is for Android, this option will be required to specify where # the NDK for the target lives. This is used to find the C compiler to link and # build native code. diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 7a8c7fee5f5..0b430f64e1e 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -176,7 +176,7 @@ fn copy_third_party_objects( if target == "x86_64-fortanix-unknown-sgx" || target.contains("pc-windows-gnullvm") - || builder.config.llvm_libunwind == LlvmLibunwind::InTree + || builder.config.llvm_libunwind(target) == LlvmLibunwind::InTree && (target.contains("linux") || target.contains("fuchsia")) { let libunwind_path = diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index f9acd52274f..843d276cd7a 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -67,7 +67,6 @@ pub struct Config { pub rustc_error_format: Option, pub json_output: bool, pub test_compare_mode: bool, - pub llvm_libunwind: LlvmLibunwind, pub color: Color, pub patch_binaries_for_nix: bool, @@ -151,6 +150,7 @@ pub struct Config { pub rust_profile_generate: Option, pub llvm_profile_use: Option, pub llvm_profile_generate: bool, + pub llvm_libunwind_default: Option, pub build: TargetSelection, pub hosts: Vec, @@ -342,6 +342,7 @@ pub struct Target { pub llvm_config: Option, /// Some(path to FileCheck) if one was specified. pub llvm_filecheck: Option, + pub llvm_libunwind: Option, pub cc: Option, pub cxx: Option, pub ar: Option, @@ -680,6 +681,7 @@ struct TomlTarget { linker: Option = "linker", llvm_config: Option = "llvm-config", llvm_filecheck: Option = "llvm-filecheck", + llvm_libunwind: Option = "llvm-libunwind", android_ndk: Option = "android-ndk", sanitizers: Option = "sanitizers", profiler: Option = "profiler", @@ -1043,10 +1045,6 @@ pub fn parse(args: &[String]) -> Config { set(&mut config.rust_rpath, rust.rpath); set(&mut config.jemalloc, rust.jemalloc); set(&mut config.test_compare_mode, rust.test_compare_mode); - config.llvm_libunwind = rust - .llvm_libunwind - .map(|v| v.parse().expect("failed to parse rust.llvm-libunwind")) - .unwrap_or_default(); set(&mut config.backtrace, rust.backtrace); set(&mut config.channel, rust.channel); config.description = rust.description; @@ -1069,6 +1067,9 @@ pub fn parse(args: &[String]) -> Config { config.rust_thin_lto_import_instr_limit = rust.thin_lto_import_instr_limit; set(&mut config.rust_remap_debuginfo, rust.remap_debuginfo); set(&mut config.control_flow_guard, rust.control_flow_guard); + config.llvm_libunwind_default = rust + .llvm_libunwind + .map(|v| v.parse().expect("failed to parse rust.llvm-libunwind")); if let Some(ref backends) = rust.codegen_backends { config.rust_codegen_backends = @@ -1095,6 +1096,10 @@ pub fn parse(args: &[String]) -> Config { if let Some(ref s) = cfg.llvm_filecheck { target.llvm_filecheck = Some(config.src.join(s)); } + target.llvm_libunwind = cfg + .llvm_libunwind + .as_ref() + .map(|v| v.parse().expect("failed to parse rust.llvm-libunwind")); if let Some(ref s) = cfg.android_ndk { target.ndk = Some(config.src.join(s)); } @@ -1328,6 +1333,14 @@ pub fn llvm_enabled(&self) -> bool { self.rust_codegen_backends.contains(&INTERNER.intern_str("llvm")) } + pub fn llvm_libunwind(&self, target: TargetSelection) -> LlvmLibunwind { + self.target_config + .get(&target) + .and_then(|t| t.llvm_libunwind) + .or(self.llvm_libunwind_default) + .unwrap_or(LlvmLibunwind::No) + } + pub fn submodules(&self, rust_info: &GitInfo) -> bool { self.submodules.unwrap_or(rust_info.is_git()) } diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 769382525fb..591f9a1ca50 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -720,7 +720,7 @@ fn clear_if_dirty(&self, dir: &Path, input: &Path) -> bool { fn std_features(&self, target: TargetSelection) -> String { let mut features = "panic-unwind".to_string(); - match self.config.llvm_libunwind { + match self.config.llvm_libunwind(target) { LlvmLibunwind::InTree => features.push_str(" llvm-libunwind"), LlvmLibunwind::System => features.push_str(" system-llvm-libunwind"), LlvmLibunwind::No => {}