Skip to content

Commit 99b3346

Browse files
committed
Auto merge of #112597 - danakj:map-linker-paths, r=michaelwoerister
Use the relative sysroot path in the linker command line to specify sysroot rlibs This addresses #112586
2 parents 0966f32 + c340325 commit 99b3346

File tree

1 file changed

+33
-3
lines changed
  • compiler/rustc_codegen_ssa/src/back

1 file changed

+33
-3
lines changed

compiler/rustc_codegen_ssa/src/back/link.rs

+33-3
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use rustc_data_structures::fx::FxIndexMap;
55
use rustc_data_structures::memmap::Mmap;
66
use rustc_data_structures::temp_dir::MaybeTempDir;
77
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};
99
use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
1010
use rustc_metadata::find_native_static_library;
1111
use rustc_metadata::fs::{copy_to_stdout, emit_wrapper_file, METADATA_FILENAME};
@@ -2682,6 +2682,30 @@ fn add_upstream_native_libraries(
26822682
}
26832683
}
26842684

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+
26852709
// Adds the static "rlib" versions of all crates to the command line.
26862710
// There's a bit of magic which happens here specifically related to LTO,
26872711
// namely that we remove upstream object files.
@@ -2713,7 +2737,13 @@ fn add_static_crate<'a>(
27132737
let cratepath = &src.rlib.as_ref().unwrap().0;
27142738

27152739
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);
27172747
};
27182748

27192749
if !are_upstream_rust_objects_already_included(sess)
@@ -2782,7 +2812,7 @@ fn add_dynamic_crate(cmd: &mut dyn Linker, sess: &Session, cratepath: &Path) {
27822812
// what its name is
27832813
let parent = cratepath.parent();
27842814
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));
27862816
}
27872817
let stem = cratepath.file_stem().unwrap().to_str().unwrap();
27882818
// Convert library file-stem into a cc -l argument.

0 commit comments

Comments
 (0)