about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBen Noordhuis <info@bnoordhuis.nl>2014-01-22 23:45:52 +0100
committerBen Noordhuis <info@bnoordhuis.nl>2014-01-23 11:45:23 +0100
commit8cce35e490ce259244656e12d272ab1915b0541b (patch)
tree7217882021ff93b5751d291496f4a9ef0d3d31a7
parentcdd146b8954d704a07a4445f00ef8ed0f65da096 (diff)
Follow symlinks in sysroot
Before this commit, rustc looked in `dirname $0`/../lib for libraries
but that doesn't work when rustc is invoked through a symlink.

This commit makes rustc look in `dirname $(readlink $0)`/../lib, i.e.
it first canonicalizes the symlink before walking up the directory tree.

Fixes #3632.
-rw-r--r--src/librustc/metadata/filesearch.rs20
1 files changed, 18 insertions, 2 deletions
diff --git a/src/librustc/metadata/filesearch.rs b/src/librustc/metadata/filesearch.rs
index f8e7a28d277..fd8c620dc4e 100644
--- a/src/librustc/metadata/filesearch.rs
+++ b/src/librustc/metadata/filesearch.rs
@@ -160,8 +160,24 @@ fn make_rustpkg_target_lib_path(dir: &Path,
 }
 
 pub fn get_or_default_sysroot() -> Path {
-    match os::self_exe_path() {
-      option::Some(p) => { let mut p = p; p.pop(); p }
+    // Follow symlinks.  If the resolved path is relative, make it absolute.
+    fn canonicalize(path: Option<Path>) -> Option<Path> {
+        path.and_then(|mut path|
+            match io::io_error::cond.trap(|_| ()).inside(|| fs::readlink(&path)) {
+                Some(canon) => {
+                    if canon.is_absolute() {
+                        Some(canon)
+                    } else {
+                        path.pop();
+                        Some(path.join(canon))
+                    }
+                },
+                None => Some(path),
+            })
+    }
+
+    match canonicalize(os::self_exe_name()) {
+      option::Some(p) => { let mut p = p; p.pop(); p.pop(); p }
       option::None => fail!("can't determine value for sysroot")
     }
 }