@@ -2,9 +2,17 @@ extern crate gcc;
2
2
3
3
use std:: env;
4
4
use std:: ffi:: OsString ;
5
+ use std:: fs;
5
6
use std:: path:: PathBuf ;
6
7
use std:: process:: Command ;
7
8
9
+ macro_rules! t {
10
+ ( $e: expr) => ( match $e {
11
+ Ok ( e) => e,
12
+ Err ( e) => panic!( "{} failed with {}" , stringify!( $e) , e) ,
13
+ } )
14
+ }
15
+
8
16
fn main ( ) {
9
17
let src = env:: current_dir ( ) . unwrap ( ) ;
10
18
let dst = PathBuf :: from ( env:: var_os ( "OUT_DIR" ) . unwrap ( ) ) ;
@@ -21,11 +29,6 @@ fn main() {
21
29
return
22
30
}
23
31
24
- // libbacktrace is already included in the linux libstd for rust
25
- if target. contains ( "linux" ) {
26
- return
27
- }
28
-
29
32
// no way this will ever compile for emscripten
30
33
if target. contains ( "emscripten" ) {
31
34
return
@@ -56,6 +59,29 @@ fn main() {
56
59
src. join( "src/libbacktrace" ) . display( ) ) ) ) ;
57
60
println ! ( "cargo:rustc-link-search=native={}/.libs" , dst. display( ) ) ;
58
61
println ! ( "cargo:rustc-link-lib=static=backtrace" ) ;
62
+
63
+ // The standard library currently bundles in libbacktrace, but it's
64
+ // compiled with hidden visibility (naturally) so we can't use it.
65
+ //
66
+ // To prevent conflicts with a second statically linked copy we rename all
67
+ // symbols with a '__rbt_' prefix manually here through `objcopy`.
68
+ let lib = dst. join ( ".libs/libbacktrace.a" ) ;
69
+ let tmpdir = dst. join ( "__tmp" ) ;
70
+ drop ( fs:: remove_dir_all ( & tmpdir) ) ;
71
+ t ! ( fs:: create_dir_all( & tmpdir) ) ;
72
+ run ( Command :: new ( "ar" ) . arg ( "x" ) . arg ( & lib) . current_dir ( & tmpdir) ) ;
73
+
74
+ t ! ( fs:: remove_file( & lib) ) ;
75
+ let mut objs = Vec :: new ( ) ;
76
+ for obj in t ! ( tmpdir. read_dir( ) ) {
77
+ let obj = t ! ( obj) ;
78
+ run ( Command :: new ( "objcopy" )
79
+ . arg ( "--redefine-syms=symbol-map" )
80
+ . arg ( obj. path ( ) ) ) ;
81
+ objs. push ( obj. path ( ) ) ;
82
+ }
83
+
84
+ run ( Command :: new ( "ar" ) . arg ( "crus" ) . arg ( & lib) . args ( & objs) ) ;
59
85
}
60
86
61
87
fn run ( cmd : & mut Command ) {
0 commit comments