@@ -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
@@ -1291,8 +1317,12 @@ enum RlibFlavor {
12911317 StaticlibBase ,
12921318}
12931319
1294- fn print_native_static_libs ( sess : & Session , all_native_libs : & [ NativeLib ] ) {
1295- let lib_args: Vec < _ > = all_native_libs
1320+ fn print_native_static_libs (
1321+ sess : & Session ,
1322+ all_native_libs : & [ NativeLib ] ,
1323+ all_rust_dylibs : & [ & Path ] ,
1324+ ) {
1325+ let mut lib_args: Vec < _ > = all_native_libs
12961326 . iter ( )
12971327 . filter ( |l| relevant_lib ( sess, l) )
12981328 . filter_map ( |lib| {
@@ -1322,6 +1352,41 @@ fn print_native_static_libs(sess: &Session, all_native_libs: &[NativeLib]) {
13221352 }
13231353 } )
13241354 . collect ( ) ;
1355+ for path in all_rust_dylibs {
1356+ // FIXME deduplicate with add_dynamic_crate
1357+
1358+ // Just need to tell the linker about where the library lives and
1359+ // what its name is
1360+ let parent = path. parent ( ) ;
1361+ if let Some ( dir) = parent {
1362+ let dir = fix_windows_verbatim_for_gcc ( dir) ;
1363+ if sess. target . is_like_msvc {
1364+ let mut arg = String :: from ( "/LIBPATH:" ) ;
1365+ arg. push_str ( & dir. display ( ) . to_string ( ) ) ;
1366+ lib_args. push ( arg) ;
1367+ } else {
1368+ lib_args. push ( "-L" . to_owned ( ) ) ;
1369+ lib_args. push ( dir. display ( ) . to_string ( ) ) ;
1370+ }
1371+ }
1372+ let stem = path. file_stem ( ) . unwrap ( ) . to_str ( ) . unwrap ( ) ;
1373+ // Convert library file-stem into a cc -l argument.
1374+ let prefix = if stem. starts_with ( "lib" ) && !sess. target . is_like_windows { 3 } else { 0 } ;
1375+ let lib = & stem[ prefix..] ;
1376+ let path = parent. unwrap_or_else ( || Path :: new ( "" ) ) ;
1377+ if sess. target . is_like_msvc {
1378+ // When producing a dll, the MSVC linker may not actually emit a
1379+ // `foo.lib` file if the dll doesn't actually export any symbols, so we
1380+ // check to see if the file is there and just omit linking to it if it's
1381+ // not present.
1382+ let name = format ! ( "{}.dll.lib" , lib) ;
1383+ if path. join ( & name) . exists ( ) {
1384+ lib_args. push ( name) ;
1385+ }
1386+ } else {
1387+ lib_args. push ( format ! ( "-l{}" , lib) ) ;
1388+ }
1389+ }
13251390 if !lib_args. is_empty ( ) {
13261391 sess. emit_note ( errors:: StaticLibraryNativeArtifacts ) ;
13271392 // Prefix for greppability
0 commit comments