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.
|
# Use LLVM libunwind as the implementation for Rust's unwinder.
|
||||||
# Accepted values are 'in-tree' (formerly true), 'system' or 'no' (formerly false).
|
# 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'
|
#llvm-libunwind = 'no'
|
||||||
|
|
||||||
# Enable Windows Control Flow Guard checks in the standard library.
|
# Enable Windows Control Flow Guard checks in the standard library.
|
||||||
|
@ -24,5 +24,12 @@ cfg-if = "0.1.8"
|
|||||||
cc = "1.0.68"
|
cc = "1.0.68"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
|
|
||||||
|
# Only applies for Linux and Fuchsia targets
|
||||||
|
# Static link to the in-tree build of llvm libunwind
|
||||||
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 = []
|
system-llvm-libunwind = []
|
||||||
|
@ -4,7 +4,8 @@ fn main() {
|
|||||||
println!("cargo:rerun-if-changed=build.rs");
|
println!("cargo:rerun-if-changed=build.rs");
|
||||||
let target = env::var("TARGET").expect("TARGET was not set");
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,101 +58,102 @@ mod llvm_libunwind {
|
|||||||
pub fn compile() {
|
pub fn compile() {
|
||||||
let target = env::var("TARGET").expect("TARGET was not set");
|
let target = env::var("TARGET").expect("TARGET was not set");
|
||||||
let target_env = env::var("CARGO_CFG_TARGET_ENV").unwrap();
|
let target_env = env::var("CARGO_CFG_TARGET_ENV").unwrap();
|
||||||
let target_vendor = env::var("CARGO_CFG_TARGET_VENDOR").unwrap();
|
let mut cc_cfg = cc::Build::new();
|
||||||
let target_endian_little = env::var("CARGO_CFG_TARGET_ENDIAN").unwrap() != "big";
|
let mut cpp_cfg = cc::Build::new();
|
||||||
let cfg = &mut cc::Build::new();
|
let root = Path::new("../../src/llvm-project/libunwind");
|
||||||
|
|
||||||
cfg.cpp(true);
|
cpp_cfg.cpp(true);
|
||||||
cfg.cpp_set_stdlib(None);
|
cpp_cfg.cpp_set_stdlib(None);
|
||||||
cfg.warnings(false);
|
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
|
// Don't set this for clang
|
||||||
if target_endian_little {
|
// By default, Clang builds C code in GNU C17 mode.
|
||||||
cfg.define("__LITTLE_ENDIAN__", Some("1"));
|
// 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" {
|
if target.contains("x86_64-fortanix-unknown-sgx") || target_env == "musl" {
|
||||||
// Don't pull in extra libraries on MSVC
|
// use the same GCC C compiler command to compile C++ code so we do not need to setup the
|
||||||
cfg.flag("/Zl");
|
// C++ compiler env variables on the builders.
|
||||||
cfg.flag("/EHsc");
|
// Don't set this for clang++, as clang++ is able to compile this without libc++.
|
||||||
cfg.define("_CRT_SECURE_NO_WARNINGS", None);
|
if cpp_cfg.get_compiler().is_like_gnu() {
|
||||||
cfg.define("_LIBUNWIND_DISABLE_VISIBILITY_ANNOTATIONS", None);
|
cpp_cfg.cpp(false);
|
||||||
} else if target.contains("x86_64-fortanix-unknown-sgx") {
|
}
|
||||||
cfg.cpp(false);
|
}
|
||||||
|
|
||||||
cfg.static_flag(true);
|
for cfg in [&mut cc_cfg, &mut cpp_cfg].iter_mut() {
|
||||||
cfg.opt_level(3);
|
cfg.warnings(false);
|
||||||
|
|
||||||
cfg.flag("-nostdinc++");
|
|
||||||
cfg.flag("-fno-exceptions");
|
|
||||||
cfg.flag("-fno-rtti");
|
|
||||||
cfg.flag("-fstrict-aliasing");
|
cfg.flag("-fstrict-aliasing");
|
||||||
cfg.flag("-funwind-tables");
|
cfg.flag("-funwind-tables");
|
||||||
cfg.flag("-fvisibility=hidden");
|
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.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![
|
let mut c_sources = vec![
|
||||||
"Unwind-EHABI.cpp",
|
|
||||||
"Unwind-seh.cpp",
|
|
||||||
"Unwind-sjlj.c",
|
"Unwind-sjlj.c",
|
||||||
"UnwindLevel1-gcc-ext.c",
|
"UnwindLevel1-gcc-ext.c",
|
||||||
"UnwindLevel1.c",
|
"UnwindLevel1.c",
|
||||||
"UnwindRegistersRestore.S",
|
"UnwindRegistersRestore.S",
|
||||||
"UnwindRegistersSave.S",
|
"UnwindRegistersSave.S",
|
||||||
"libunwind.cpp",
|
|
||||||
];
|
];
|
||||||
|
|
||||||
if target_vendor == "apple" {
|
let cpp_sources = vec!["Unwind-EHABI.cpp", "Unwind-seh.cpp", "libunwind.cpp"];
|
||||||
unwind_sources.push("Unwind_AppleExtras.cpp");
|
let cpp_len = cpp_sources.len();
|
||||||
}
|
|
||||||
|
|
||||||
if target.contains("x86_64-fortanix-unknown-sgx") {
|
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");
|
for src in c_sources {
|
||||||
cfg.include(root.join("include"));
|
cc_cfg.file(root.join("src").join(src).canonicalize().unwrap());
|
||||||
for src in unwind_sources {
|
|
||||||
cfg.file(root.join("src").join(src));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if target_env == "musl" {
|
for src in cpp_sources {
|
||||||
// use the same C compiler command to compile C++ code so we do not need to setup the
|
cpp_cfg.file(root.join("src").join(src).canonicalize().unwrap());
|
||||||
// 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());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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")]
|
#[cfg(target_env = "musl")]
|
||||||
#[link(name = "unwind", kind = "static", cfg(target_feature = "crt-static"))]
|
cfg_if::cfg_if! {
|
||||||
#[link(name = "gcc_s", cfg(not(target_feature = "crt-static")))]
|
if #[cfg(all(feature = "llvm-libunwind", feature = "system-llvm-libunwind"))] {
|
||||||
extern "C" {}
|
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
|
// 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
|
// glibc needs it, and needs it listed later on the linker command line. We
|
||||||
@ -68,5 +81,5 @@ extern "C" {}
|
|||||||
extern "C" {}
|
extern "C" {}
|
||||||
|
|
||||||
#[cfg(all(target_vendor = "fortanix", target_env = "sgx"))]
|
#[cfg(all(target_vendor = "fortanix", target_env = "sgx"))]
|
||||||
#[link(name = "unwind", kind = "static-nobundle")]
|
#[link(name = "unwind", kind = "static")]
|
||||||
extern "C" {}
|
extern "C" {}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user