@@ -5,7 +5,7 @@ use rustc_data_structures::fx::FxIndexMap;
5
5
use rustc_data_structures:: memmap:: Mmap ;
6
6
use rustc_data_structures:: temp_dir:: MaybeTempDir ;
7
7
use rustc_errors:: { ErrorGuaranteed , Handler } ;
8
- use rustc_fs_util:: fix_windows_verbatim_for_gcc;
8
+ use rustc_fs_util:: { fix_windows_verbatim_for_gcc, try_canonicalize } ;
9
9
use rustc_hir:: def_id:: { CrateNum , LOCAL_CRATE } ;
10
10
use rustc_metadata:: find_native_static_library;
11
11
use rustc_metadata:: fs:: { copy_to_stdout, emit_wrapper_file, METADATA_FILENAME } ;
@@ -2682,6 +2682,30 @@ fn add_upstream_native_libraries(
2682
2682
}
2683
2683
}
2684
2684
2685
+ // Rehome lib paths (which exclude the library file name) that point into the sysroot lib directory
2686
+ // to be relative to the sysroot directory, which may be a relative path specified by the user.
2687
+ //
2688
+ // If the sysroot is a relative path, and the sysroot libs are specified as an absolute path, the
2689
+ // linker command line can be non-deterministic due to the paths including the current working
2690
+ // directory. The linker command line needs to be deterministic since it appears inside the PDB
2691
+ // file generated by the MSVC linker. See https://github.com/rust-lang/rust/issues/112586.
2692
+ //
2693
+ // The returned path will always have `fix_windows_verbatim_for_gcc()` applied to it.
2694
+ fn rehome_sysroot_lib_dir < ' a > ( sess : & ' a Session , lib_dir : & Path ) -> PathBuf {
2695
+ let sysroot_lib_path = sess. target_filesearch ( PathKind :: All ) . get_lib_path ( ) ;
2696
+ let canonical_sysroot_lib_path =
2697
+ { try_canonicalize ( & sysroot_lib_path) . unwrap_or_else ( |_| sysroot_lib_path. clone ( ) ) } ;
2698
+
2699
+ let canonical_lib_dir = try_canonicalize ( lib_dir) . unwrap_or_else ( |_| lib_dir. to_path_buf ( ) ) ;
2700
+ if canonical_lib_dir == canonical_sysroot_lib_path {
2701
+ // This path, returned by `target_filesearch().get_lib_path()`, has
2702
+ // already had `fix_windows_verbatim_for_gcc()` applied if needed.
2703
+ sysroot_lib_path
2704
+ } else {
2705
+ fix_windows_verbatim_for_gcc ( & lib_dir)
2706
+ }
2707
+ }
2708
+
2685
2709
// Adds the static "rlib" versions of all crates to the command line.
2686
2710
// There's a bit of magic which happens here specifically related to LTO,
2687
2711
// namely that we remove upstream object files.
@@ -2713,7 +2737,13 @@ fn add_static_crate<'a>(
2713
2737
let cratepath = & src. rlib . as_ref ( ) . unwrap ( ) . 0 ;
2714
2738
2715
2739
let mut link_upstream = |path : & Path | {
2716
- cmd. link_rlib ( & fix_windows_verbatim_for_gcc ( path) ) ;
2740
+ let rlib_path = if let Some ( dir) = path. parent ( ) {
2741
+ let file_name = path. file_name ( ) . expect ( "rlib path has no file name path component" ) ;
2742
+ rehome_sysroot_lib_dir ( sess, & dir) . join ( file_name)
2743
+ } else {
2744
+ fix_windows_verbatim_for_gcc ( path)
2745
+ } ;
2746
+ cmd. link_rlib ( & rlib_path) ;
2717
2747
} ;
2718
2748
2719
2749
if !are_upstream_rust_objects_already_included ( sess)
@@ -2782,7 +2812,7 @@ fn add_dynamic_crate(cmd: &mut dyn Linker, sess: &Session, cratepath: &Path) {
2782
2812
// what its name is
2783
2813
let parent = cratepath. parent ( ) ;
2784
2814
if let Some ( dir) = parent {
2785
- cmd. include_path ( & fix_windows_verbatim_for_gcc ( dir) ) ;
2815
+ cmd. include_path ( & rehome_sysroot_lib_dir ( sess , dir) ) ;
2786
2816
}
2787
2817
let stem = cratepath. file_stem ( ) . unwrap ( ) . to_str ( ) . unwrap ( ) ;
2788
2818
// Convert library file-stem into a cc -l argument.
0 commit comments