Skip to content

Commit e98d4d9

Browse files
committed
rollup merge of rust-lang#23283: brson/rpathfix
Fix regression in -C rpath that causes failures with symlinks The new `relative_from` method no longer supports the case on unix where both paths are absolute, which `-C rpath` depended on. This version fixes the problem by copying the old path_relative_from function into the rpath module. Fixes rust-lang#23140 After experimenting with the new `relative_from` function on `Path` I'm not sure what it's use case is. It no longer even figures out that the relative path from `/foo/bar` to `/foo/baz/qux` is `../baz/qux`.
2 parents 67e516c + 9ec9bc6 commit e98d4d9

File tree

2 files changed

+46
-15
lines changed

2 files changed

+46
-15
lines changed

src/librustc_back/rpath.rs

Lines changed: 43 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -99,30 +99,58 @@ fn get_rpath_relative_to_output(config: &mut RPathConfig, lib: &Path) -> String
9999
lib.pop();
100100
let mut output = (config.realpath)(&cwd.join(&config.out_filename)).unwrap();
101101
output.pop();
102-
let relative = relativize(&lib, &output);
102+
let relative = path_relative_from(&lib, &output)
103+
.expect(&format!("couldn't create relative path from {:?} to {:?}", output, lib));
103104
// FIXME (#9639): This needs to handle non-utf8 paths
104105
format!("{}/{}", prefix,
105106
relative.to_str().expect("non-utf8 component in path"))
106107
}
107108

108-
fn relativize(path: &Path, rel: &Path) -> PathBuf {
109-
let mut res = PathBuf::new("");
110-
let mut cur = rel;
111-
while !path.starts_with(cur) {
112-
res.push("..");
113-
match cur.parent() {
114-
Some(p) => cur = p,
115-
None => panic!("can't create relative paths across filesystems"),
109+
// This routine is adapted from the *old* Path's `path_relative_from`
110+
// function, which works differently from the new `relative_from` function.
111+
// In particular, this handles the case on unix where both paths are
112+
// absolute but with only the root as the common directory.
113+
fn path_relative_from(path: &Path, base: &Path) -> Option<PathBuf> {
114+
use std::path::Component;
115+
116+
if path.is_absolute() != base.is_absolute() {
117+
if path.is_absolute() {
118+
Some(PathBuf::new(path))
119+
} else {
120+
None
116121
}
122+
} else {
123+
let mut ita = path.components();
124+
let mut itb = base.components();
125+
let mut comps: Vec<Component> = vec![];
126+
loop {
127+
match (ita.next(), itb.next()) {
128+
(None, None) => break,
129+
(Some(a), None) => {
130+
comps.push(a);
131+
comps.extend(ita.by_ref());
132+
break;
133+
}
134+
(None, _) => comps.push(Component::ParentDir),
135+
(Some(a), Some(b)) if comps.is_empty() && a == b => (),
136+
(Some(a), Some(b)) if b == Component::CurDir => comps.push(a),
137+
(Some(_), Some(b)) if b == Component::ParentDir => return None,
138+
(Some(a), Some(_)) => {
139+
comps.push(Component::ParentDir);
140+
for _ in itb {
141+
comps.push(Component::ParentDir);
142+
}
143+
comps.push(a);
144+
comps.extend(ita.by_ref());
145+
break;
146+
}
147+
}
148+
}
149+
Some(comps.iter().map(|c| c.as_os_str()).collect())
117150
}
118-
match path.relative_from(cur) {
119-
Some(s) => { res.push(s); res }
120-
None => panic!("couldn't create relative path from {:?} to {:?}",
121-
rel, path),
122-
}
123-
124151
}
125152

153+
126154
fn get_install_prefix_rpath(config: &mut RPathConfig) -> String {
127155
let path = (config.get_install_prefix_lib_path)();
128156
let path = env::current_dir().unwrap().join(&path);

src/libstd/path.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1243,6 +1243,9 @@ impl Path {
12431243
}
12441244

12451245
/// Returns a path that, when joined onto `base`, yields `self`.
1246+
///
1247+
/// If `base` is not a prefix of `self` (i.e. `starts_with`
1248+
/// returns false), then `relative_from` returns `None`.
12461249
#[unstable(feature = "path_relative_from", reason = "see #23284")]
12471250
pub fn relative_from<'a, P: ?Sized>(&'a self, base: &'a P) -> Option<&Path> where
12481251
P: AsPath

0 commit comments

Comments
 (0)