mirror of
https://github.com/rust-lang/rust.git
synced 2024-10-30 05:51:58 +00:00
Auto merge of #84124 - 12101111:libunwind, r=petrochenkov
libunwind fix and cleanup
Fix:
1. "system-llvm-libunwind" now only skip build-script for linux target
2. workaround from https://github.com/rust-lang/rust/pull/65972 is not needed, upstream fix it in 68c50708d1
( LLVM 11 )
3. remove code for MSCV and Apple in `compile()`, as they are not used
4. fix https://github.com/rust-lang/rust/issues/69222 , compile c files and cpp files in different config
5. fix conditional compilation for musl target.
6. fix that x86_64-fortanix-unknown-sgx don't link libunwind built in build-script into rlib
This commit is contained in:
commit
9814e83094
@ -563,6 +563,14 @@ changelog-seen = 2
|
||||
|
||||
# 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'
|
||||
|
||||
# Enable Windows Control Flow Guard checks in the standard library.
|
||||
|
@ -24,5 +24,12 @@ cfg-if = "0.1.8"
|
||||
cc = "1.0.68"
|
||||
|
||||
[features]
|
||||
|
||||
# Only applies for Linux and Fuchsia targets
|
||||
# Static link to the in-tree build of llvm libunwind
|
||||
llvm-libunwind = []
|
||||
|
||||
# Only applies for Linux and Fuchsia targets
|
||||
# If crt-static is enabled, static link to `libunwind.a` provided by system
|
||||
# If crt-static is disabled, dynamic link to `libunwind.so` provided by system
|
||||
system-llvm-libunwind = []
|
||||
|
@ -4,7 +4,8 @@ fn main() {
|
||||
println!("cargo:rerun-if-changed=build.rs");
|
||||
let target = env::var("TARGET").expect("TARGET was not set");
|
||||
|
||||
if cfg!(feature = "system-llvm-libunwind") {
|
||||
if cfg!(target_os = "linux") && cfg!(feature = "system-llvm-libunwind") {
|
||||
// linking for Linux is handled in lib.rs
|
||||
return;
|
||||
}
|
||||
|
||||
@ -57,101 +58,102 @@ mod llvm_libunwind {
|
||||
pub fn compile() {
|
||||
let target = env::var("TARGET").expect("TARGET was not set");
|
||||
let target_env = env::var("CARGO_CFG_TARGET_ENV").unwrap();
|
||||
let target_vendor = env::var("CARGO_CFG_TARGET_VENDOR").unwrap();
|
||||
let target_endian_little = env::var("CARGO_CFG_TARGET_ENDIAN").unwrap() != "big";
|
||||
let cfg = &mut cc::Build::new();
|
||||
let mut cc_cfg = cc::Build::new();
|
||||
let mut cpp_cfg = cc::Build::new();
|
||||
let root = Path::new("../../src/llvm-project/libunwind");
|
||||
|
||||
cfg.cpp(true);
|
||||
cfg.cpp_set_stdlib(None);
|
||||
cfg.warnings(false);
|
||||
cpp_cfg.cpp(true);
|
||||
cpp_cfg.cpp_set_stdlib(None);
|
||||
cpp_cfg.flag("-nostdinc++");
|
||||
cpp_cfg.flag("-fno-exceptions");
|
||||
cpp_cfg.flag("-fno-rtti");
|
||||
cpp_cfg.flag_if_supported("-fvisibility-global-new-delete-hidden");
|
||||
|
||||
// libunwind expects a __LITTLE_ENDIAN__ macro to be set for LE archs, cf. #65765
|
||||
if target_endian_little {
|
||||
cfg.define("__LITTLE_ENDIAN__", Some("1"));
|
||||
// Don't set this for clang
|
||||
// By default, Clang builds C code in GNU C17 mode.
|
||||
// By default, Clang builds C++ code according to the C++98 standard,
|
||||
// with many C++11 features accepted as extensions.
|
||||
if cpp_cfg.get_compiler().is_like_gnu() {
|
||||
cpp_cfg.flag("-std=c++11");
|
||||
cc_cfg.flag("-std=c99");
|
||||
}
|
||||
|
||||
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 if target.contains("x86_64-fortanix-unknown-sgx") {
|
||||
cfg.cpp(false);
|
||||
if target.contains("x86_64-fortanix-unknown-sgx") || target_env == "musl" {
|
||||
// use the same GCC C compiler command to compile C++ code so we do not need to setup the
|
||||
// C++ compiler env variables on the builders.
|
||||
// Don't set this for clang++, as clang++ is able to compile this without libc++.
|
||||
if cpp_cfg.get_compiler().is_like_gnu() {
|
||||
cpp_cfg.cpp(false);
|
||||
}
|
||||
}
|
||||
|
||||
cfg.static_flag(true);
|
||||
cfg.opt_level(3);
|
||||
|
||||
cfg.flag("-nostdinc++");
|
||||
cfg.flag("-fno-exceptions");
|
||||
cfg.flag("-fno-rtti");
|
||||
for cfg in [&mut cc_cfg, &mut cpp_cfg].iter_mut() {
|
||||
cfg.warnings(false);
|
||||
cfg.flag("-fstrict-aliasing");
|
||||
cfg.flag("-funwind-tables");
|
||||
cfg.flag("-fvisibility=hidden");
|
||||
cfg.flag("-fno-stack-protector");
|
||||
cfg.flag("-ffreestanding");
|
||||
cfg.flag("-fexceptions");
|
||||
|
||||
// easiest way to undefine since no API available in cc::Build to undefine
|
||||
cfg.flag("-U_FORTIFY_SOURCE");
|
||||
cfg.define("_FORTIFY_SOURCE", "0");
|
||||
|
||||
cfg.flag_if_supported("-fvisibility-global-new-delete-hidden");
|
||||
|
||||
cfg.define("_LIBUNWIND_DISABLE_VISIBILITY_ANNOTATIONS", None);
|
||||
cfg.define("RUST_SGX", "1");
|
||||
cfg.define("__NO_STRING_INLINES", None);
|
||||
cfg.define("__NO_MATH_INLINES", None);
|
||||
cfg.define("_LIBUNWIND_IS_BAREMETAL", None);
|
||||
cfg.define("__LIBUNWIND_IS_NATIVE_ONLY", None);
|
||||
cfg.define("NDEBUG", None);
|
||||
} else {
|
||||
cfg.flag("-std=c99");
|
||||
cfg.flag("-std=c++11");
|
||||
cfg.flag("-nostdinc++");
|
||||
cfg.flag("-fno-exceptions");
|
||||
cfg.flag("-fno-rtti");
|
||||
cfg.flag("-fstrict-aliasing");
|
||||
cfg.flag("-funwind-tables");
|
||||
cfg.flag("-fvisibility=hidden");
|
||||
cfg.flag_if_supported("-fvisibility-global-new-delete-hidden");
|
||||
cfg.define("_LIBUNWIND_DISABLE_VISIBILITY_ANNOTATIONS", None);
|
||||
cfg.include(root.join("include"));
|
||||
cfg.cargo_metadata(false);
|
||||
|
||||
if target.contains("x86_64-fortanix-unknown-sgx") {
|
||||
cfg.static_flag(true);
|
||||
cfg.opt_level(3);
|
||||
cfg.flag("-fno-stack-protector");
|
||||
cfg.flag("-ffreestanding");
|
||||
cfg.flag("-fexceptions");
|
||||
|
||||
// easiest way to undefine since no API available in cc::Build to undefine
|
||||
cfg.flag("-U_FORTIFY_SOURCE");
|
||||
cfg.define("_FORTIFY_SOURCE", "0");
|
||||
cfg.define("RUST_SGX", "1");
|
||||
cfg.define("__NO_STRING_INLINES", None);
|
||||
cfg.define("__NO_MATH_INLINES", None);
|
||||
cfg.define("_LIBUNWIND_IS_BAREMETAL", None);
|
||||
cfg.define("__LIBUNWIND_IS_NATIVE_ONLY", None);
|
||||
cfg.define("NDEBUG", None);
|
||||
}
|
||||
}
|
||||
|
||||
let mut unwind_sources = vec![
|
||||
"Unwind-EHABI.cpp",
|
||||
"Unwind-seh.cpp",
|
||||
let mut c_sources = vec![
|
||||
"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 cpp_sources = vec!["Unwind-EHABI.cpp", "Unwind-seh.cpp", "libunwind.cpp"];
|
||||
let cpp_len = cpp_sources.len();
|
||||
|
||||
if target.contains("x86_64-fortanix-unknown-sgx") {
|
||||
unwind_sources.push("UnwindRustSgx.c");
|
||||
c_sources.push("UnwindRustSgx.c");
|
||||
}
|
||||
|
||||
let root = Path::new("../../src/llvm-project/libunwind");
|
||||
cfg.include(root.join("include"));
|
||||
for src in unwind_sources {
|
||||
cfg.file(root.join("src").join(src));
|
||||
for src in c_sources {
|
||||
cc_cfg.file(root.join("src").join(src).canonicalize().unwrap());
|
||||
}
|
||||
|
||||
if target_env == "musl" {
|
||||
// use the same C compiler command to compile C++ code so we do not need to setup the
|
||||
// C++ compiler env variables on the builders
|
||||
cfg.cpp(false);
|
||||
// linking for musl is handled in lib.rs
|
||||
cfg.cargo_metadata(false);
|
||||
println!("cargo:rustc-link-search=native={}", env::var("OUT_DIR").unwrap());
|
||||
for src in cpp_sources {
|
||||
cpp_cfg.file(root.join("src").join(src).canonicalize().unwrap());
|
||||
}
|
||||
|
||||
cfg.compile("unwind");
|
||||
let out_dir = env::var("OUT_DIR").unwrap();
|
||||
println!("cargo:rustc-link-search=native={}", &out_dir);
|
||||
|
||||
cpp_cfg.compile("unwind-cpp");
|
||||
|
||||
let mut count = 0;
|
||||
for entry in std::fs::read_dir(&out_dir).unwrap() {
|
||||
let obj = entry.unwrap().path().canonicalize().unwrap();
|
||||
if let Some(ext) = obj.extension() {
|
||||
if ext == "o" {
|
||||
cc_cfg.object(&obj);
|
||||
count += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
assert_eq!(cpp_len, count, "Can't get object files from {:?}", &out_dir);
|
||||
cc_cfg.compile("unwind");
|
||||
}
|
||||
}
|
||||
|
@ -37,9 +37,22 @@ cfg_if::cfg_if! {
|
||||
}
|
||||
|
||||
#[cfg(target_env = "musl")]
|
||||
#[link(name = "unwind", kind = "static", cfg(target_feature = "crt-static"))]
|
||||
#[link(name = "gcc_s", cfg(not(target_feature = "crt-static")))]
|
||||
extern "C" {}
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(all(feature = "llvm-libunwind", feature = "system-llvm-libunwind"))] {
|
||||
compile_error!("`llvm-libunwind` and `system-llvm-libunwind` cannot be enabled at the same time");
|
||||
} else if #[cfg(feature = "llvm-libunwind")] {
|
||||
#[link(name = "unwind", kind = "static")]
|
||||
extern "C" {}
|
||||
} else if #[cfg(feature = "system-llvm-libunwind")] {
|
||||
#[link(name = "unwind", kind = "static-nobundle", cfg(target_feature = "crt-static"))]
|
||||
#[link(name = "unwind", cfg(not(target_feature = "crt-static")))]
|
||||
extern "C" {}
|
||||
} else {
|
||||
#[link(name = "unwind", kind = "static", cfg(target_feature = "crt-static"))]
|
||||
#[link(name = "gcc_s", cfg(not(target_feature = "crt-static")))]
|
||||
extern "C" {}
|
||||
}
|
||||
}
|
||||
|
||||
// When building with crt-static, we get `gcc_eh` from the `libc` crate, since
|
||||
// glibc needs it, and needs it listed later on the linker command line. We
|
||||
@ -68,5 +81,5 @@ extern "C" {}
|
||||
extern "C" {}
|
||||
|
||||
#[cfg(all(target_vendor = "fortanix", target_env = "sgx"))]
|
||||
#[link(name = "unwind", kind = "static-nobundle")]
|
||||
#[link(name = "unwind", kind = "static")]
|
||||
extern "C" {}
|
||||
|
Loading…
Reference in New Issue
Block a user