@@ -544,12 +544,38 @@ fn link_staticlib<'a>(
544544
545545 ab. build ( out_filename) ;
546546
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+ }
550572 }
551573 }
552574
575+ if sess. opts . prints . contains ( & PrintRequest :: NativeStaticLibs ) {
576+ print_native_static_libs ( sess, & all_native_libs, & all_rust_dylibs) ;
577+ }
578+
553579 Ok ( ( ) )
554580}
555581
@@ -1289,8 +1315,12 @@ enum RlibFlavor {
12891315 StaticlibBase ,
12901316}
12911317
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
12941324 . iter ( )
12951325 . filter ( |l| relevant_lib ( sess, l) )
12961326 . filter_map ( |lib| {
@@ -1319,6 +1349,41 @@ fn print_native_static_libs(sess: &Session, all_native_libs: &[NativeLib]) {
13191349 }
13201350 } )
13211351 . 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+ }
13221387 if !lib_args. is_empty ( ) {
13231388 sess. emit_note ( errors:: StaticLibraryNativeArtifacts ) ;
13241389 // Prefix for greppability
0 commit comments