Skip to content

Commit 4e7d53d

Browse files
committed
Search codegen backends based on target libdir instead of sysroot.
Fixes cases with custom libdir when it consists of two or more parts.
1 parent 94bf2c1 commit 4e7d53d

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
@@ -124,6 +124,13 @@ pub fn make_target_lib_path(sysroot: &Path, target_triple: &str) -> PathBuf {
124124
sysroot.join(&relative_target_lib_path(sysroot, target_triple))
125125
}
126126

127+
pub fn target_lib_path(target_triple: &str) -> PathBuf {
128+
let mut p = PathBuf::from(RUST_LIB_DIR);
129+
p.push(target_triple);
130+
p.push("lib");
131+
p
132+
}
133+
127134
pub fn get_or_default_sysroot() -> PathBuf {
128135
// Follow symlinks. If the resolved path is relative, make it absolute.
129136
fn canonicalize(path: Option<PathBuf>) -> Option<PathBuf> {

src/librustc_driver/lib.rs

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

296296
let target = session::config::host_triple();
297-
let mut sysroot_candidates = vec![filesearch::get_or_default_sysroot()];
297+
// get target libdir path based on executable binary path
298+
let sysroot = filesearch::get_or_default_sysroot();
299+
let mut libdir_candidates = vec![filesearch::make_target_lib_path(&sysroot, &target)];
298300
let path = current_dll_path()
299301
.and_then(|s| s.canonicalize().ok());
300302
if let Some(dll) = path {
301-
// use `parent` twice to chop off the file name and then also the
302-
// directory containing the dll which should be either `lib` or `bin`.
303-
if let Some(path) = dll.parent().and_then(|p| p.parent()) {
303+
// use `parent` once to chop off the file name
304+
if let Some(path) = dll.parent() {
304305
// The original `path` pointed at the `rustc_driver` crate's dll.
305306
// Now that dll should only be in one of two locations. The first is
306-
// in the compiler's libdir, for example `$sysroot/lib/*.dll`. The
307+
// in the compiler's libdir, for example `$sysroot/$libdir/*.dll`. The
307308
// other is the target's libdir, for example
308-
// `$sysroot/lib/rustlib/$target/lib/*.dll`.
309+
// `$sysroot/$libdir/rustlib/$target/lib/*.dll`.
309310
//
310311
// We don't know which, so let's assume that if our `path` above
311-
// ends in `$target` we *could* be in the target libdir, and always
312-
// assume that we may be in the main libdir.
313-
sysroot_candidates.push(path.to_owned());
314-
315-
if path.ends_with(target) {
316-
sysroot_candidates.extend(path.parent() // chop off `$target`
317-
.and_then(|p| p.parent()) // chop off `rustlib`
318-
.and_then(|p| p.parent()) // chop off `lib`
319-
.map(|s| s.to_owned()));
312+
// doesn't end in `$target` we *could* be in the main libdir, and always
313+
// assume that we may be in the target libdir.
314+
libdir_candidates.push(path.to_owned());
315+
316+
if !path.parent().map_or(false, |p| p.ends_with(target)) {
317+
libdir_candidates.push(path.join(filesearch::target_lib_path(target)));
320318
}
321319
}
322320
}
323321

324-
let sysroot = sysroot_candidates.iter()
325-
.map(|sysroot| {
326-
let libdir = filesearch::relative_target_lib_path(&sysroot, &target);
327-
sysroot.join(libdir).with_file_name(
322+
let sysroot = libdir_candidates.iter()
323+
.map(|libdir| {
324+
debug!("Trying target libdir: {}", libdir.display());
325+
libdir.with_file_name(
328326
option_env!("CFG_CODEGEN_BACKENDS_DIR").unwrap_or("codegen-backends"))
329327
})
330328
.filter(|f| {
@@ -333,12 +331,12 @@ fn get_codegen_sysroot(backend_name: &str) -> fn() -> Box<dyn CodegenBackend> {
333331
})
334332
.next();
335333
let sysroot = sysroot.unwrap_or_else(|| {
336-
let candidates = sysroot_candidates.iter()
334+
let candidates = libdir_candidates.iter()
337335
.map(|p| p.display().to_string())
338336
.collect::<Vec<_>>()
339337
.join("\n* ");
340338
let err = format!("failed to find a `codegen-backends` folder \
341-
in the sysroot candidates:\n* {}", candidates);
339+
in the libdir candidates:\n* {}", candidates);
342340
early_error(ErrorOutputType::default(), &err);
343341
});
344342
info!("probing {} for a codegen backend", sysroot.display());

0 commit comments

Comments
 (0)