]> git.lizzy.rs Git - rust.git/commitdiff
Auto merge of #57101 - o01eg:fix-57014, r=alexcrichton
authorbors <bors@rust-lang.org>
Sat, 5 Jan 2019 12:21:44 +0000 (12:21 +0000)
committerbors <bors@rust-lang.org>
Sat, 5 Jan 2019 12:21:44 +0000 (12:21 +0000)
Search codegen backends based on target libdir instead of sysroot

Fixes #57014

Fixes cases with custom libdir when it consists of two or more parts.

src/librustc/session/filesearch.rs
src/librustc_driver/lib.rs

index 19f1c7a18fad14ebf0c4f2f2c2269cbff1de984c..c6e68ba379ec378aa0b1cfa85616ddd78181e6f4 100644 (file)
@@ -114,6 +114,13 @@ pub fn make_target_lib_path(sysroot: &Path, target_triple: &str) -> PathBuf {
     sysroot.join(&relative_target_lib_path(sysroot, target_triple))
 }
 
+pub fn target_lib_path(target_triple: &str) -> PathBuf {
+    let mut p = PathBuf::from(RUST_LIB_DIR);
+    p.push(target_triple);
+    p.push("lib");
+    p
+}
+
 pub fn get_or_default_sysroot() -> PathBuf {
     // Follow symlinks.  If the resolved path is relative, make it absolute.
     fn canonicalize(path: Option<PathBuf>) -> Option<PathBuf> {
index e9f309373008b60005c7deced81a4d78827835cd..5ff3dc14cdc8a10d9c6020fa62268f0965b7bc73 100644 (file)
@@ -276,37 +276,35 @@ fn get_codegen_sysroot(backend_name: &str) -> fn() -> Box<dyn CodegenBackend> {
     }
 
     let target = session::config::host_triple();
-    let mut sysroot_candidates = vec![filesearch::get_or_default_sysroot()];
+    // get target libdir path based on executable binary path
+    let sysroot = filesearch::get_or_default_sysroot();
+    let mut libdir_candidates = vec![filesearch::make_target_lib_path(&sysroot, &target)];
     let path = current_dll_path()
         .and_then(|s| s.canonicalize().ok());
     if let Some(dll) = path {
-        // use `parent` twice to chop off the file name and then also the
-        // directory containing the dll which should be either `lib` or `bin`.
-        if let Some(path) = dll.parent().and_then(|p| p.parent()) {
+        // use `parent` once to chop off the file name
+        if let Some(path) = dll.parent() {
             // The original `path` pointed at the `rustc_driver` crate's dll.
             // Now that dll should only be in one of two locations. The first is
-            // in the compiler's libdir, for example `$sysroot/lib/*.dll`. The
+            // in the compiler's libdir, for example `$sysroot/$libdir/*.dll`. The
             // other is the target's libdir, for example
-            // `$sysroot/lib/rustlib/$target/lib/*.dll`.
+            // `$sysroot/$libdir/rustlib/$target/lib/*.dll`.
             //
             // We don't know which, so let's assume that if our `path` above
-            // ends in `$target` we *could* be in the target libdir, and always
-            // assume that we may be in the main libdir.
-            sysroot_candidates.push(path.to_owned());
-
-            if path.ends_with(target) {
-                sysroot_candidates.extend(path.parent() // chop off `$target`
-                    .and_then(|p| p.parent())           // chop off `rustlib`
-                    .and_then(|p| p.parent())           // chop off `lib`
-                    .map(|s| s.to_owned()));
+            // doesn't end in `$target` we *could* be in the main libdir, and always
+            // assume that we may be in the target libdir.
+            libdir_candidates.push(path.to_owned());
+
+            if !path.parent().map_or(false, |p| p.ends_with(target)) {
+                libdir_candidates.push(path.join(filesearch::target_lib_path(target)));
             }
         }
     }
 
-    let sysroot = sysroot_candidates.iter()
-        .map(|sysroot| {
-            let libdir = filesearch::relative_target_lib_path(&sysroot, &target);
-            sysroot.join(libdir).with_file_name(
+    let sysroot = libdir_candidates.iter()
+        .map(|libdir| {
+            debug!("Trying target libdir: {}", libdir.display());
+            libdir.with_file_name(
                 option_env!("CFG_CODEGEN_BACKENDS_DIR").unwrap_or("codegen-backends"))
         })
         .filter(|f| {
@@ -315,12 +313,12 @@ fn get_codegen_sysroot(backend_name: &str) -> fn() -> Box<dyn CodegenBackend> {
         })
         .next();
     let sysroot = sysroot.unwrap_or_else(|| {
-        let candidates = sysroot_candidates.iter()
+        let candidates = libdir_candidates.iter()
             .map(|p| p.display().to_string())
             .collect::<Vec<_>>()
             .join("\n* ");
         let err = format!("failed to find a `codegen-backends` folder \
-                           in the sysroot candidates:\n* {}", candidates);
+                           in the libdir candidates:\n* {}", candidates);
         early_error(ErrorOutputType::default(), &err);
     });
     info!("probing {} for a codegen backend", sysroot.display());