mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 08:13:41 +00:00
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.
This commit is contained in:
parent
f8673e0ad8
commit
86d1678403
@ -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)",
|
||||
|
@ -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
|
||||
#
|
||||
|
@ -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);
|
||||
|
@ -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")
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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"]
|
||||
|
@ -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"]
|
||||
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 1f484cbe0e863e9e215f1b3d7198063444d60873
|
||||
Subproject commit 84abffda0e03b03c62bdfc3cfeda1c2cf1f88c85
|
Loading…
Reference in New Issue
Block a user