Skip to content

Commit 746de61

Browse files
authored
Unrolled build for rust-lang#125263
Rollup merge of rust-lang#125263 - lqd:lld-fallback, r=petrochenkov rust-lld: fallback to rustc's sysroot if there's no path to the linker in the target sysroot As seen in rust-lang#125246, some sysroots don't expect to contain `rust-lld` and want to keep it that way, so we fallback to the default rustc sysroot if there is no path to the linker in any of the sysroot tools search paths. This is how we locate codegen-backends' dylibs already. People also have requested an error if none of these search paths contain the self-contained linker directory, so there's also an error in that case. r? `@petrochenkov` cc `@ehuss` `@RalfJung` I'm not sure where we check for `rust-lld`'s existence on the targets where we use it by default, and if we just ignore it when missing or emit a warning (as I assume we don't emit an error), so I just checked for the existence of `gcc-ld`, where `cc` will look for the lld-wrapper binaries. <sub>*Feel free to point out better ways to do this, it's the middle of the night here.*</sub> Fixes rust-lang#125246
2 parents 78dd504 + d64a8bd commit 746de61

File tree

5 files changed

+40
-9
lines changed

5 files changed

+40
-9
lines changed

compiler/rustc_codegen_ssa/messages.ftl

+2
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,8 @@ codegen_ssa_rlib_only_rmeta_found = could not find rlib for: `{$crate_name}`, fo
212212
213213
codegen_ssa_select_cpp_build_tool_workload = in the Visual Studio installer, ensure the "C++ build tools" workload is selected
214214
215+
codegen_ssa_self_contained_linker_missing = the self-contained linker was requested, but it wasn't found in the target's sysroot, or in rustc's sysroot
216+
215217
codegen_ssa_shuffle_indices_evaluation = could not evaluate shuffle_indices at compile time
216218
217219
codegen_ssa_specify_libraries_to_link = use the `-l` flag to specify native libraries to link

compiler/rustc_codegen_ssa/src/back/link.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -3141,13 +3141,21 @@ fn add_lld_args(
31413141

31423142
let self_contained_linker = self_contained_cli || self_contained_target;
31433143
if self_contained_linker && !sess.opts.cg.link_self_contained.is_linker_disabled() {
3144+
let mut linker_path_exists = false;
31443145
for path in sess.get_tools_search_paths(false) {
3146+
let linker_path = path.join("gcc-ld");
3147+
linker_path_exists |= linker_path.exists();
31453148
cmd.arg({
31463149
let mut arg = OsString::from("-B");
3147-
arg.push(path.join("gcc-ld"));
3150+
arg.push(linker_path);
31483151
arg
31493152
});
31503153
}
3154+
if !linker_path_exists {
3155+
// As a sanity check, we emit an error if none of these paths exist: we want
3156+
// self-contained linking and have no linker.
3157+
sess.dcx().emit_fatal(errors::SelfContainedLinkerMissing);
3158+
}
31513159
}
31523160

31533161
// 2. Implement the "linker flavor" part of this feature by asking `cc` to use some kind of

compiler/rustc_codegen_ssa/src/errors.rs

+4
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,10 @@ pub struct UnableToExeLinker {
413413
#[diag(codegen_ssa_msvc_missing_linker)]
414414
pub struct MsvcMissingLinker;
415415

416+
#[derive(Diagnostic)]
417+
#[diag(codegen_ssa_self_contained_linker_missing)]
418+
pub struct SelfContainedLinkerMissing;
419+
416420
#[derive(Diagnostic)]
417421
#[diag(codegen_ssa_check_installed_visual_studio)]
418422
pub struct CheckInstalledVisualStudio;

compiler/rustc_session/src/filesearch.rs

+8
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,14 @@ pub fn make_target_lib_path(sysroot: &Path, target_triple: &str) -> PathBuf {
5151
PathBuf::from_iter([sysroot, Path::new(&rustlib_path), Path::new("lib")])
5252
}
5353

54+
/// Returns a path to the target's `bin` folder within its `rustlib` path in the sysroot. This is
55+
/// where binaries are usually installed, e.g. the self-contained linkers, lld-wrappers, LLVM tools,
56+
/// etc.
57+
pub fn make_target_bin_path(sysroot: &Path, target_triple: &str) -> PathBuf {
58+
let rustlib_path = rustc_target::target_rustlib_path(sysroot, target_triple);
59+
PathBuf::from_iter([sysroot, Path::new(&rustlib_path), Path::new("bin")])
60+
}
61+
5462
#[cfg(unix)]
5563
fn current_dll_path() -> Result<PathBuf, String> {
5664
use std::ffi::{CStr, OsStr};

compiler/rustc_session/src/session.rs

+17-8
Original file line numberDiff line numberDiff line change
@@ -449,15 +449,24 @@ impl Session {
449449
)
450450
}
451451

452-
/// Returns a list of directories where target-specific tool binaries are located.
452+
/// Returns a list of directories where target-specific tool binaries are located. Some fallback
453+
/// directories are also returned, for example if `--sysroot` is used but tools are missing
454+
/// (#125246): we also add the bin directories to the sysroot where rustc is located.
453455
pub fn get_tools_search_paths(&self, self_contained: bool) -> Vec<PathBuf> {
454-
let rustlib_path = rustc_target::target_rustlib_path(&self.sysroot, config::host_triple());
455-
let p = PathBuf::from_iter([
456-
Path::new(&self.sysroot),
457-
Path::new(&rustlib_path),
458-
Path::new("bin"),
459-
]);
460-
if self_contained { vec![p.clone(), p.join("self-contained")] } else { vec![p] }
456+
let bin_path = filesearch::make_target_bin_path(&self.sysroot, config::host_triple());
457+
let fallback_sysroot_paths = filesearch::sysroot_candidates()
458+
.into_iter()
459+
.map(|sysroot| filesearch::make_target_bin_path(&sysroot, config::host_triple()));
460+
let search_paths = std::iter::once(bin_path).chain(fallback_sysroot_paths);
461+
462+
if self_contained {
463+
// The self-contained tools are expected to be e.g. in `bin/self-contained` in the
464+
// sysroot's `rustlib` path, so we add such a subfolder to the bin path, and the
465+
// fallback paths.
466+
search_paths.flat_map(|path| [path.clone(), path.join("self-contained")]).collect()
467+
} else {
468+
search_paths.collect()
469+
}
461470
}
462471

463472
pub fn init_incr_comp_session(&self, session_dir: PathBuf, lock_file: flock::Lock) {

0 commit comments

Comments
 (0)