@@ -52,6 +52,15 @@ use std::path::{Path, PathBuf};
5252use  std:: process:: { ExitStatus ,  Output ,  Stdio } ; 
5353use  std:: { env,  fmt,  fs,  io,  mem,  str} ; 
5454
55+ #[ derive( Default ) ]  
56+ pub  struct  SearchPaths ( OnceCell < Vec < PathBuf > > ) ; 
57+ 
58+ impl  SearchPaths  { 
59+     pub ( super )  fn  get ( & self ,  sess :  & Session )  -> & [ PathBuf ]  { 
60+         self . 0 . get_or_init ( || archive_search_paths ( sess) ) 
61+     } 
62+ } 
63+ 
5564pub  fn  ensure_removed ( dcx :  & DiagCtxt ,  path :  & Path )  { 
5665    if  let  Err ( e)  = fs:: remove_file ( path)  { 
5766        if  e. kind ( )  != io:: ErrorKind :: NotFound  { 
@@ -1265,15 +1274,15 @@ fn link_sanitizer_runtime(
12651274        let  path = find_sanitizer_runtime ( sess,  & filename) ; 
12661275        let  rpath = path. to_str ( ) . expect ( "non-utf8 component in path" ) ; 
12671276        linker. args ( & [ "-Wl,-rpath" ,  "-Xlinker" ,  rpath] ) ; 
1268-         linker. link_dylib ( & filename,  false ,  true ) ; 
1277+         linker. link_dylib_by_name ( & filename,  false ,  true ) ; 
12691278    }  else  if  sess. target . is_like_msvc  && flavor == LinkerFlavor :: Msvc ( Lld :: No )  && name == "asan"  { 
12701279        // MSVC provides the `/INFERASANLIBS` argument to automatically find the 
12711280        // compatible ASAN library. 
12721281        linker. arg ( "/INFERASANLIBS" ) ; 
12731282    }  else  { 
12741283        let  filename = format ! ( "librustc{channel}_rt.{name}.a" ) ; 
12751284        let  path = find_sanitizer_runtime ( sess,  & filename) . join ( & filename) ; 
1276-         linker. link_whole_rlib ( & path) ; 
1285+         linker. link_staticlib_by_path ( & path,   true ) ; 
12771286    } 
12781287} 
12791288
@@ -2445,7 +2454,7 @@ fn add_native_libs_from_crate(
24452454    archive_builder_builder :  & dyn  ArchiveBuilderBuilder , 
24462455    codegen_results :  & CodegenResults , 
24472456    tmpdir :  & Path , 
2448-     search_paths :  & OnceCell < Vec < PathBuf > > , 
2457+     search_paths :  & SearchPaths , 
24492458    bundled_libs :  & FxHashSet < Symbol > , 
24502459    cnum :  CrateNum , 
24512460    link_static :  bool , 
@@ -2505,46 +2514,34 @@ fn add_native_libs_from_crate(
25052514                        if  let  Some ( filename)  = lib. filename  { 
25062515                            // If rlib contains native libs as archives, they are unpacked to tmpdir. 
25072516                            let  path = tmpdir. join ( filename. as_str ( ) ) ; 
2508-                             if  whole_archive { 
2509-                                 cmd. link_whole_rlib ( & path) ; 
2510-                             }  else  { 
2511-                                 cmd. link_rlib ( & path) ; 
2512-                             } 
2517+                             cmd. link_staticlib_by_path ( & path,  whole_archive) ; 
25132518                        } 
25142519                    }  else  { 
2515-                         if  whole_archive { 
2516-                             cmd. link_whole_staticlib ( 
2517-                                 name, 
2518-                                 verbatim, 
2519-                                 search_paths. get_or_init ( || archive_search_paths ( sess) ) , 
2520-                             ) ; 
2521-                         }  else  { 
2522-                             cmd. link_staticlib ( name,  verbatim) 
2523-                         } 
2520+                         cmd. link_staticlib_by_name ( name,  verbatim,  whole_archive,  search_paths) ; 
25242521                    } 
25252522                } 
25262523            } 
25272524            NativeLibKind :: Dylib  {  as_needed }  => { 
25282525                if  link_dynamic { 
2529-                     cmd. link_dylib ( name,  verbatim,  as_needed. unwrap_or ( true ) ) 
2526+                     cmd. link_dylib_by_name ( name,  verbatim,  as_needed. unwrap_or ( true ) ) 
25302527                } 
25312528            } 
25322529            NativeLibKind :: Unspecified  => { 
25332530                // If we are generating a static binary, prefer static library when the 
25342531                // link kind is unspecified. 
25352532                if  !link_output_kind. can_link_dylib ( )  && !sess. target . crt_static_allows_dylibs  { 
25362533                    if  link_static { 
2537-                         cmd. link_staticlib ( name,  verbatim) 
2534+                         cmd. link_staticlib_by_name ( name,  verbatim,   false ,  search_paths ) ; 
25382535                    } 
25392536                }  else  { 
25402537                    if  link_dynamic { 
2541-                         cmd. link_dylib ( name,  verbatim,  true ) ; 
2538+                         cmd. link_dylib_by_name ( name,  verbatim,  true ) ; 
25422539                    } 
25432540                } 
25442541            } 
25452542            NativeLibKind :: Framework  {  as_needed }  => { 
25462543                if  link_dynamic { 
2547-                     cmd. link_framework ( name,  as_needed. unwrap_or ( true ) ) 
2544+                     cmd. link_framework_by_name ( name,  verbatim ,  as_needed. unwrap_or ( true ) ) 
25482545                } 
25492546            } 
25502547            NativeLibKind :: RawDylib  => { 
@@ -2581,7 +2578,7 @@ fn add_local_native_libraries(
25812578        } 
25822579    } 
25832580
2584-     let  search_paths = OnceCell :: new ( ) ; 
2581+     let  search_paths = SearchPaths :: default ( ) ; 
25852582    // All static and dynamic native library dependencies are linked to the local crate. 
25862583    let  link_static = true ; 
25872584    let  link_dynamic = true ; 
@@ -2623,7 +2620,7 @@ fn add_upstream_rust_crates<'a>(
26232620        . find ( |( ty,  _) | * ty == crate_type) 
26242621        . expect ( "failed to find crate type in dependency format list" ) ; 
26252622
2626-     let  search_paths = OnceCell :: new ( ) ; 
2623+     let  search_paths = SearchPaths :: default ( ) ; 
26272624    for  & cnum in  & codegen_results. crate_info . used_crates  { 
26282625        // We may not pass all crates through to the linker. Some crates may appear statically in 
26292626        // an existing dylib, meaning we'll pick up all the symbols from the dylib. 
@@ -2698,7 +2695,7 @@ fn add_upstream_native_libraries(
26982695    tmpdir :  & Path , 
26992696    link_output_kind :  LinkOutputKind , 
27002697)  { 
2701-     let  search_path  = OnceCell :: new ( ) ; 
2698+     let  search_paths  = SearchPaths :: default ( ) ; 
27022699    for  & cnum in  & codegen_results. crate_info . used_crates  { 
27032700        // Static libraries are not linked here, they are linked in `add_upstream_rust_crates`. 
27042701        // FIXME: Merge this function to `add_upstream_rust_crates` so that all native libraries 
@@ -2720,7 +2717,7 @@ fn add_upstream_native_libraries(
27202717            archive_builder_builder, 
27212718            codegen_results, 
27222719            tmpdir, 
2723-             & search_path , 
2720+             & search_paths , 
27242721            & Default :: default ( ) , 
27252722            cnum, 
27262723            link_static, 
@@ -2791,7 +2788,7 @@ fn add_static_crate<'a>(
27912788        }  else  { 
27922789            fix_windows_verbatim_for_gcc ( path) 
27932790        } ; 
2794-         cmd. link_rlib ( & rlib_path) ; 
2791+         cmd. link_staticlib_by_path ( & rlib_path,   false ) ; 
27952792    } ; 
27962793
27972794    if  !are_upstream_rust_objects_already_included ( sess) 
@@ -2859,13 +2856,24 @@ fn add_dynamic_crate(cmd: &mut dyn Linker, sess: &Session, cratepath: &Path) {
28592856    // Just need to tell the linker about where the library lives and 
28602857    // what its name is 
28612858    let  parent = cratepath. parent ( ) ; 
2859+     // When producing a dll, the MSVC linker may not actually emit a 
2860+     // `foo.lib` file if the dll doesn't actually export any symbols, so we 
2861+     // check to see if the file is there and just omit linking to it if it's 
2862+     // not present. 
2863+     if  sess. target . is_like_msvc  && !cratepath. with_extension ( "dll.lib" ) . exists ( )  { 
2864+         return ; 
2865+     } 
28622866    if  let  Some ( dir)  = parent { 
28632867        cmd. include_path ( & rehome_sysroot_lib_dir ( sess,  dir) ) ; 
28642868    } 
2865-     let  stem = cratepath. file_stem ( ) . unwrap ( ) . to_str ( ) . unwrap ( ) ; 
2869+     // "<dir>/name.dll -> name.dll" on windows-msvc 
2870+     // "<dir>/name.dll -> name" on windows-gnu 
2871+     // "<dir>/libname.<ext> -> name" elsewhere 
2872+     let  stem = if  sess. target . is_like_msvc  {  cratepath. file_name ( )  }  else  {  cratepath. file_stem ( )  } ; 
2873+     let  stem = stem. unwrap ( ) . to_str ( ) . unwrap ( ) ; 
28662874    // Convert library file-stem into a cc -l argument. 
28672875    let  prefix = if  stem. starts_with ( "lib" )  && !sess. target . is_like_windows  {  3  }  else  {  0  } ; 
2868-     cmd. link_rust_dylib ( & stem[ prefix..] ,  parent . unwrap_or_else ( ||  Path :: new ( "" ) ) ) ; 
2876+     cmd. link_dylib_by_name ( & stem[ prefix..] ,  false ,   true ) ; 
28692877} 
28702878
28712879fn  relevant_lib ( sess :  & Session ,  lib :  & NativeLib )  -> bool  { 
0 commit comments