Skip to content

Commit 7e07271

Browse files
committed
Avoid absolute sysroot paths in the MSVC linker command line
When the `--sysroot` is specified as relative to the current working directory, the sysroot's rlibs should also be specified as relative paths. Otherwise, the current working directory ends up in the absolute paths, and in the linker command line. And the entire linker command line appears in the PDB file generated by the MSVC linker. When adding an rlib to the linker command line, if the rlib's canonical path is in the sysroot's canonical path, then use the current sysroot path + filename instead of the full absolute path to the rlib. This means that when `--sysroot=foo` is specified, the linker command line will contain `foo/rustlib/target/lib/lib*.rlib` instead of the full absolute path to the same. This addresses #112586
1 parent 5683791 commit 7e07271

File tree

1 file changed

+27
-2
lines changed
  • compiler/rustc_codegen_ssa/src/back

1 file changed

+27
-2
lines changed

compiler/rustc_codegen_ssa/src/back/link.rs

+27-2
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,31 @@ fn add_upstream_native_libraries(
26822682
}
26832683
}
26842684

2685+
// Rehome sysroot lib paths to be relative to the sysroot, which may be a relative
2686+
// path specified by the user. If the sysroot is a relative path, and the sysroot rlibs
2687+
// are specified as an absolute path, the linker command line can be non-deterministic
2688+
// due to the paths including the current working directory. The linker command line
2689+
// needs to be deterministic since it appears inside the PDB file generated by the MSVC
2690+
// linker. See https://github.com/rust-lang/rust/issues/112586.
2691+
//
2692+
// Note that the `susroot_lib_path` returned by `target_filesearch().get_lib_path()` has
2693+
// already had `fix_windows_verbatim_for_gcc()` applied if needed.
2694+
fn rehome_sysroot_rlib_path<'a>(sess: &'a Session, rlib_path: PathBuf) -> 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 mut canonical_rlib_dir = try_canonicalize(&rlib_path).unwrap_or_else(|_| rlib_path.clone());
2700+
canonical_rlib_dir.pop();
2701+
2702+
if canonical_rlib_dir == canonical_sysroot_lib_path {
2703+
sysroot_lib_path
2704+
.join(rlib_path.file_name().expect("rlib path has no file name path component"))
2705+
} else {
2706+
rlib_path
2707+
}
2708+
}
2709+
26852710
// Adds the static "rlib" versions of all crates to the command line.
26862711
// There's a bit of magic which happens here specifically related to LTO,
26872712
// namely that we remove upstream object files.
@@ -2713,7 +2738,7 @@ fn add_static_crate<'a>(
27132738
let cratepath = &src.rlib.as_ref().unwrap().0;
27142739

27152740
let mut link_upstream = |path: &Path| {
2716-
cmd.link_rlib(&fix_windows_verbatim_for_gcc(path));
2741+
cmd.link_rlib(&rehome_sysroot_rlib_path(sess, fix_windows_verbatim_for_gcc(path)));
27172742
};
27182743

27192744
if !are_upstream_rust_objects_already_included(sess)

0 commit comments

Comments
 (0)