@@ -7,6 +7,49 @@ struct TreeSitterParser {
7
7
extra_files : Vec < & ' static str > ,
8
8
}
9
9
10
+ /// Emit linking flags for this library, but specifcy `+whole-archive`.
11
+ ///
12
+ /// This should be possible in the cc crate directly after
13
+ /// https://github.com/rust-lang/cc-rs/pull/671
14
+ fn emit_whole_archive_link_flags ( lib_name : & str , is_cpp : bool ) {
15
+ println ! ( "cargo:rustc-link-lib=static:+whole-archive={}" , lib_name) ;
16
+ println ! (
17
+ "cargo:rustc-link-search=native={}" ,
18
+ std:: env:: var( "OUT_DIR" ) . expect( "did not set OUT_DIR" )
19
+ ) ;
20
+
21
+ if is_cpp {
22
+ let cpp_stdlib = if let Ok ( stdlib) = std:: env:: var ( "CXXSTDLIB" ) {
23
+ if stdlib. is_empty ( ) {
24
+ None
25
+ } else {
26
+ Some ( stdlib)
27
+ }
28
+ } else {
29
+ let target = std:: env:: var ( "TARGET" ) . expect ( "TARGET environment should be set" ) ;
30
+
31
+ // Equivalent to https://github.com/rust-lang/cc-rs/blob/53fb72c87e5769a299f1886ead831901b9c775d6/src/lib.rs#L2528
32
+ if target. contains ( "msvc" ) {
33
+ None
34
+ } else if target. contains ( "apple" ) {
35
+ Some ( "c++" . to_string ( ) )
36
+ } else if target. contains ( "freebsd" ) {
37
+ Some ( "c++" . to_string ( ) )
38
+ } else if target. contains ( "openbsd" ) {
39
+ Some ( "c++" . to_string ( ) )
40
+ } else if target. contains ( "android" ) {
41
+ Some ( "c++_shared" . to_string ( ) )
42
+ } else {
43
+ Some ( "stdc++" . to_string ( ) )
44
+ }
45
+ } ;
46
+
47
+ if let Some ( cpp_stdlib) = cpp_stdlib {
48
+ println ! ( "cargo:rustc-link-lib={}" , cpp_stdlib) ;
49
+ }
50
+ }
51
+ }
52
+
10
53
impl TreeSitterParser {
11
54
fn build ( & self ) {
12
55
let dir = PathBuf :: from ( & self . src_dir ) ;
@@ -49,6 +92,10 @@ impl TreeSitterParser {
49
92
for file in cpp_files {
50
93
cpp_build. file ( dir. join ( file) ) ;
51
94
}
95
+
96
+ cpp_build. cargo_metadata ( false ) ;
97
+ emit_whole_archive_link_flags ( & format ! ( "{}-cpp" , self . name) , true ) ;
98
+
52
99
cpp_build. compile ( & format ! ( "{}-cpp" , self . name) ) ;
53
100
}
54
101
@@ -60,6 +107,10 @@ impl TreeSitterParser {
60
107
for file in c_files {
61
108
build. file ( dir. join ( file) ) ;
62
109
}
110
+
111
+ build. cargo_metadata ( false ) ;
112
+ emit_whole_archive_link_flags ( self . name , false ) ;
113
+
63
114
build. compile ( self . name ) ;
64
115
}
65
116
}
0 commit comments