@@ -4,7 +4,8 @@ fn main() {
4
4
println!("cargo:rerun-if-changed=build.rs");
5
5
let target = env::var("TARGET").expect("TARGET was not set");
6
6
7
- if cfg!(feature = "system-llvm-libunwind") {
7
+ if cfg!(target_os = "linux") && cfg!(feature = "system-llvm-libunwind") {
8
+ // linking for Linux is handled in lib.rs
8
9
return;
9
10
}
10
11
@@ -57,101 +58,102 @@ mod llvm_libunwind {
57
58
pub fn compile() {
58
59
let target = env::var("TARGET").expect("TARGET was not set");
59
60
let target_env = env::var("CARGO_CFG_TARGET_ENV").unwrap();
60
- let target_vendor = env::var("CARGO_CFG_TARGET_VENDOR").unwrap();
61
- let target_endian_little = env::var("CARGO_CFG_TARGET_ENDIAN").unwrap() != "big";
62
- let cfg = &mut cc::Build::new();
63
-
64
- cfg.cpp(true);
65
- cfg.cpp_set_stdlib(None);
66
- cfg.warnings(false);
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");
67
64
68
- // libunwind expects a __LITTLE_ENDIAN__ macro to be set for LE archs, cf. #65765
69
- if target_endian_little {
70
- cfg.define("__LITTLE_ENDIAN__", Some("1"));
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");
71
79
}
72
80
73
- if target_env == "msvc" {
74
- // Don't pull in extra libraries on MSVC
75
- cfg.flag("/Zl");
76
- cfg.flag("/EHsc");
77
- cfg.define("_CRT_SECURE_NO_WARNINGS", None);
78
- cfg.define("_LIBUNWIND_DISABLE_VISIBILITY_ANNOTATIONS", None);
79
- } else if target.contains("x86_64-fortanix-unknown-sgx") {
80
- cfg.cpp(false);
81
-
82
- cfg.static_flag(true);
83
- cfg.opt_level(3);
84
-
85
- cfg.flag("-nostdinc++");
86
- cfg.flag("-fno-exceptions");
87
- cfg.flag("-fno-rtti");
88
- cfg.flag("-fstrict-aliasing");
89
- cfg.flag("-funwind-tables");
90
- cfg.flag("-fvisibility=hidden");
91
- cfg.flag("-fno-stack-protector");
92
- cfg.flag("-ffreestanding");
93
- cfg.flag("-fexceptions");
94
-
95
- // easiest way to undefine since no API available in cc::Build to undefine
96
- cfg.flag("-U_FORTIFY_SOURCE");
97
- cfg.define("_FORTIFY_SOURCE", "0");
98
-
99
- cfg.flag_if_supported("-fvisibility-global-new-delete-hidden");
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
+ }
100
89
101
- cfg.define("_LIBUNWIND_DISABLE_VISIBILITY_ANNOTATIONS", None);
102
- cfg.define("RUST_SGX", "1");
103
- cfg.define("__NO_STRING_INLINES", None);
104
- cfg.define("__NO_MATH_INLINES", None);
105
- cfg.define("_LIBUNWIND_IS_BAREMETAL", None);
106
- cfg.define("__LIBUNWIND_IS_NATIVE_ONLY", None);
107
- cfg.define("NDEBUG", None);
108
- } else {
109
- cfg.flag("-std=c99");
110
- cfg.flag("-std=c++11");
111
- cfg.flag("-nostdinc++");
112
- cfg.flag("-fno-exceptions");
113
- cfg.flag("-fno-rtti");
90
+ for cfg in [&mut cc_cfg, &mut cpp_cfg].iter_mut() {
91
+ cfg.warnings(false);
114
92
cfg.flag("-fstrict-aliasing");
115
93
cfg.flag("-funwind-tables");
116
94
cfg.flag("-fvisibility=hidden");
117
- cfg.flag_if_supported("-fvisibility-global-new-delete-hidden");
118
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
+ }
119
116
}
120
117
121
- let mut unwind_sources = vec![
122
- "Unwind-EHABI.cpp",
123
- "Unwind-seh.cpp",
118
+ let mut c_sources = vec![
124
119
"Unwind-sjlj.c",
125
120
"UnwindLevel1-gcc-ext.c",
126
121
"UnwindLevel1.c",
127
122
"UnwindRegistersRestore.S",
128
123
"UnwindRegistersSave.S",
129
- "libunwind.cpp",
130
124
];
131
125
132
- if target_vendor == "apple" {
133
- unwind_sources.push("Unwind_AppleExtras.cpp");
134
- }
126
+ let cpp_sources = vec!["Unwind-EHABI.cpp", "Unwind-seh.cpp", "libunwind.cpp"];
127
+ let cpp_len = cpp_sources.len();
135
128
136
129
if target.contains("x86_64-fortanix-unknown-sgx") {
137
- unwind_sources .push("UnwindRustSgx.c");
130
+ c_sources .push("UnwindRustSgx.c");
138
131
}
139
132
140
- let root = Path::new("../../src/llvm-project/libunwind");
141
- cfg.include(root.join("include"));
142
- for src in unwind_sources {
143
- cfg.file(root.join("src").join(src));
133
+ for src in c_sources {
134
+ cc_cfg.file(root.join("src").join(src).canonicalize().unwrap());
144
135
}
145
136
146
- if target_env == "musl" {
147
- // use the same C compiler command to compile C++ code so we do not need to setup the
148
- // C++ compiler env variables on the builders
149
- cfg.cpp(false);
150
- // linking for musl is handled in lib.rs
151
- cfg.cargo_metadata(false);
152
- println!("cargo:rustc-link-search=native={}", env::var("OUT_DIR").unwrap());
137
+ for src in cpp_sources {
138
+ cpp_cfg.file(root.join("src").join(src).canonicalize().unwrap());
153
139
}
154
140
155
- cfg.compile("unwind");
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");
156
158
}
157
159
}
0 commit comments