]> git.lizzy.rs Git - rust.git/blob - library/unwind/build.rs
Rollup merge of #85730 - Smittyvb:iter-min-max-floats, r=m-ou-se
[rust.git] / library / unwind / build.rs
1 use std::env;
2
3 fn main() {
4     println!("cargo:rerun-if-changed=build.rs");
5     let target = env::var("TARGET").expect("TARGET was not set");
6
7     if cfg!(target_os = "linux") && cfg!(feature = "system-llvm-libunwind") {
8         // linking for Linux is handled in lib.rs
9         return;
10     }
11
12     if cfg!(feature = "llvm-libunwind")
13         && ((target.contains("linux") && !target.contains("musl")) || target.contains("fuchsia"))
14     {
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();
23         }
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");
31         } else {
32             println!("cargo:rustc-link-lib=c++abi");
33         }
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
50     }
51 }
52
53 mod llvm_libunwind {
54     use std::env;
55     use std::path::Path;
56
57     /// Compile the libunwind C/C++ source code.
58     pub fn compile() {
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");
64
65         cpp_cfg.cpp(true);
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");
71
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");
79         }
80
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() {
86                 cpp_cfg.cpp(false);
87             }
88         }
89
90         for cfg in [&mut cc_cfg, &mut cpp_cfg].iter_mut() {
91             cfg.warnings(false);
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);
98
99             if target.contains("x86_64-fortanix-unknown-sgx") {
100                 cfg.static_flag(true);
101                 cfg.opt_level(3);
102                 cfg.flag("-fno-stack-protector");
103                 cfg.flag("-ffreestanding");
104                 cfg.flag("-fexceptions");
105
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);
115             }
116         }
117
118         let mut c_sources = vec![
119             "Unwind-sjlj.c",
120             "UnwindLevel1-gcc-ext.c",
121             "UnwindLevel1.c",
122             "UnwindRegistersRestore.S",
123             "UnwindRegistersSave.S",
124         ];
125
126         let cpp_sources = vec!["Unwind-EHABI.cpp", "Unwind-seh.cpp", "libunwind.cpp"];
127         let cpp_len = cpp_sources.len();
128
129         if target.contains("x86_64-fortanix-unknown-sgx") {
130             c_sources.push("UnwindRustSgx.c");
131         }
132
133         for src in c_sources {
134             cc_cfg.file(root.join("src").join(src).canonicalize().unwrap());
135         }
136
137         for src in cpp_sources {
138             cpp_cfg.file(root.join("src").join(src).canonicalize().unwrap());
139         }
140
141         let out_dir = env::var("OUT_DIR").unwrap();
142         println!("cargo:rustc-link-search=native={}", &out_dir);
143
144         cpp_cfg.compile("unwind-cpp");
145
146         let mut count = 0;
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() {
150                 if ext == "o" {
151                     cc_cfg.object(&obj);
152                     count += 1;
153                 }
154             }
155         }
156         assert_eq!(cpp_len, count, "Can't get object files from {:?}", &out_dir);
157         cc_cfg.compile("unwind");
158     }
159 }