@@ -4,7 +4,8 @@ fn main() {
44 println ! ( "cargo:rerun-if-changed=build.rs" ) ;
55 let target = env:: var ( "TARGET" ) . expect ( "TARGET was not set" ) ;
66
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
89 return ;
910 }
1011
@@ -57,101 +58,102 @@ mod llvm_libunwind {
5758 pub fn compile ( ) {
5859 let target = env:: var ( "TARGET" ) . expect ( "TARGET was not set" ) ;
5960 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" ) ;
6764
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" ) ;
7179 }
7280
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+ }
10089
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 ) ;
11492 cfg. flag ( "-fstrict-aliasing" ) ;
11593 cfg. flag ( "-funwind-tables" ) ;
11694 cfg. flag ( "-fvisibility=hidden" ) ;
117- cfg. flag_if_supported ( "-fvisibility-global-new-delete-hidden" ) ;
11895 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+ }
119116 }
120117
121- let mut unwind_sources = vec ! [
122- "Unwind-EHABI.cpp" ,
123- "Unwind-seh.cpp" ,
118+ let mut c_sources = vec ! [
124119 "Unwind-sjlj.c" ,
125120 "UnwindLevel1-gcc-ext.c" ,
126121 "UnwindLevel1.c" ,
127122 "UnwindRegistersRestore.S" ,
128123 "UnwindRegistersSave.S" ,
129- "libunwind.cpp" ,
130124 ] ;
131125
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 ( ) ;
135128
136129 if target. contains ( "x86_64-fortanix-unknown-sgx" ) {
137- unwind_sources . push ( "UnwindRustSgx.c" ) ;
130+ c_sources . push ( "UnwindRustSgx.c" ) ;
138131 }
139132
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 ( ) ) ;
144135 }
145136
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 ( ) ) ;
153139 }
154140
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" ) ;
156158 }
157159}
0 commit comments