@@ -12,7 +12,12 @@ fn main() {
12
12
println ! ( "cargo:rerun-if-changed=dotnet/src" ) ;
13
13
println ! ( "cargo:rerun-if-changed=dotnet/LiteDB/LiteDB" ) ;
14
14
15
- // currently this code is only tested on macOS.
15
+ // Note for users of this library:
16
+ // The NativeAOT does not support start-stop-gc so you have to disable it.
17
+ if std:: env:: var ( "TARGET" ) . unwrap ( ) . contains ( "linux" ) {
18
+ // start stop gc is not supported by dotnet.
19
+ println ! ( "cargo:rustc-link-arg=-Wl,-z,nostart-stop-gc" ) ;
20
+ }
16
21
17
22
let out_dir = PathBuf :: from ( std:: env:: var_os ( "OUT_DIR" ) . unwrap ( ) ) ;
18
23
let target_info = TargetInformation :: from_triple ( std:: env:: var ( "TARGET" ) . unwrap ( ) . as_str ( ) ) ;
@@ -44,6 +49,18 @@ fn main() {
44
49
path = dotnet_built. parent( ) . unwrap( ) . display( )
45
50
) ;
46
51
52
+ // link bootstrapper
53
+ let bootstrapper = dotnet_sdk_folder. join ( target_info. bootstrapper ) ;
54
+ if target_info. family == TargetFamily :: Linux || target_info. family == TargetFamily :: MacOS {
55
+ // for unix-like platforms, generate a static library from bootstrapperdll and link it
56
+ create_libbootstrapperdll_a ( & bootstrapper, & patched_lib_folder, & target_info) ;
57
+ println ! ( "cargo:rustc-link-lib=static:+whole-archive=bootstrapperdll" ) ;
58
+ } else {
59
+ // for windows, generate a .lib file from bootstrapperdll.obj and link it
60
+ create_libbootstrapperdll_lib ( & bootstrapper, & patched_lib_folder, & target_info) ;
61
+ println ! ( "cargo:rustc-link-lib=static:+whole-archive=bootstrapperdll" ) ;
62
+ }
63
+
47
64
// link prebuilt dotnet
48
65
if target_info. family == TargetFamily :: MacOS {
49
66
// for apple platform, we need to fix object file a little
@@ -68,15 +85,6 @@ fn main() {
68
85
remove_libunwind ( & before, & patched) ;
69
86
}
70
87
71
- if target_info. family == TargetFamily :: Linux {
72
- // start stop gc is not supported by dotnet.
73
- println ! ( "cargo:rustc-link-arg=-Wl,-z,nostart-stop-gc" ) ;
74
- } else if target_info. family == TargetFamily :: Windows {
75
- // "/merge:.modules=.rdata" "/merge:.unbox=.text"
76
- println ! ( "cargo:rustc-link-arg=/merge:.modules=.rdata" ) ;
77
- println ! ( "cargo:rustc-link-arg=/merge:.unbox=.text" ) ;
78
- }
79
-
80
88
let common_libs: & [ & str ] = & [
81
89
//"static=Runtime.ServerGC",
82
90
"static=Runtime.WorkstationGC" ,
@@ -241,3 +249,40 @@ fn remove_libunwind(archive: &Path, patched: &Path) {
241
249
. flush ( )
242
250
. expect ( "writing patched library" ) ;
243
251
}
252
+
253
+ fn create_libbootstrapperdll_a ( obj : & Path , folder : & Path , target_info : & TargetInformation ) {
254
+ let lib_path = folder. join ( "libbootstrapperdll.a" ) ;
255
+ let file = std:: fs:: File :: create ( & lib_path) . expect ( "failed to create libbootstrapperdll.a" ) ;
256
+ let mut builder = ar:: Builder :: new ( std:: io:: BufWriter :: new ( file) ) ;
257
+ builder
258
+ . append_file (
259
+ b"bootstrapperdll.o" ,
260
+ & mut std:: fs:: File :: open ( obj) . expect ( "opening bootstrapperdll.o" ) ,
261
+ )
262
+ . unwrap ( ) ;
263
+
264
+ builder
265
+ . into_inner ( )
266
+ . unwrap ( )
267
+ . flush ( )
268
+ . expect ( "writing patched libbootstrapperdll.a" ) ;
269
+
270
+ if target_info. family == TargetFamily :: MacOS {
271
+ // for bsd, ranlib to index
272
+ Command :: new ( "ranlib" )
273
+ . arg ( lib_path)
274
+ . status ( )
275
+ . expect ( "running ranlib" ) ;
276
+ }
277
+ }
278
+
279
+ fn create_libbootstrapperdll_lib ( obj : & Path , folder : & Path , _target_info : & TargetInformation ) {
280
+ let lib_path = folder. join ( "bootstrapperdll.lib" ) ;
281
+
282
+ cc:: windows_registry:: find ( std:: env:: var ( "TARGET" ) . unwrap ( ) . as_str ( ) , "lib.exe" )
283
+ . expect ( "finding lib.exe" )
284
+ . arg ( format ! ( "/out:{}" , lib_path. to_str( ) . unwrap( ) ) )
285
+ . arg ( obj)
286
+ . status ( )
287
+ . expect ( "running lib /out:bootstrapperdll.lib bootstrapperdll.obj" ) ;
288
+ }
0 commit comments