@@ -4,7 +4,13 @@ fn main() {
44 println ! ( "cargo:rerun-if-changed=build.rs" ) ;
55 let target = env:: var ( "TARGET" ) . expect ( "TARGET was not set" ) ;
66
7- if target. contains ( "linux" ) {
7+ if cfg ! ( feature = "llvm-libunwind" ) &&
8+ ( target. contains ( "linux" ) ||
9+ target. contains ( "fuchsia" ) ) {
10+ // Build the unwinding from libunwind C/C++ source code.
11+ #[ cfg( feature = "llvm-libunwind" ) ]
12+ llvm_libunwind:: compile ( ) ;
13+ } else if target. contains ( "linux" ) {
814 if target. contains ( "musl" ) {
915 // musl is handled in lib.rs
1016 } else if !target. contains ( "android" ) {
@@ -37,3 +43,62 @@ fn main() {
3743 println ! ( "cargo:rustc-link-lib=unwind" ) ;
3844 }
3945}
46+
47+ #[ cfg( feature = "llvm-libunwind" ) ]
48+ mod llvm_libunwind {
49+ use std:: env;
50+ use std:: path:: Path ;
51+
52+ /// Compile the libunwind C/C++ source code.
53+ pub fn compile ( ) {
54+ let target_env = env:: var ( "CARGO_CFG_TARGET_ENV" ) . unwrap ( ) ;
55+ let target_vendor = env:: var ( "CARGO_CFG_TARGET_VENDOR" ) . unwrap ( ) ;
56+ let cfg = & mut cc:: Build :: new ( ) ;
57+
58+ cfg. cpp ( true ) ;
59+ cfg. cpp_set_stdlib ( None ) ;
60+ cfg. warnings ( false ) ;
61+
62+ if target_env == "msvc" {
63+ // Don't pull in extra libraries on MSVC
64+ cfg. flag ( "/Zl" ) ;
65+ cfg. flag ( "/EHsc" ) ;
66+ cfg. define ( "_CRT_SECURE_NO_WARNINGS" , None ) ;
67+ cfg. define ( "_LIBUNWIND_DISABLE_VISIBILITY_ANNOTATIONS" , None ) ;
68+ } else {
69+ cfg. flag ( "-std=c99" ) ;
70+ cfg. flag ( "-std=c++11" ) ;
71+ cfg. flag ( "-nostdinc++" ) ;
72+ if cfg. is_flag_supported ( "-funwind-tables" ) . unwrap_or_default ( ) &&
73+ cfg. is_flag_supported ( "-fno-exceptions" ) . unwrap_or_default ( ) {
74+ cfg. flag ( "-funwind-tables" ) ;
75+ cfg. flag ( "-fno-exceptions" ) ;
76+ }
77+ cfg. flag ( "-fno-rtti" ) ;
78+ cfg. flag ( "-fstrict-aliasing" ) ;
79+ }
80+
81+ let mut unwind_sources = vec ! [
82+ "Unwind-EHABI.cpp" ,
83+ "Unwind-seh.cpp" ,
84+ "Unwind-sjlj.c" ,
85+ "UnwindLevel1-gcc-ext.c" ,
86+ "UnwindLevel1.c" ,
87+ "UnwindRegistersRestore.S" ,
88+ "UnwindRegistersSave.S" ,
89+ "libunwind.cpp" ,
90+ ] ;
91+
92+ if target_vendor == "apple" {
93+ unwind_sources. push ( "Unwind_AppleExtras.cpp" ) ;
94+ }
95+
96+ let root = Path :: new ( "../llvm-project/libunwind" ) ;
97+ cfg. include ( root. join ( "include" ) ) ;
98+ for src in unwind_sources {
99+ cfg. file ( root. join ( "src" ) . join ( src) ) ;
100+ }
101+
102+ cfg. compile ( "unwind" ) ;
103+ }
104+ }
0 commit comments