Rollup merge of #74915 - alexcrichton:allow-failing-canonicalize, r=Mark-Simulacrum
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:
commit
0a45b1303c
@ -248,9 +248,9 @@ fn existing_match(&self, name: Symbol, hash: Option<Svh>, kind: PathKind) -> Opt
|
||||
// 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 @@ fn find_library_crate(
|
||||
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) {
|
||||
return FileDoesntMatch;
|
||||
};
|
||||
seen_paths.insert(p.clone());
|
||||
match found_kind {
|
||||
CrateFlavor::Rlib => rlibs.insert(p, kind),
|
||||
CrateFlavor::Rmeta => rmetas.insert(p, kind),
|
||||
CrateFlavor::Dylib => dylibs.insert(p, kind),
|
||||
};
|
||||
FileMatches
|
||||
})
|
||||
.unwrap_or(FileDoesntMatch)
|
||||
let path = fs::canonicalize(&spf.path).unwrap_or_else(|_| spf.path.clone());
|
||||
if seen_paths.contains(&path) {
|
||||
return FileDoesntMatch;
|
||||
};
|
||||
seen_paths.insert(path.clone());
|
||||
match found_kind {
|
||||
CrateFlavor::Rlib => rlibs.insert(path, kind),
|
||||
CrateFlavor::Rmeta => rmetas.insert(path, kind),
|
||||
CrateFlavor::Dylib => dylibs.insert(path, kind),
|
||||
};
|
||||
FileMatches
|
||||
});
|
||||
self.rejected_via_kind.extend(staticlibs);
|
||||
|
||||
@ -688,12 +685,13 @@ fn find_commandline_library(&mut self) -> Result<Option<Library>, CrateError> {
|
||||
&& 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) {
|
||||
// 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),
|
||||
}
|
||||
})
|
||||
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.
|
||||
fix_windows_verbatim_for_gcc(&path)
|
||||
}
|
||||
|
||||
match env::current_exe() {
|
||||
Ok(exe) => match canonicalize(Some(exe)) {
|
||||
Some(mut p) => {
|
||||
p.pop();
|
||||
p.pop();
|
||||
p
|
||||
}
|
||||
None => panic!("can't determine value for sysroot"),
|
||||
},
|
||||
Err(ref e) => panic!(format!("failed to get current_exe: {}", e)),
|
||||
Ok(exe) => {
|
||||
let mut p = canonicalize(exe);
|
||||
p.pop();
|
||||
p.pop();
|
||||
p
|
||||
}
|
||||
Err(e) => panic!("failed to get current_exe: {}", e),
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user