diff options
| author | bors <bors@rust-lang.org> | 2019-04-04 05:24:54 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2019-04-04 05:24:54 +0000 |
| commit | f717b58dd70829f105960a071c7992b440720482 (patch) | |
| tree | 93d798116dc2a7156982905e6cfcd536a6a0777a | |
| parent | a5dfdc589a1b44f01cb640cd0244372dcbbd6f37 (diff) | |
| parent | 86d1678403a46cd30019487dcc21166c1d09a597 (diff) | |
| download | rust-f717b58dd70829f105960a071c7992b440720482.tar.gz rust-f717b58dd70829f105960a071c7992b440720482.zip | |
Auto merge of #59089 - petrhosek:llvm-unwind, r=petrhosek
Support using LLVM's libunwind as the unwinder implementation This avoids the dependency on host libraries such as libgcc_s which may be undesirable in some deployment environments where these aren't available.
| -rw-r--r-- | Cargo.lock | 1 | ||||
| -rw-r--r-- | config.toml.example | 3 | ||||
| -rw-r--r-- | src/bootstrap/config.rs | 3 | ||||
| -rwxr-xr-x | src/bootstrap/configure.py | 2 | ||||
| -rw-r--r-- | src/bootstrap/lib.rs | 3 | ||||
| -rw-r--r-- | src/libstd/Cargo.toml | 1 | ||||
| -rw-r--r-- | src/libunwind/Cargo.toml | 9 | ||||
| -rw-r--r-- | src/libunwind/build.rs | 67 | ||||
| m--------- | src/llvm-project | 0 |
9 files changed, 88 insertions, 1 deletions
diff --git a/Cargo.lock b/Cargo.lock index c7007017078..4a71884cb08 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3849,6 +3849,7 @@ dependencies = [ name = "unwind" version = "0.0.0" dependencies = [ + "cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)", "compiler_builtins 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/config.toml.example b/config.toml.example index 5e0a2fbf0d3..8b2153cd2e6 100644 --- a/config.toml.example +++ b/config.toml.example @@ -421,6 +421,9 @@ # development of NLL #test-compare-mode = false +# Use LLVM libunwind as the implementation for Rust's unwinder. +#llvm-libunwind = false + # ============================================================================= # Options for specific targets # diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index cb71550c12d..0c31c41ceda 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -48,6 +48,7 @@ pub struct Config { pub exclude: Vec<PathBuf>, pub rustc_error_format: Option<String>, pub test_compare_mode: bool, + pub llvm_libunwind: bool, pub run_host_only: bool, @@ -329,6 +330,7 @@ struct Rust { remap_debuginfo: Option<bool>, jemalloc: Option<bool>, test_compare_mode: Option<bool>, + llvm_libunwind: Option<bool>, } /// TOML representation of how each build target is configured. @@ -548,6 +550,7 @@ impl Config { set(&mut config.rust_rpath, rust.rpath); set(&mut config.jemalloc, rust.jemalloc); set(&mut config.test_compare_mode, rust.test_compare_mode); + set(&mut config.llvm_libunwind, rust.llvm_libunwind); set(&mut config.backtrace, rust.backtrace); set(&mut config.channel, rust.channel.clone()); set(&mut config.rust_dist_src, rust.dist_src); diff --git a/src/bootstrap/configure.py b/src/bootstrap/configure.py index b2d8f2d8ebf..ade8afee7c1 100755 --- a/src/bootstrap/configure.py +++ b/src/bootstrap/configure.py @@ -68,6 +68,8 @@ o("cflags", "llvm.cflags", "build LLVM with these extra compiler flags") o("cxxflags", "llvm.cxxflags", "build LLVM with these extra compiler flags") o("ldflags", "llvm.ldflags", "build LLVM with these extra linker flags") +o("llvm-libunwind", "rust.llvm_libunwind", "use LLVM libunwind") + # Optimization and debugging options. These may be overridden by the release # channel, etc. o("optimize", "rust.optimize", "build optimized rust code") diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 47ac04baf6d..bcd28e9cf5e 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -506,6 +506,9 @@ impl Build { fn std_features(&self) -> String { let mut features = "panic-unwind".to_string(); + if self.config.llvm_libunwind { + features.push_str(" llvm-libunwind"); + } if self.config.backtrace { features.push_str(" backtrace"); } diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml index 9ac03adfc27..875483518e8 100644 --- a/src/libstd/Cargo.toml +++ b/src/libstd/Cargo.toml @@ -54,6 +54,7 @@ backtrace = ["backtrace-sys"] panic-unwind = ["panic_unwind"] profiler = ["profiler_builtins"] compiler_builtins_c = ["compiler_builtins/c"] +llvm-libunwind = ["unwind/llvm-libunwind"] # Make panics and failed asserts immediately abort without formatting any message panic_immediate_abort = ["core/panic_immediate_abort"] diff --git a/src/libunwind/Cargo.toml b/src/libunwind/Cargo.toml index 2378b0a315a..4ddc878997e 100644 --- a/src/libunwind/Cargo.toml +++ b/src/libunwind/Cargo.toml @@ -4,6 +4,9 @@ name = "unwind" version = "0.0.0" build = "build.rs" edition = "2018" +include = [ + '/libunwind/*', +] [lib] name = "unwind" @@ -16,3 +19,9 @@ doc = false core = { path = "../libcore" } libc = { version = "0.2.43", features = ['rustc-dep-of-std'], default-features = false } compiler_builtins = "0.1.0" + +[build-dependencies] +cc = { optional = true, version = "1.0.1" } + +[features] +llvm-libunwind = ["cc"] diff --git a/src/libunwind/build.rs b/src/libunwind/build.rs index b50a11fa03a..f3fda9eaa75 100644 --- a/src/libunwind/build.rs +++ b/src/libunwind/build.rs @@ -4,7 +4,13 @@ fn main() { println!("cargo:rerun-if-changed=build.rs"); let target = env::var("TARGET").expect("TARGET was not set"); - if target.contains("linux") { + if cfg!(feature = "llvm-libunwind") && + (target.contains("linux") || + target.contains("fuchsia")) { + // Build the unwinding from libunwind C/C++ source code. + #[cfg(feature = "llvm-libunwind")] + llvm_libunwind::compile(); + } else if target.contains("linux") { if target.contains("musl") { // musl is handled in lib.rs } else if !target.contains("android") { @@ -37,3 +43,62 @@ fn main() { println!("cargo:rustc-link-lib=unwind"); } } + +#[cfg(feature = "llvm-libunwind")] +mod llvm_libunwind { + use std::env; + use std::path::Path; + + /// Compile the libunwind C/C++ source code. + pub fn compile() { + let target_env = env::var("CARGO_CFG_TARGET_ENV").unwrap(); + let target_vendor = env::var("CARGO_CFG_TARGET_VENDOR").unwrap(); + let cfg = &mut cc::Build::new(); + + cfg.cpp(true); + cfg.cpp_set_stdlib(None); + cfg.warnings(false); + + if target_env == "msvc" { + // Don't pull in extra libraries on MSVC + cfg.flag("/Zl"); + cfg.flag("/EHsc"); + cfg.define("_CRT_SECURE_NO_WARNINGS", None); + cfg.define("_LIBUNWIND_DISABLE_VISIBILITY_ANNOTATIONS", None); + } else { + cfg.flag("-std=c99"); + cfg.flag("-std=c++11"); + cfg.flag("-nostdinc++"); + if cfg.is_flag_supported("-funwind-tables").unwrap_or_default() && + cfg.is_flag_supported("-fno-exceptions").unwrap_or_default() { + cfg.flag("-funwind-tables"); + cfg.flag("-fno-exceptions"); + } + cfg.flag("-fno-rtti"); + cfg.flag("-fstrict-aliasing"); + } + + let mut unwind_sources = vec![ + "Unwind-EHABI.cpp", + "Unwind-seh.cpp", + "Unwind-sjlj.c", + "UnwindLevel1-gcc-ext.c", + "UnwindLevel1.c", + "UnwindRegistersRestore.S", + "UnwindRegistersSave.S", + "libunwind.cpp", + ]; + + if target_vendor == "apple" { + unwind_sources.push("Unwind_AppleExtras.cpp"); + } + + let root = Path::new("../llvm-project/libunwind"); + cfg.include(root.join("include")); + for src in unwind_sources { + cfg.file(root.join("src").join(src)); + } + + cfg.compile("unwind"); + } +} diff --git a/src/llvm-project b/src/llvm-project -Subproject 1f484cbe0e863e9e215f1b3d7198063444d6087 +Subproject 84abffda0e03b03c62bdfc3cfeda1c2cf1f88c8 |
