@@ -544,12 +544,38 @@ fn link_staticlib<'a>(
544
544
545
545
ab. build ( out_filename) ;
546
546
547
- if !all_native_libs. is_empty ( ) {
548
- if sess. opts . prints . contains ( & PrintRequest :: NativeStaticLibs ) {
549
- print_native_static_libs ( sess, & all_native_libs) ;
547
+ let crates = codegen_results. crate_info . used_crates . iter ( ) ;
548
+
549
+ let fmts = codegen_results
550
+ . crate_info
551
+ . dependency_formats
552
+ . iter ( )
553
+ . find_map ( |& ( ty, ref list) | if ty == CrateType :: Staticlib { Some ( list) } else { None } )
554
+ . expect ( "no dependency formats for staticlib" ) ;
555
+
556
+ let mut all_rust_dylibs = vec ! [ ] ;
557
+ for & cnum in crates {
558
+ match fmts. get ( cnum. as_usize ( ) - 1 ) {
559
+ Some ( & Linkage :: Dynamic ) => { }
560
+ _ => continue ,
561
+ }
562
+ let crate_name = codegen_results. crate_info . crate_name [ & cnum] ;
563
+ let used_crate_source = & codegen_results. crate_info . used_crate_source [ & cnum] ;
564
+ if let Some ( ( path, _) ) = & used_crate_source. dylib {
565
+ all_rust_dylibs. push ( & * * path) ;
566
+ } else {
567
+ if used_crate_source. rmeta . is_some ( ) {
568
+ sess. emit_fatal ( errors:: LinkRlibError :: OnlyRmetaFound { crate_name } ) ;
569
+ } else {
570
+ sess. emit_fatal ( errors:: LinkRlibError :: NotFound { crate_name } ) ;
571
+ }
550
572
}
551
573
}
552
574
575
+ if sess. opts . prints . contains ( & PrintRequest :: NativeStaticLibs ) {
576
+ print_native_static_libs ( sess, & all_native_libs, & all_rust_dylibs) ;
577
+ }
578
+
553
579
Ok ( ( ) )
554
580
}
555
581
@@ -1289,8 +1315,12 @@ enum RlibFlavor {
1289
1315
StaticlibBase ,
1290
1316
}
1291
1317
1292
- fn print_native_static_libs ( sess : & Session , all_native_libs : & [ NativeLib ] ) {
1293
- let lib_args: Vec < _ > = all_native_libs
1318
+ fn print_native_static_libs (
1319
+ sess : & Session ,
1320
+ all_native_libs : & [ NativeLib ] ,
1321
+ all_rust_dylibs : & [ & Path ] ,
1322
+ ) {
1323
+ let mut lib_args: Vec < _ > = all_native_libs
1294
1324
. iter ( )
1295
1325
. filter ( |l| relevant_lib ( sess, l) )
1296
1326
. filter_map ( |lib| {
@@ -1319,6 +1349,41 @@ fn print_native_static_libs(sess: &Session, all_native_libs: &[NativeLib]) {
1319
1349
}
1320
1350
} )
1321
1351
. collect ( ) ;
1352
+ for path in all_rust_dylibs {
1353
+ // FIXME deduplicate with add_dynamic_crate
1354
+
1355
+ // Just need to tell the linker about where the library lives and
1356
+ // what its name is
1357
+ let parent = path. parent ( ) ;
1358
+ if let Some ( dir) = parent {
1359
+ let dir = fix_windows_verbatim_for_gcc ( dir) ;
1360
+ if sess. target . is_like_msvc {
1361
+ let mut arg = String :: from ( "/LIBPATH:" ) ;
1362
+ arg. push_str ( & dir. display ( ) . to_string ( ) ) ;
1363
+ lib_args. push ( arg) ;
1364
+ } else {
1365
+ lib_args. push ( "-L" . to_owned ( ) ) ;
1366
+ lib_args. push ( dir. display ( ) . to_string ( ) ) ;
1367
+ }
1368
+ }
1369
+ let stem = path. file_stem ( ) . unwrap ( ) . to_str ( ) . unwrap ( ) ;
1370
+ // Convert library file-stem into a cc -l argument.
1371
+ let prefix = if stem. starts_with ( "lib" ) && !sess. target . is_like_windows { 3 } else { 0 } ;
1372
+ let lib = & stem[ prefix..] ;
1373
+ let path = parent. unwrap_or_else ( || Path :: new ( "" ) ) ;
1374
+ if sess. target . is_like_msvc {
1375
+ // When producing a dll, the MSVC linker may not actually emit a
1376
+ // `foo.lib` file if the dll doesn't actually export any symbols, so we
1377
+ // check to see if the file is there and just omit linking to it if it's
1378
+ // not present.
1379
+ let name = format ! ( "{}.dll.lib" , lib) ;
1380
+ if path. join ( & name) . exists ( ) {
1381
+ lib_args. push ( name) ;
1382
+ }
1383
+ } else {
1384
+ lib_args. push ( format ! ( "-l{}" , lib) ) ;
1385
+ }
1386
+ }
1322
1387
if !lib_args. is_empty ( ) {
1323
1388
sess. emit_note ( errors:: StaticLibraryNativeArtifacts ) ;
1324
1389
// Prefix for greppability
0 commit comments