Skip to content

Commit 3f2c55f

Browse files
committed
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 rust-lang#11734 cc rust-lang#11857
1 parent 25a6b6e commit 3f2c55f

File tree

2 files changed

+10
-14
lines changed

2 files changed

+10
-14
lines changed

src/librustc/back/rpath.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,10 @@
1212
use driver::session::Session;
1313
use metadata::cstore;
1414
use metadata::filesearch;
15+
use util::fs;
1516

1617
use collections::HashSet;
17-
use std::{os, slice};
18+
use std::os;
1819
use syntax::abi;
1920

2021
fn not_win32(os: abi::Os) -> bool {
@@ -121,9 +122,9 @@ pub fn get_rpath_relative_to_output(os: abi::Os,
121122
abi::OsWin32 => unreachable!()
122123
};
123124

124-
let mut lib = os::make_absolute(lib);
125+
let mut lib = fs::realpath(&os::make_absolute(lib)).unwrap();
125126
lib.pop();
126-
let mut output = os::make_absolute(output);
127+
let mut output = fs::realpath(&os::make_absolute(output)).unwrap();
127128
output.pop();
128129
let relative = lib.path_relative_from(&output);
129130
let relative = relative.expect("could not create rpath relative to output");

src/librustc/metadata/filesearch.rs

+6-11
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ use std::os;
1515
use std::io::fs;
1616
use collections::HashSet;
1717

18+
use myfs = util::fs;
19+
1820
pub enum FileMatch { FileMatches, FileDoesntMatch }
1921

2022
// A module for searching for libraries
@@ -156,17 +158,10 @@ fn make_rustpkg_target_lib_path(sysroot: &Path,
156158
pub fn get_or_default_sysroot() -> Path {
157159
// Follow symlinks. If the resolved path is relative, make it absolute.
158160
fn canonicalize(path: Option<Path>) -> Option<Path> {
159-
path.and_then(|mut path|
160-
match fs::readlink(&path) {
161-
Ok(canon) => {
162-
if canon.is_absolute() {
163-
Some(canon)
164-
} else {
165-
path.pop();
166-
Some(path.join(canon))
167-
}
168-
},
169-
Err(..) => Some(path),
161+
path.and_then(|path|
162+
match myfs::realpath(&path) {
163+
Ok(canon) => Some(canon),
164+
Err(e) => fail!("failed to get realpath: {}", e),
170165
})
171166
}
172167

0 commit comments

Comments
 (0)