@@ -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