rustc: Ignore fs::canonicalize errors in metadata
This commit updates the metadata location logic to ignore errors when calling `fs::canonicalize`. Canonicalization was added historically so multiple `-L` paths to the same directory don't print errors about multiple candidates (since rustc can deduplicate same-named paths), but canonicalization doesn't work on all filesystems. Cargo, for example, always uses this sort of fallback where it will opportunitistically try to canonicalize but fall back to using the input path if it otherwise doesn't work. If rustc is run on a filesystem that doesn't support canonicalization then the effect of this change will be that `-L` paths which logically point to the same directory will cause errors, but that's a rare enough occurrence it shouldn't cause much issue in practice. Otherwise rustc doesn't work at all today on those sorts of filesystem where canonicalization isn't supported!
This commit is contained in:
parent
584e83dd5a
commit
cd8bdb5eb9
@ -236,9 +236,9 @@ impl<'a> CrateLoader<'a> {
|
||||
// Only use `--extern crate_name=path` here, not `--extern crate_name`.
|
||||
if let Some(mut files) = entry.files() {
|
||||
if files.any(|l| {
|
||||
let l = fs::canonicalize(l).ok();
|
||||
source.dylib.as_ref().map(|p| &p.0) == l.as_ref()
|
||||
|| source.rlib.as_ref().map(|p| &p.0) == l.as_ref()
|
||||
let l = fs::canonicalize(l).unwrap_or(l.clone().into());
|
||||
source.dylib.as_ref().map(|p| &p.0) == Some(&l)
|
||||
|| source.rlib.as_ref().map(|p| &p.0) == Some(&l)
|
||||
}) {
|
||||
ret = Some(cnum);
|
||||
}
|
||||
|
@ -426,20 +426,17 @@ impl<'a> CrateLocator<'a> {
|
||||
info!("lib candidate: {}", spf.path.display());
|
||||
|
||||
let (rlibs, rmetas, dylibs) = candidates.entry(hash.to_string()).or_default();
|
||||
fs::canonicalize(&spf.path)
|
||||
.map(|p| {
|
||||
if seen_paths.contains(&p) {
|
||||
let path = fs::canonicalize(&spf.path).unwrap_or_else(|_| spf.path.clone());
|
||||
if seen_paths.contains(&path) {
|
||||
return FileDoesntMatch;
|
||||
};
|
||||
seen_paths.insert(p.clone());
|
||||
seen_paths.insert(path.clone());
|
||||
match found_kind {
|
||||
CrateFlavor::Rlib => rlibs.insert(p, kind),
|
||||
CrateFlavor::Rmeta => rmetas.insert(p, kind),
|
||||
CrateFlavor::Dylib => dylibs.insert(p, kind),
|
||||
CrateFlavor::Rlib => rlibs.insert(path, kind),
|
||||
CrateFlavor::Rmeta => rmetas.insert(path, kind),
|
||||
CrateFlavor::Dylib => dylibs.insert(path, kind),
|
||||
};
|
||||
FileMatches
|
||||
})
|
||||
.unwrap_or(FileDoesntMatch)
|
||||
});
|
||||
self.rejected_via_kind.extend(staticlibs);
|
||||
|
||||
@ -688,12 +685,13 @@ impl<'a> CrateLocator<'a> {
|
||||
&& file.ends_with(&self.target.options.dll_suffix)
|
||||
{
|
||||
// Make sure there's at most one rlib and at most one dylib.
|
||||
let loc = fs::canonicalize(&loc).unwrap_or_else(|_| loc.clone());
|
||||
if loc.file_name().unwrap().to_str().unwrap().ends_with(".rlib") {
|
||||
rlibs.insert(fs::canonicalize(&loc).unwrap(), PathKind::ExternFlag);
|
||||
rlibs.insert(loc, PathKind::ExternFlag);
|
||||
} else if loc.file_name().unwrap().to_str().unwrap().ends_with(".rmeta") {
|
||||
rmetas.insert(fs::canonicalize(&loc).unwrap(), PathKind::ExternFlag);
|
||||
rmetas.insert(loc, PathKind::ExternFlag);
|
||||
} else {
|
||||
dylibs.insert(fs::canonicalize(&loc).unwrap(), PathKind::ExternFlag);
|
||||
dylibs.insert(loc, PathKind::ExternFlag);
|
||||
}
|
||||
} else {
|
||||
self.rejected_via_filename
|
||||
|
@ -117,28 +117,22 @@ pub fn make_target_lib_path(sysroot: &Path, target_triple: &str) -> PathBuf {
|
||||
|
||||
pub fn get_or_default_sysroot() -> PathBuf {
|
||||
// Follow symlinks. If the resolved path is relative, make it absolute.
|
||||
fn canonicalize(path: Option<PathBuf>) -> Option<PathBuf> {
|
||||
path.and_then(|path| {
|
||||
match fs::canonicalize(&path) {
|
||||
fn canonicalize(path: PathBuf) -> PathBuf {
|
||||
let path = fs::canonicalize(&path).unwrap_or(path);
|
||||
// See comments on this target function, but the gist is that
|
||||
// gcc chokes on verbatim paths which fs::canonicalize generates
|
||||
// so we try to avoid those kinds of paths.
|
||||
Ok(canon) => Some(fix_windows_verbatim_for_gcc(&canon)),
|
||||
Err(e) => panic!("failed to get realpath: {}", e),
|
||||
}
|
||||
})
|
||||
fix_windows_verbatim_for_gcc(&path)
|
||||
}
|
||||
|
||||
match env::current_exe() {
|
||||
Ok(exe) => match canonicalize(Some(exe)) {
|
||||
Some(mut p) => {
|
||||
Ok(exe) => {
|
||||
let mut p = canonicalize(exe);
|
||||
p.pop();
|
||||
p.pop();
|
||||
p
|
||||
}
|
||||
None => panic!("can't determine value for sysroot"),
|
||||
},
|
||||
Err(ref e) => panic!(format!("failed to get current_exe: {}", e)),
|
||||
Err(e) => panic!("failed to get current_exe: {}", e),
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user