about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2014-04-08 10:15:46 -0700
committerAlex Crichton <alex@alexcrichton.com>2014-04-10 15:22:00 -0700
commit3f2c55f7d5b5c7717dd12eef4572c52a4e8ff550 (patch)
tree5d33313d67b78e779affbc42ce0b988226242209 /src
parent25a6b6ef8b4a2852c98585496146ca9d3da37b1b (diff)
downloadrust-3f2c55f7d5b5c7717dd12eef4572c52a4e8ff550.tar.gz
rust-3f2c55f7d5b5c7717dd12eef4572c52a4e8ff550.zip
rustc: Use realpath() for sysroot/rpath
When calculating the sysroot, it's more accurate to use realpath() rather than
just one readlink() to account for any intermediate symlinks that the rustc
binary resolves itself to.

For rpath, realpath() is necessary because the rpath must dictate a relative
rpath from the destination back to the originally linked library, which works
more robustly if there are no symlinks involved.

Concretely, any binary generated on OSX into $TMPDIR requires an absolute rpath
because the temporary directory is behind a symlink with one layer of
indirection. This symlink causes all relative rpaths to fail to resolve.

cc #11734
cc #11857
Diffstat (limited to 'src')
-rw-r--r--src/librustc/back/rpath.rs7
-rw-r--r--src/librustc/metadata/filesearch.rs17
2 files changed, 10 insertions, 14 deletions
diff --git a/src/librustc/back/rpath.rs b/src/librustc/back/rpath.rs
index 4b54b1f6008..e455c4ad23c 100644
--- a/src/librustc/back/rpath.rs
+++ b/src/librustc/back/rpath.rs
@@ -12,9 +12,10 @@
 use driver::session::Session;
 use metadata::cstore;
 use metadata::filesearch;
+use util::fs;
 
 use collections::HashSet;
-use std::{os, slice};
+use std::os;
 use syntax::abi;
 
 fn not_win32(os: abi::Os) -> bool {
@@ -121,9 +122,9 @@ pub fn get_rpath_relative_to_output(os: abi::Os,
         abi::OsWin32 => unreachable!()
     };
 
-    let mut lib = os::make_absolute(lib);
+    let mut lib = fs::realpath(&os::make_absolute(lib)).unwrap();
     lib.pop();
-    let mut output = os::make_absolute(output);
+    let mut output = fs::realpath(&os::make_absolute(output)).unwrap();
     output.pop();
     let relative = lib.path_relative_from(&output);
     let relative = relative.expect("could not create rpath relative to output");
diff --git a/src/librustc/metadata/filesearch.rs b/src/librustc/metadata/filesearch.rs
index 7a531c5c128..f4ea386a2ec 100644
--- a/src/librustc/metadata/filesearch.rs
+++ b/src/librustc/metadata/filesearch.rs
@@ -15,6 +15,8 @@ use std::os;
 use std::io::fs;
 use collections::HashSet;
 
+use myfs = util::fs;
+
 pub enum FileMatch { FileMatches, FileDoesntMatch }
 
 // A module for searching for libraries
@@ -156,17 +158,10 @@ fn make_rustpkg_target_lib_path(sysroot: &Path,
 pub fn get_or_default_sysroot() -> Path {
     // Follow symlinks.  If the resolved path is relative, make it absolute.
     fn canonicalize(path: Option<Path>) -> Option<Path> {
-        path.and_then(|mut path|
-            match fs::readlink(&path) {
-                Ok(canon) => {
-                    if canon.is_absolute() {
-                        Some(canon)
-                    } else {
-                        path.pop();
-                        Some(path.join(canon))
-                    }
-                },
-                Err(..) => Some(path),
+        path.and_then(|path|
+            match myfs::realpath(&path) {
+                Ok(canon) => Some(canon),
+                Err(e) => fail!("failed to get realpath: {}", e),
             })
     }