@@ -376,13 +376,14 @@ fn link_rlib<'a>(
376376 }
377377
378378 for ( raw_dylib_name, raw_dylib_imports) in
379- collate_raw_dylibs ( sess, & codegen_results. crate_info . used_libraries ) ?
379+ collate_raw_dylibs ( sess, codegen_results. crate_info . used_libraries . iter ( ) ) ?
380380 {
381381 let output_path = archive_builder_builder. create_dll_import_lib (
382382 sess,
383383 & raw_dylib_name,
384384 & raw_dylib_imports,
385385 tmpdir. as_ref ( ) ,
386+ true ,
386387 ) ;
387388
388389 ab. add_archive ( & output_path, Box :: new ( |_| false ) ) . unwrap_or_else ( |e| {
@@ -434,9 +435,9 @@ fn link_rlib<'a>(
434435/// then the CodegenResults value contains one NativeLib instance for each block. However, the
435436/// linker appears to expect only a single import library for each library used, so we need to
436437/// collate the symbols together by library name before generating the import libraries.
437- fn collate_raw_dylibs (
438- sess : & Session ,
439- used_libraries : & [ NativeLib ] ,
438+ fn collate_raw_dylibs < ' a , ' b > (
439+ sess : & ' a Session ,
440+ used_libraries : impl IntoIterator < Item = & ' b NativeLib > ,
440441) -> Result < Vec < ( String , Vec < DllImport > ) > , ErrorGuaranteed > {
441442 // Use index maps to preserve original order of imports and libraries.
442443 let mut dylib_table = FxIndexMap :: < String , FxIndexMap < Symbol , & DllImport > > :: default ( ) ;
@@ -2028,13 +2029,43 @@ fn linker_with_args<'a>(
20282029
20292030 // Link with the import library generated for any raw-dylib functions.
20302031 for ( raw_dylib_name, raw_dylib_imports) in
2031- collate_raw_dylibs ( sess, & codegen_results. crate_info . used_libraries ) ?
2032+ collate_raw_dylibs ( sess, codegen_results. crate_info . used_libraries . iter ( ) ) ?
2033+ {
2034+ cmd. add_object ( & archive_builder_builder. create_dll_import_lib (
2035+ sess,
2036+ & raw_dylib_name,
2037+ & raw_dylib_imports,
2038+ tmpdir,
2039+ true ,
2040+ ) ) ;
2041+ }
2042+ // As with add_upstream_native_libraries, we need to add the upstream raw-dylib symbols in case
2043+ // they are used within inlined functions or instantiated generic functions. We do this *after*
2044+ // handling the raw-dylib symbols in the current crate to make sure that those are chosen first
2045+ // by the linker.
2046+ let ( _, dependency_linkage) = codegen_results
2047+ . crate_info
2048+ . dependency_formats
2049+ . iter ( )
2050+ . find ( |( ty, _) | * ty == crate_type)
2051+ . expect ( "failed to find crate type in dependency format list" ) ;
2052+ let native_libraries_from_nonstatics = codegen_results
2053+ . crate_info
2054+ . native_libraries
2055+ . iter ( )
2056+ . filter_map ( |( cnum, libraries) | {
2057+ ( dependency_linkage[ cnum. as_usize ( ) - 1 ] != Linkage :: Static ) . then ( || libraries)
2058+ } )
2059+ . flatten ( ) ;
2060+ for ( raw_dylib_name, raw_dylib_imports) in
2061+ collate_raw_dylibs ( sess, native_libraries_from_nonstatics) ?
20322062 {
20332063 cmd. add_object ( & archive_builder_builder. create_dll_import_lib (
20342064 sess,
20352065 & raw_dylib_name,
20362066 & raw_dylib_imports,
20372067 tmpdir,
2068+ false ,
20382069 ) ) ;
20392070 }
20402071
0 commit comments