Skip to content

Commit 6861426

Browse files
committed
Auto merge of rust-lang#57101 - o01eg:fix-57014, r=alexcrichton
Search codegen backends based on target libdir instead of sysroot Fixes rust-lang#57014 Fixes cases with custom libdir when it consists of two or more parts.
2 parents cae623c + 4e7d53d commit 6861426

File tree

2 files changed

+26
-21
lines changed

2 files changed

+26
-21
lines changed

src/librustc/session/filesearch.rs

+7
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,13 @@ pub fn make_target_lib_path(sysroot: &Path, target_triple: &str) -> PathBuf {
114114
sysroot.join(&relative_target_lib_path(sysroot, target_triple))
115115
}
116116

117+
pub fn target_lib_path(target_triple: &str) -> PathBuf {
118+
let mut p = PathBuf::from(RUST_LIB_DIR);
119+
p.push(target_triple);
120+
p.push("lib");
121+
p
122+
}
123+
117124
pub fn get_or_default_sysroot() -> PathBuf {
118125
// Follow symlinks. If the resolved path is relative, make it absolute.
119126
fn canonicalize(path: Option<PathBuf>) -> Option<PathBuf> {

src/librustc_driver/lib.rs

+19-21
Original file line numberDiff line numberDiff line change
@@ -276,37 +276,35 @@ fn get_codegen_sysroot(backend_name: &str) -> fn() -> Box<dyn CodegenBackend> {
276276
}
277277

278278
let target = session::config::host_triple();
279-
let mut sysroot_candidates = vec![filesearch::get_or_default_sysroot()];
279+
// get target libdir path based on executable binary path
280+
let sysroot = filesearch::get_or_default_sysroot();
281+
let mut libdir_candidates = vec![filesearch::make_target_lib_path(&sysroot, &target)];
280282
let path = current_dll_path()
281283
.and_then(|s| s.canonicalize().ok());
282284
if let Some(dll) = path {
283-
// use `parent` twice to chop off the file name and then also the
284-
// directory containing the dll which should be either `lib` or `bin`.
285-
if let Some(path) = dll.parent().and_then(|p| p.parent()) {
285+
// use `parent` once to chop off the file name
286+
if let Some(path) = dll.parent() {
286287
// The original `path` pointed at the `rustc_driver` crate's dll.
287288
// Now that dll should only be in one of two locations. The first is
288-
// in the compiler's libdir, for example `$sysroot/lib/*.dll`. The
289+
// in the compiler's libdir, for example `$sysroot/$libdir/*.dll`. The
289290
// other is the target's libdir, for example
290-
// `$sysroot/lib/rustlib/$target/lib/*.dll`.
291+
// `$sysroot/$libdir/rustlib/$target/lib/*.dll`.
291292
//
292293
// We don't know which, so let's assume that if our `path` above
293-
// ends in `$target` we *could* be in the target libdir, and always
294-
// assume that we may be in the main libdir.
295-
sysroot_candidates.push(path.to_owned());
296-
297-
if path.ends_with(target) {
298-
sysroot_candidates.extend(path.parent() // chop off `$target`
299-
.and_then(|p| p.parent()) // chop off `rustlib`
300-
.and_then(|p| p.parent()) // chop off `lib`
301-
.map(|s| s.to_owned()));
294+
// doesn't end in `$target` we *could* be in the main libdir, and always
295+
// assume that we may be in the target libdir.
296+
libdir_candidates.push(path.to_owned());
297+
298+
if !path.parent().map_or(false, |p| p.ends_with(target)) {
299+
libdir_candidates.push(path.join(filesearch::target_lib_path(target)));
302300
}
303301
}
304302
}
305303

306-
let sysroot = sysroot_candidates.iter()
307-
.map(|sysroot| {
308-
let libdir = filesearch::relative_target_lib_path(&sysroot, &target);
309-
sysroot.join(libdir).with_file_name(
304+
let sysroot = libdir_candidates.iter()
305+
.map(|libdir| {
306+
debug!("Trying target libdir: {}", libdir.display());
307+
libdir.with_file_name(
310308
option_env!("CFG_CODEGEN_BACKENDS_DIR").unwrap_or("codegen-backends"))
311309
})
312310
.filter(|f| {
@@ -315,12 +313,12 @@ fn get_codegen_sysroot(backend_name: &str) -> fn() -> Box<dyn CodegenBackend> {
315313
})
316314
.next();
317315
let sysroot = sysroot.unwrap_or_else(|| {
318-
let candidates = sysroot_candidates.iter()
316+
let candidates = libdir_candidates.iter()
319317
.map(|p| p.display().to_string())
320318
.collect::<Vec<_>>()
321319
.join("\n* ");
322320
let err = format!("failed to find a `codegen-backends` folder \
323-
in the sysroot candidates:\n* {}", candidates);
321+
in the libdir candidates:\n* {}", candidates);
324322
early_error(ErrorOutputType::default(), &err);
325323
});
326324
info!("probing {} for a codegen backend", sysroot.display());

0 commit comments

Comments
 (0)