diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 6939674ce9d..874732ee9ef 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -3116,13 +3116,21 @@ fn add_lld_args( let self_contained_linker = self_contained_cli || self_contained_target; if self_contained_linker && !sess.opts.cg.link_self_contained.is_linker_disabled() { + let mut linker_path_exists = false; for path in sess.get_tools_search_paths(false) { + let linker_path = path.join("gcc-ld"); + linker_path_exists |= linker_path.exists(); cmd.arg({ let mut arg = OsString::from("-B"); - arg.push(path.join("gcc-ld")); + arg.push(linker_path); arg }); } + if !linker_path_exists { + // As an additional sanity check, we do nothing if the sysroot doesn't contain the + // linker path at all. + return; + } } // 2. Implement the "linker flavor" part of this feature by asking `cc` to use some kind of diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index db01bb90d6f..05284c5ed40 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -449,15 +449,24 @@ impl Session { ) } - /// Returns a list of directories where target-specific tool binaries are located. + /// Returns a list of directories where target-specific tool binaries are located. Some fallback + /// directories are also returned, for example if `--sysroot` is used but tools are missing + /// (#125246): we also add the bin directories to the sysroot where rustc is located. pub fn get_tools_search_paths(&self, self_contained: bool) -> Vec { - let rustlib_path = rustc_target::target_rustlib_path(&self.sysroot, config::host_triple()); - let p = PathBuf::from_iter([ - Path::new(&self.sysroot), - Path::new(&rustlib_path), - Path::new("bin"), - ]); - if self_contained { vec![p.clone(), p.join("self-contained")] } else { vec![p] } + let bin_path = filesearch::make_target_bin_path(&self.sysroot, config::host_triple()); + let fallback_sysroot_paths = filesearch::sysroot_candidates() + .into_iter() + .map(|sysroot| filesearch::make_target_bin_path(&sysroot, config::host_triple())); + let search_paths = std::iter::once(bin_path).chain(fallback_sysroot_paths); + + if self_contained { + // The self-contained tools are expected to be e.g. in `bin/self-contained` in the + // sysroot's `rustlib` path, so we add such a subfolder to the bin path, and the + // fallback paths. + search_paths.flat_map(|path| [path.clone(), path.join("self-contained")]).collect() + } else { + search_paths.collect() + } } pub fn init_incr_comp_session(&self, session_dir: PathBuf, lock_file: flock::Lock) {