mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-29 03:27:44 +00:00
Auto merge of #81419 - rylev:canocalize-extern-entries, r=petrochenkov
Pre-canoncalize ExternLocation::ExactPaths This stores pre-canacolized paths inside `ExternLocation::ExactPaths` so that we don't need to canoncalize them every time we want to compare them to source lib paths. This is related to #81414.
This commit is contained in:
commit
c4e33b51c1
@ -11,7 +11,7 @@ use rustc_session::config::{
|
|||||||
};
|
};
|
||||||
use rustc_session::lint::Level;
|
use rustc_session::lint::Level;
|
||||||
use rustc_session::search_paths::SearchPath;
|
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_session::{build_session, getopts, DiagnosticOutput, Session};
|
||||||
use rustc_span::edition::{Edition, DEFAULT_EDITION};
|
use rustc_span::edition::{Edition, DEFAULT_EDITION};
|
||||||
use rustc_span::symbol::sym;
|
use rustc_span::symbol::sym;
|
||||||
@ -20,7 +20,7 @@ use rustc_target::spec::{CodeModel, LinkerFlavor, MergeFunctions, PanicStrategy}
|
|||||||
use rustc_target::spec::{RelocModel, RelroLevel, SplitDebuginfo, TlsModel};
|
use rustc_target::spec::{RelocModel, RelroLevel, SplitDebuginfo, TlsModel};
|
||||||
use std::collections::{BTreeMap, BTreeSet};
|
use std::collections::{BTreeMap, BTreeSet};
|
||||||
use std::iter::FromIterator;
|
use std::iter::FromIterator;
|
||||||
use std::path::PathBuf;
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
type CfgSpecs = FxHashSet<(String, Option<String>)>;
|
type CfgSpecs = FxHashSet<(String, Option<String>)>;
|
||||||
|
|
||||||
@ -50,7 +50,8 @@ where
|
|||||||
S: Into<String>,
|
S: Into<String>,
|
||||||
I: IntoIterator<Item = S>,
|
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 {
|
ExternEntry {
|
||||||
location: ExternLocation::ExactPaths(locations),
|
location: ExternLocation::ExactPaths(locations),
|
||||||
|
@ -28,7 +28,7 @@ use rustc_target::spec::{PanicStrategy, TargetTriple};
|
|||||||
|
|
||||||
use proc_macro::bridge::client::ProcMacro;
|
use proc_macro::bridge::client::ProcMacro;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::{cmp, env, fs};
|
use std::{cmp, env};
|
||||||
use tracing::{debug, info};
|
use tracing::{debug, info};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
@ -252,10 +252,10 @@ impl<'a> CrateLoader<'a> {
|
|||||||
// Only use `--extern crate_name=path` here, not `--extern crate_name`.
|
// Only use `--extern crate_name=path` here, not `--extern crate_name`.
|
||||||
if let Some(mut files) = entry.files() {
|
if let Some(mut files) = entry.files() {
|
||||||
if files.any(|l| {
|
if files.any(|l| {
|
||||||
let l = fs::canonicalize(l).unwrap_or(l.clone().into());
|
let l = l.canonicalized();
|
||||||
source.dylib.as_ref().map(|(p, _)| p) == Some(&l)
|
source.dylib.as_ref().map(|(p, _)| p) == Some(l)
|
||||||
|| source.rlib.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)
|
|| source.rmeta.as_ref().map(|(p, _)| p) == Some(l)
|
||||||
}) {
|
}) {
|
||||||
ret = Some(cnum);
|
ret = Some(cnum);
|
||||||
}
|
}
|
||||||
|
@ -224,6 +224,7 @@ use rustc_middle::middle::cstore::{CrateSource, MetadataLoader};
|
|||||||
use rustc_session::config::{self, CrateType};
|
use rustc_session::config::{self, CrateType};
|
||||||
use rustc_session::filesearch::{FileDoesntMatch, FileMatches, FileSearch};
|
use rustc_session::filesearch::{FileDoesntMatch, FileMatches, FileSearch};
|
||||||
use rustc_session::search_paths::PathKind;
|
use rustc_session::search_paths::PathKind;
|
||||||
|
use rustc_session::utils::CanonicalizedPath;
|
||||||
use rustc_session::{CrateDisambiguator, Session};
|
use rustc_session::{CrateDisambiguator, Session};
|
||||||
use rustc_span::symbol::{sym, Symbol};
|
use rustc_span::symbol::{sym, Symbol};
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
@ -244,7 +245,7 @@ crate struct CrateLocator<'a> {
|
|||||||
|
|
||||||
// Immutable per-search configuration.
|
// Immutable per-search configuration.
|
||||||
crate_name: Symbol,
|
crate_name: Symbol,
|
||||||
exact_paths: Vec<PathBuf>,
|
exact_paths: Vec<CanonicalizedPath>,
|
||||||
pub hash: Option<Svh>,
|
pub hash: Option<Svh>,
|
||||||
pub host_hash: Option<Svh>,
|
pub host_hash: Option<Svh>,
|
||||||
extra_filename: Option<&'a str>,
|
extra_filename: Option<&'a str>,
|
||||||
@ -315,7 +316,7 @@ impl<'a> CrateLocator<'a> {
|
|||||||
.into_iter()
|
.into_iter()
|
||||||
.filter_map(|entry| entry.files())
|
.filter_map(|entry| entry.files())
|
||||||
.flatten()
|
.flatten()
|
||||||
.map(PathBuf::from)
|
.cloned()
|
||||||
.collect()
|
.collect()
|
||||||
} else {
|
} else {
|
||||||
// SVH being specified means this is a transitive dependency,
|
// SVH being specified means this is a transitive dependency,
|
||||||
@ -664,13 +665,19 @@ impl<'a> CrateLocator<'a> {
|
|||||||
let mut rmetas = FxHashMap::default();
|
let mut rmetas = FxHashMap::default();
|
||||||
let mut dylibs = FxHashMap::default();
|
let mut dylibs = FxHashMap::default();
|
||||||
for loc in &self.exact_paths {
|
for loc in &self.exact_paths {
|
||||||
if !loc.exists() {
|
if !loc.canonicalized().exists() {
|
||||||
return Err(CrateError::ExternLocationNotExist(self.crate_name, loc.clone()));
|
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,
|
Some(file) => file,
|
||||||
None => {
|
None => {
|
||||||
return Err(CrateError::ExternLocationNotFile(self.crate_name, loc.clone()));
|
return Err(CrateError::ExternLocationNotFile(
|
||||||
|
self.crate_name,
|
||||||
|
loc.original().clone(),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -685,7 +692,8 @@ impl<'a> CrateLocator<'a> {
|
|||||||
// e.g. symbolic links. If we canonicalize too early, we resolve
|
// e.g. symbolic links. If we canonicalize too early, we resolve
|
||||||
// the symlink, the file type is lost and we might treat rlibs and
|
// the symlink, the file type is lost and we might treat rlibs and
|
||||||
// rmetas as dylibs.
|
// 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") {
|
if loc.file_name().unwrap().to_str().unwrap().ends_with(".rlib") {
|
||||||
rlibs.insert(loc_canon, PathKind::ExternFlag);
|
rlibs.insert(loc_canon, PathKind::ExternFlag);
|
||||||
} else if loc.file_name().unwrap().to_str().unwrap().ends_with(".rmeta") {
|
} else if loc.file_name().unwrap().to_str().unwrap().ends_with(".rmeta") {
|
||||||
@ -695,7 +703,7 @@ impl<'a> CrateLocator<'a> {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.rejected_via_filename
|
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 @@ pub use crate::options::*;
|
|||||||
|
|
||||||
use crate::lint;
|
use crate::lint;
|
||||||
use crate::search_paths::SearchPath;
|
use crate::search_paths::SearchPath;
|
||||||
use crate::utils::NativeLibKind;
|
use crate::utils::{CanonicalizedPath, NativeLibKind};
|
||||||
use crate::{early_error, early_warn, Session};
|
use crate::{early_error, early_warn, Session};
|
||||||
|
|
||||||
use rustc_data_structures::fx::FxHashSet;
|
use rustc_data_structures::fx::FxHashSet;
|
||||||
@ -436,7 +436,7 @@ pub enum ExternLocation {
|
|||||||
/// which one to use.
|
/// which one to use.
|
||||||
///
|
///
|
||||||
/// Added via `--extern prelude_name=some_file.rlib`
|
/// Added via `--extern prelude_name=some_file.rlib`
|
||||||
ExactPaths(BTreeSet<String>),
|
ExactPaths(BTreeSet<CanonicalizedPath>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Externs {
|
impl Externs {
|
||||||
@ -458,7 +458,7 @@ impl ExternEntry {
|
|||||||
ExternEntry { location, is_private_dep: false, add_prelude: false }
|
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 {
|
match &self.location {
|
||||||
ExternLocation::ExactPaths(set) => Some(set.iter()),
|
ExternLocation::ExactPaths(set) => Some(set.iter()),
|
||||||
_ => None,
|
_ => None,
|
||||||
@ -1639,13 +1639,15 @@ pub fn parse_externs(
|
|||||||
for arg in matches.opt_strs("extern") {
|
for arg in matches.opt_strs("extern") {
|
||||||
let (name, path) = match arg.split_once('=') {
|
let (name, path) = match arg.split_once('=') {
|
||||||
None => (arg, None),
|
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(':') {
|
let (options, name) = match name.split_once(':') {
|
||||||
None => (None, name),
|
None => (None, name),
|
||||||
Some((opts, name)) => (Some(opts), name.to_string()),
|
Some((opts, name)) => (Some(opts), name.to_string()),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let path = path.map(|p| CanonicalizedPath::new(p));
|
||||||
|
|
||||||
let entry = externs.entry(name.to_owned());
|
let entry = externs.entry(name.to_owned());
|
||||||
|
|
||||||
use std::collections::btree_map::Entry;
|
use std::collections::btree_map::Entry;
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
use crate::session::Session;
|
use crate::session::Session;
|
||||||
use rustc_data_structures::profiling::VerboseTimingGuard;
|
use rustc_data_structures::profiling::VerboseTimingGuard;
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
impl Session {
|
impl Session {
|
||||||
pub fn timer<'a>(&'a self, what: &'static str) -> VerboseTimingGuard<'a> {
|
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);
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user