rollup merge of #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 #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`.
This commit is contained in:
commit
e98d4d9589
@ -99,30 +99,58 @@ fn get_rpath_relative_to_output(config: &mut RPathConfig, lib: &Path) -> String
|
||||
lib.pop();
|
||||
let mut output = (config.realpath)(&cwd.join(&config.out_filename)).unwrap();
|
||||
output.pop();
|
||||
let relative = relativize(&lib, &output);
|
||||
let relative = path_relative_from(&lib, &output)
|
||||
.expect(&format!("couldn't create relative path from {:?} to {:?}", output, lib));
|
||||
// FIXME (#9639): This needs to handle non-utf8 paths
|
||||
format!("{}/{}", prefix,
|
||||
relative.to_str().expect("non-utf8 component in path"))
|
||||
}
|
||||
|
||||
fn relativize(path: &Path, rel: &Path) -> PathBuf {
|
||||
let mut res = PathBuf::new("");
|
||||
let mut cur = rel;
|
||||
while !path.starts_with(cur) {
|
||||
res.push("..");
|
||||
match cur.parent() {
|
||||
Some(p) => cur = p,
|
||||
None => panic!("can't create relative paths across filesystems"),
|
||||
}
|
||||
}
|
||||
match path.relative_from(cur) {
|
||||
Some(s) => { res.push(s); res }
|
||||
None => panic!("couldn't create relative path from {:?} to {:?}",
|
||||
rel, path),
|
||||
}
|
||||
// This routine is adapted from the *old* Path's `path_relative_from`
|
||||
// function, which works differently from the new `relative_from` function.
|
||||
// In particular, this handles the case on unix where both paths are
|
||||
// absolute but with only the root as the common directory.
|
||||
fn path_relative_from(path: &Path, base: &Path) -> Option<PathBuf> {
|
||||
use std::path::Component;
|
||||
|
||||
if path.is_absolute() != base.is_absolute() {
|
||||
if path.is_absolute() {
|
||||
Some(PathBuf::new(path))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else {
|
||||
let mut ita = path.components();
|
||||
let mut itb = base.components();
|
||||
let mut comps: Vec<Component> = vec![];
|
||||
loop {
|
||||
match (ita.next(), itb.next()) {
|
||||
(None, None) => break,
|
||||
(Some(a), None) => {
|
||||
comps.push(a);
|
||||
comps.extend(ita.by_ref());
|
||||
break;
|
||||
}
|
||||
(None, _) => comps.push(Component::ParentDir),
|
||||
(Some(a), Some(b)) if comps.is_empty() && a == b => (),
|
||||
(Some(a), Some(b)) if b == Component::CurDir => comps.push(a),
|
||||
(Some(_), Some(b)) if b == Component::ParentDir => return None,
|
||||
(Some(a), Some(_)) => {
|
||||
comps.push(Component::ParentDir);
|
||||
for _ in itb {
|
||||
comps.push(Component::ParentDir);
|
||||
}
|
||||
comps.push(a);
|
||||
comps.extend(ita.by_ref());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
Some(comps.iter().map(|c| c.as_os_str()).collect())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn get_install_prefix_rpath(config: &mut RPathConfig) -> String {
|
||||
let path = (config.get_install_prefix_lib_path)();
|
||||
let path = env::current_dir().unwrap().join(&path);
|
||||
|
@ -1243,6 +1243,9 @@ impl Path {
|
||||
}
|
||||
|
||||
/// Returns a path that, when joined onto `base`, yields `self`.
|
||||
///
|
||||
/// If `base` is not a prefix of `self` (i.e. `starts_with`
|
||||
/// returns false), then `relative_from` returns `None`.
|
||||
#[unstable(feature = "path_relative_from", reason = "see #23284")]
|
||||
pub fn relative_from<'a, P: ?Sized>(&'a self, base: &'a P) -> Option<&Path> where
|
||||
P: AsPath
|
||||
|
Loading…
x
Reference in New Issue
Block a user