-
Notifications
You must be signed in to change notification settings - Fork 13.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
libunwind fix and cleanup #84124
libunwind fix and cleanup #84124
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -24,5 +24,12 @@ cfg-if = "0.1.8" | |
cc = "1.0.67" | ||
|
||
[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 = [] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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(); | ||
|
||
cfg.cpp(true); | ||
cfg.cpp_set_stdlib(None); | ||
cfg.warnings(false); | ||
let mut cc_cfg = cc::Build::new(); | ||
let mut cpp_cfg = cc::Build::new(); | ||
let root = Path::new("../../src/llvm-project/libunwind"); | ||
|
||
// libunwind expects a __LITTLE_ENDIAN__ macro to be set for LE archs, cf. #65765 | ||
if target_endian_little { | ||
cfg.define("__LITTLE_ENDIAN__", Some("1")); | ||
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"); | ||
|
||
// 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); | ||
|
||
cfg.static_flag(true); | ||
cfg.opt_level(3); | ||
|
||
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("-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"); | ||
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.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"); | ||
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_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" { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, great, so there is a way to get |
||
cc_cfg.object(&obj); | ||
count += 1; | ||
} | ||
} | ||
} | ||
assert_eq!(cpp_len, count, "Can't get object files from {:?}", &out_dir); | ||
cc_cfg.compile("unwind"); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does musl support linking with static libgcc at all?
If it does, then linking to libunwind when
llvm-libunwind = 'no'
is specified doesn't look right, perhaps rustbuild should have different defaults for musl instead.I don't suggest doing it in this PR, but could you make an issue for this (if musl does support linking with static libgcc)?
Otherwise adding the fact that musl doesn't support linking with static libgcc to the docs should be enough.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
musl support linking with
libgcc_eh.a
This is the default behavior for musl target since
libunwind
crate was added. Maybe rust-lang/compiler-team#422 would fix this situation.