4 println!("cargo:rerun-if-changed=build.rs");
5 let target = env::var("TARGET").expect("TARGET was not set");
7 if cfg!(target_os = "linux") && cfg!(feature = "system-llvm-libunwind") {
8 // linking for Linux is handled in lib.rs
12 if cfg!(feature = "llvm-libunwind")
13 && ((target.contains("linux") && !target.contains("musl")) || target.contains("fuchsia"))
15 // Build the unwinding from libunwind C/C++ source code.
16 llvm_libunwind::compile();
17 } else if target.contains("x86_64-fortanix-unknown-sgx") {
18 llvm_libunwind::compile();
19 } else if target.contains("linux") {
20 // linking for Linux is handled in lib.rs
21 if target.contains("musl") {
22 llvm_libunwind::compile();
24 } else if target.contains("freebsd") {
25 println!("cargo:rustc-link-lib=gcc_s");
26 } else if target.contains("netbsd") {
27 println!("cargo:rustc-link-lib=gcc_s");
28 } else if target.contains("openbsd") {
29 if target.contains("sparc64") {
30 println!("cargo:rustc-link-lib=gcc");
32 println!("cargo:rustc-link-lib=c++abi");
34 } else if target.contains("solaris") {
35 println!("cargo:rustc-link-lib=gcc_s");
36 } else if target.contains("illumos") {
37 println!("cargo:rustc-link-lib=gcc_s");
38 } else if target.contains("dragonfly") {
39 println!("cargo:rustc-link-lib=gcc_pic");
40 } else if target.contains("pc-windows-gnu") {
41 // This is handled in the target spec with late_link_args_[static|dynamic]
42 } else if target.contains("uwp-windows-gnu") {
43 println!("cargo:rustc-link-lib=unwind");
44 } else if target.contains("fuchsia") {
45 println!("cargo:rustc-link-lib=unwind");
46 } else if target.contains("haiku") {
47 println!("cargo:rustc-link-lib=gcc_s");
48 } else if target.contains("redox") {
49 // redox is handled in lib.rs
57 /// Compile the libunwind C/C++ source code.
59 let target = env::var("TARGET").expect("TARGET was not set");
60 let target_env = env::var("CARGO_CFG_TARGET_ENV").unwrap();
61 let mut cc_cfg = cc::Build::new();
62 let mut cpp_cfg = cc::Build::new();
63 let root = Path::new("../../src/llvm-project/libunwind");
66 cpp_cfg.cpp_set_stdlib(None);
67 cpp_cfg.flag("-nostdinc++");
68 cpp_cfg.flag("-fno-exceptions");
69 cpp_cfg.flag("-fno-rtti");
70 cpp_cfg.flag_if_supported("-fvisibility-global-new-delete-hidden");
72 // Don't set this for clang
73 // By default, Clang builds C code in GNU C17 mode.
74 // By default, Clang builds C++ code according to the C++98 standard,
75 // with many C++11 features accepted as extensions.
76 if cpp_cfg.get_compiler().is_like_gnu() {
77 cpp_cfg.flag("-std=c++11");
78 cc_cfg.flag("-std=c99");
81 if target.contains("x86_64-fortanix-unknown-sgx") || target_env == "musl" {
82 // use the same GCC C compiler command to compile C++ code so we do not need to setup the
83 // C++ compiler env variables on the builders.
84 // Don't set this for clang++, as clang++ is able to compile this without libc++.
85 if cpp_cfg.get_compiler().is_like_gnu() {
90 for cfg in [&mut cc_cfg, &mut cpp_cfg].iter_mut() {
92 cfg.flag("-fstrict-aliasing");
93 cfg.flag("-funwind-tables");
94 cfg.flag("-fvisibility=hidden");
95 cfg.define("_LIBUNWIND_DISABLE_VISIBILITY_ANNOTATIONS", None);
96 cfg.include(root.join("include"));
97 cfg.cargo_metadata(false);
99 if target.contains("x86_64-fortanix-unknown-sgx") {
100 cfg.static_flag(true);
102 cfg.flag("-fno-stack-protector");
103 cfg.flag("-ffreestanding");
104 cfg.flag("-fexceptions");
106 // easiest way to undefine since no API available in cc::Build to undefine
107 cfg.flag("-U_FORTIFY_SOURCE");
108 cfg.define("_FORTIFY_SOURCE", "0");
109 cfg.define("RUST_SGX", "1");
110 cfg.define("__NO_STRING_INLINES", None);
111 cfg.define("__NO_MATH_INLINES", None);
112 cfg.define("_LIBUNWIND_IS_BAREMETAL", None);
113 cfg.define("__LIBUNWIND_IS_NATIVE_ONLY", None);
114 cfg.define("NDEBUG", None);
118 let mut c_sources = vec![
120 "UnwindLevel1-gcc-ext.c",
122 "UnwindRegistersRestore.S",
123 "UnwindRegistersSave.S",
126 let cpp_sources = vec!["Unwind-EHABI.cpp", "Unwind-seh.cpp", "libunwind.cpp"];
127 let cpp_len = cpp_sources.len();
129 if target.contains("x86_64-fortanix-unknown-sgx") {
130 c_sources.push("UnwindRustSgx.c");
133 for src in c_sources {
134 cc_cfg.file(root.join("src").join(src).canonicalize().unwrap());
137 for src in cpp_sources {
138 cpp_cfg.file(root.join("src").join(src).canonicalize().unwrap());
141 let out_dir = env::var("OUT_DIR").unwrap();
142 println!("cargo:rustc-link-search=native={}", &out_dir);
144 cpp_cfg.compile("unwind-cpp");
147 for entry in std::fs::read_dir(&out_dir).unwrap() {
148 let obj = entry.unwrap().path().canonicalize().unwrap();
149 if let Some(ext) = obj.extension() {
156 assert_eq!(cpp_len, count, "Can't get object files from {:?}", &out_dir);
157 cc_cfg.compile("unwind");