about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2023-03-01 01:21:56 +0100
committerGitHub <noreply@github.com>2023-03-01 01:21:56 +0100
commit0dfbce1bb06b510102f8df6e5e49a5705ba15153 (patch)
tree69c3c53074026312ab92a0a213ac4462aed56d9c
parent31f858d9a511f24fedb8ed997b28304fec809630 (diff)
parent2186358e5a124d486f55a20220f720fb8f9a0694 (diff)
downloadrust-0dfbce1bb06b510102f8df6e5e49a5705ba15153.tar.gz
rust-0dfbce1bb06b510102f8df6e5e49a5705ba15153.zip
Rollup merge of #108376 - liushuyu:fix-sysroot-infer-103660, r=ozkanonur
compiler/rustc_session: fix sysroot detection logic

This pull request fixes the sysroot detection logic on systems where `/usr/lib` contains a multi-arch structure (e.g. installs `rustc_driver` into `/usr/lib/x86_64-linux-gnu` folder).

This fixes a regression for various Linux systems introduced in #103660. On Debian and Ubuntu systems, the logic in the pull request, as mentioned earlier, will resolve the sysroot to `/usr/lib`, making `rustc --print target-libdir` to return `/usr/lib/lib/rustlib/x86_64-unknown-linux-gnu/lib` (notice the extra `lib` at the beginning).

The fix is not very "clean" according to the standard. If you have any suggestions on improving the logic, you are more than welcome to comment below!
-rw-r--r--compiler/rustc_session/src/filesearch.rs12
1 files changed, 11 insertions, 1 deletions
diff --git a/compiler/rustc_session/src/filesearch.rs b/compiler/rustc_session/src/filesearch.rs
index 2075ed57a94..f1fbf38217d 100644
--- a/compiler/rustc_session/src/filesearch.rs
+++ b/compiler/rustc_session/src/filesearch.rs
@@ -182,7 +182,17 @@ pub fn get_or_default_sysroot() -> Result<PathBuf, String> {
         if dir.ends_with(crate::config::host_triple()) {
             dir.parent() // chop off `$target`
                 .and_then(|p| p.parent()) // chop off `rustlib`
-                .and_then(|p| p.parent()) // chop off `lib`
+                .and_then(|p| {
+                    // chop off `lib` (this could be also $arch dir if the host sysroot uses a
+                    // multi-arch layout like Debian or Ubuntu)
+                    match p.parent() {
+                        Some(p) => match p.file_name() {
+                            Some(f) if f == "lib" => p.parent(), // first chop went for $arch, so chop again for `lib`
+                            _ => Some(p),
+                        },
+                        None => None,
+                    }
+                })
                 .map(|s| s.to_owned())
                 .ok_or(format!(
                     "Could not move 3 levels upper using `parent()` on {}",