提交 6c7ecd00 编写于 作者: R Ryan Levick

Pre-canoncalize ExternLocation::ExactPaths

上级 c6bc4622
......@@ -11,7 +11,7 @@
};
use rustc_session::lint::Level;
use rustc_session::search_paths::SearchPath;
use rustc_session::utils::NativeLibKind;
use rustc_session::utils::{CanonicalizedPath, NativeLibKind};
use rustc_session::{build_session, getopts, DiagnosticOutput, Session};
use rustc_span::edition::{Edition, DEFAULT_EDITION};
use rustc_span::symbol::sym;
......@@ -20,7 +20,7 @@
use rustc_target::spec::{RelocModel, RelroLevel, SplitDebuginfo, TlsModel};
use std::collections::{BTreeMap, BTreeSet};
use std::iter::FromIterator;
use std::path::PathBuf;
use std::path::{Path, PathBuf};
type CfgSpecs = FxHashSet<(String, Option<String>)>;
......@@ -50,7 +50,8 @@ fn new_public_extern_entry<S, I>(locations: I) -> ExternEntry
S: Into<String>,
I: IntoIterator<Item = S>,
{
let locations: BTreeSet<_> = locations.into_iter().map(|s| s.into()).collect();
let locations: BTreeSet<CanonicalizedPath> =
locations.into_iter().map(|s| CanonicalizedPath::new(Path::new(&s.into()))).collect();
ExternEntry {
location: ExternLocation::ExactPaths(locations),
......
......@@ -28,7 +28,7 @@
use proc_macro::bridge::client::ProcMacro;
use std::path::Path;
use std::{cmp, env, fs};
use std::{cmp, env};
use tracing::{debug, info};
#[derive(Clone)]
......@@ -252,10 +252,10 @@ 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).unwrap_or(l.clone().into());
source.dylib.as_ref().map(|(p, _)| p) == Some(&l)
|| source.rlib.as_ref().map(|(p, _)| p) == Some(&l)
|| source.rmeta.as_ref().map(|(p, _)| p) == Some(&l)
let l = l.canonicalized();
source.dylib.as_ref().map(|(p, _)| p) == Some(l)
|| source.rlib.as_ref().map(|(p, _)| p) == Some(l)
|| source.rmeta.as_ref().map(|(p, _)| p) == Some(l)
}) {
ret = Some(cnum);
}
......
......@@ -224,6 +224,7 @@
use rustc_session::config::{self, CrateType};
use rustc_session::filesearch::{FileDoesntMatch, FileMatches, FileSearch};
use rustc_session::search_paths::PathKind;
use rustc_session::utils::CanonicalizedPath;
use rustc_session::{CrateDisambiguator, Session};
use rustc_span::symbol::{sym, Symbol};
use rustc_span::Span;
......@@ -244,7 +245,7 @@
// Immutable per-search configuration.
crate_name: Symbol,
exact_paths: Vec<PathBuf>,
exact_paths: Vec<CanonicalizedPath>,
pub hash: Option<Svh>,
pub host_hash: Option<Svh>,
extra_filename: Option<&'a str>,
......@@ -315,7 +316,7 @@ impl<'a> CrateLocator<'a> {
.into_iter()
.filter_map(|entry| entry.files())
.flatten()
.map(PathBuf::from)
.cloned()
.collect()
} else {
// SVH being specified means this is a transitive dependency,
......@@ -664,13 +665,19 @@ fn find_commandline_library(&mut self) -> Result<Option<Library>, CrateError> {
let mut rmetas = FxHashMap::default();
let mut dylibs = FxHashMap::default();
for loc in &self.exact_paths {
if !loc.exists() {
return Err(CrateError::ExternLocationNotExist(self.crate_name, loc.clone()));
if !loc.canonicalized().exists() {
return Err(CrateError::ExternLocationNotExist(
self.crate_name,
loc.original().clone(),
));
}
let file = match loc.file_name().and_then(|s| s.to_str()) {
let file = match loc.original().file_name().and_then(|s| s.to_str()) {
Some(file) => file,
None => {
return Err(CrateError::ExternLocationNotFile(self.crate_name, loc.clone()));
return Err(CrateError::ExternLocationNotFile(
self.crate_name,
loc.original().clone(),
));
}
};
......@@ -685,7 +692,8 @@ fn find_commandline_library(&mut self) -> Result<Option<Library>, CrateError> {
// e.g. symbolic links. If we canonicalize too early, we resolve
// the symlink, the file type is lost and we might treat rlibs and
// rmetas as dylibs.
let loc_canon = fs::canonicalize(&loc).unwrap_or_else(|_| loc.clone());
let loc_canon = loc.canonicalized().clone();
let loc = loc.original();
if loc.file_name().unwrap().to_str().unwrap().ends_with(".rlib") {
rlibs.insert(loc_canon, PathKind::ExternFlag);
} else if loc.file_name().unwrap().to_str().unwrap().ends_with(".rmeta") {
......@@ -695,7 +703,7 @@ fn find_commandline_library(&mut self) -> Result<Option<Library>, CrateError> {
}
} else {
self.rejected_via_filename
.push(CrateMismatch { path: loc.clone(), got: String::new() });
.push(CrateMismatch { path: loc.original().clone(), got: String::new() });
}
}
......
......@@ -5,7 +5,7 @@
use crate::lint;
use crate::search_paths::SearchPath;
use crate::utils::NativeLibKind;
use crate::utils::{CanonicalizedPath, NativeLibKind};
use crate::{early_error, early_warn, Session};
use rustc_data_structures::fx::FxHashSet;
......@@ -436,7 +436,7 @@ pub enum ExternLocation {
/// which one to use.
///
/// Added via `--extern prelude_name=some_file.rlib`
ExactPaths(BTreeSet<String>),
ExactPaths(BTreeSet<CanonicalizedPath>),
}
impl Externs {
......@@ -458,7 +458,7 @@ fn new(location: ExternLocation) -> ExternEntry {
ExternEntry { location, is_private_dep: false, add_prelude: false }
}
pub fn files(&self) -> Option<impl Iterator<Item = &String>> {
pub fn files(&self) -> Option<impl Iterator<Item = &CanonicalizedPath>> {
match &self.location {
ExternLocation::ExactPaths(set) => Some(set.iter()),
_ => None,
......@@ -1639,13 +1639,15 @@ pub fn parse_externs(
for arg in matches.opt_strs("extern") {
let (name, path) = match arg.split_once('=') {
None => (arg, None),
Some((name, path)) => (name.to_string(), Some(path.to_string())),
Some((name, path)) => (name.to_string(), Some(Path::new(path))),
};
let (options, name) = match name.split_once(':') {
None => (None, name),
Some((opts, name)) => (Some(opts), name.to_string()),
};
let path = path.map(|p| CanonicalizedPath::new(p));
let entry = externs.entry(name.to_owned());
use std::collections::btree_map::Entry;
......
use crate::session::Session;
use rustc_data_structures::profiling::VerboseTimingGuard;
use std::path::{Path, PathBuf};
impl Session {
pub fn timer<'a>(&'a self, what: &'static str) -> VerboseTimingGuard<'a> {
......@@ -30,3 +31,25 @@ pub enum NativeLibKind {
}
rustc_data_structures::impl_stable_hash_via_hash!(NativeLibKind);
/// A path that has been canonicalized along with its original, non-canonicalized form
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub struct CanonicalizedPath {
// Optional since canonicalization can sometimes fail
canonicalized: Option<PathBuf>,
original: PathBuf,
}
impl CanonicalizedPath {
pub fn new(path: &Path) -> Self {
Self { original: path.to_owned(), canonicalized: std::fs::canonicalize(path).ok() }
}
pub fn canonicalized(&self) -> &PathBuf {
self.canonicalized.as_ref().unwrap_or(self.original())
}
pub fn original(&self) -> &PathBuf {
&self.original
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册