diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 4fb51ecc1d347..826c09cd948f6 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -637,7 +637,7 @@ fn link_dwarf_object<'a>(sess: &'a Session, executable_out_filename: &Path) { cmd.arg("-o"); cmd.arg(&dwp_out_filename); - let mut new_path = sess.host_filesearch(PathKind::All).get_tools_search_paths(false); + let mut new_path = sess.get_tools_search_paths(false); if let Some(path) = env::var_os("PATH") { new_path.extend(env::split_paths(&path)); } @@ -2555,8 +2555,7 @@ fn add_gcc_ld_path(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) { match ld_impl { LdImpl::Lld => { if sess.target.lld_flavor == LldFlavor::Ld64 { - let tools_path = - sess.host_filesearch(PathKind::All).get_tools_search_paths(false); + let tools_path = sess.get_tools_search_paths(false); let ld64_exe = tools_path .into_iter() .map(|p| p.join("gcc-ld")) @@ -2571,8 +2570,7 @@ fn add_gcc_ld_path(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) { arg }); } else { - let tools_path = - sess.host_filesearch(PathKind::All).get_tools_search_paths(false); + let tools_path = sess.get_tools_search_paths(false); let lld_path = tools_path .into_iter() .map(|p| p.join("gcc-ld")) diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs index 9e1c6a169f152..e3b0eea0d89c7 100644 --- a/compiler/rustc_codegen_ssa/src/back/linker.rs +++ b/compiler/rustc_codegen_ssa/src/back/linker.rs @@ -15,7 +15,6 @@ use rustc_middle::middle::dependency_format::Linkage; use rustc_middle::ty::TyCtxt; use rustc_serialize::{json, Encoder}; use rustc_session::config::{self, CrateType, DebugInfo, LinkerPluginLto, Lto, OptLevel, Strip}; -use rustc_session::search_paths::PathKind; use rustc_session::Session; use rustc_span::symbol::Symbol; use rustc_target::spec::{LinkOutputKind, LinkerFlavor, LldFlavor}; @@ -101,7 +100,7 @@ pub fn get_linker<'a>( // The compiler's sysroot often has some bundled tools, so add it to the // PATH for the child. - let mut new_path = sess.host_filesearch(PathKind::All).get_tools_search_paths(self_contained); + let mut new_path = sess.get_tools_search_paths(self_contained); let mut msvc_changed_path = false; if sess.target.is_like_msvc { if let Some(ref tool) = msvc_tool { diff --git a/compiler/rustc_driver/src/lib.rs b/compiler/rustc_driver/src/lib.rs index 53053327d0dab..4c6a2baaef1e5 100644 --- a/compiler/rustc_driver/src/lib.rs +++ b/compiler/rustc_driver/src/lib.rs @@ -677,10 +677,7 @@ impl RustcDefaultCalls { println!("{}", targets.join("\n")); } Sysroot => println!("{}", sess.sysroot.display()), - TargetLibdir => println!( - "{}", - sess.target_tlib_path.as_ref().unwrap_or(&sess.host_tlib_path).dir.display() - ), + TargetLibdir => println!("{}", sess.target_tlib_path.dir.display()), TargetSpec => println!("{}", sess.target.to_json().pretty()), FileNames | CrateName => { let input = input.unwrap_or_else(|| { diff --git a/compiler/rustc_session/src/filesearch.rs b/compiler/rustc_session/src/filesearch.rs index 6fe6a555f1af8..9359a55e55a9c 100644 --- a/compiler/rustc_session/src/filesearch.rs +++ b/compiler/rustc_session/src/filesearch.rs @@ -1,3 +1,5 @@ +//! A module for searching for libraries + pub use self::FileMatch::*; use std::env; @@ -14,8 +16,6 @@ pub enum FileMatch { FileDoesntMatch, } -// A module for searching for libraries - #[derive(Clone)] pub struct FileSearch<'a> { sysroot: &'a Path, @@ -83,22 +83,10 @@ impl<'a> FileSearch<'a> { FileSearch { sysroot, triple, search_paths, tlib_path, kind } } - // Returns just the directories within the search paths. + /// Returns just the directories within the search paths. pub fn search_path_dirs(&self) -> Vec { self.search_paths().map(|sp| sp.dir.to_path_buf()).collect() } - - // Returns a list of directories where target-specific tool binaries are located. - pub fn get_tools_search_paths(&self, self_contained: bool) -> Vec { - let rustlib_path = rustc_target::target_rustlib_path(self.sysroot, &self.triple); - let p = std::array::IntoIter::new([ - Path::new(&self.sysroot), - Path::new(&rustlib_path), - Path::new("bin"), - ]) - .collect::(); - if self_contained { vec![p.clone(), p.join("self-contained")] } else { vec![p] } - } } pub fn make_target_lib_path(sysroot: &Path, target_triple: &str) -> PathBuf { @@ -107,8 +95,8 @@ pub fn make_target_lib_path(sysroot: &Path, target_triple: &str) -> PathBuf { .collect::() } -// This function checks if sysroot is found using env::args().next(), and if it -// is not found, uses env::current_exe() to imply sysroot. +/// This function checks if sysroot is found using env::args().next(), and if it +/// is not found, uses env::current_exe() to imply sysroot. pub fn get_or_default_sysroot() -> PathBuf { // Follow symlinks. If the resolved path is relative, make it absolute. fn canonicalize(path: PathBuf) -> PathBuf { diff --git a/compiler/rustc_session/src/search_paths.rs b/compiler/rustc_session/src/search_paths.rs index 83b737a73b1e8..acb6c735e051e 100644 --- a/compiler/rustc_session/src/search_paths.rs +++ b/compiler/rustc_session/src/search_paths.rs @@ -9,17 +9,17 @@ pub struct SearchPath { pub files: Vec, } -// The obvious implementation of `SearchPath::files` is a `Vec`. But -// it is searched repeatedly by `find_library_crate`, and the searches involve -// checking the prefix and suffix of the filename of each `PathBuf`. This is -// doable, but very slow, because it involves calls to `file_name` and -// `extension` that are themselves slow. -// -// This type augments the `PathBuf` with an `Option` containing the -// `PathBuf`'s filename. The prefix and suffix checking is much faster on the -// `Option` than the `PathBuf`. (It's an `Option` because -// `Path::file_name` can fail; if that happens then all subsequent checking -// will also fail, which is fine.) +/// The obvious implementation of `SearchPath::files` is a `Vec`. But +/// it is searched repeatedly by `find_library_crate`, and the searches involve +/// checking the prefix and suffix of the filename of each `PathBuf`. This is +/// doable, but very slow, because it involves calls to `file_name` and +/// `extension` that are themselves slow. +/// +/// This type augments the `PathBuf` with an `Option` containing the +/// `PathBuf`'s filename. The prefix and suffix checking is much faster on the +/// `Option` than the `PathBuf`. (It's an `Option` because +/// `Path::file_name` can fail; if that happens then all subsequent checking +/// will also fail, which is fine.) #[derive(Clone, Debug)] pub struct SearchPathFile { pub path: PathBuf, diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 4471e1e0ae8b4..d6f4a3ae4f121 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -36,7 +36,7 @@ use std::fmt; use std::io::Write; use std::num::NonZeroU32; use std::ops::{Div, Mul}; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; use std::str::FromStr; use std::sync::Arc; use std::time::Duration; @@ -131,9 +131,8 @@ pub struct Session { pub target: Target, pub host: Target, pub opts: config::Options, - pub host_tlib_path: SearchPath, - /// `None` if the host and target are the same. - pub target_tlib_path: Option, + pub host_tlib_path: Lrc, + pub target_tlib_path: Lrc, pub parse_sess: ParseSess, pub sysroot: PathBuf, /// The name of the root source file of the crate, in the local file system. @@ -787,8 +786,7 @@ impl Session { &self.sysroot, self.opts.target_triple.triple(), &self.opts.search_paths, - // `target_tlib_path == None` means it's the same as `host_tlib_path`. - self.target_tlib_path.as_ref().unwrap_or(&self.host_tlib_path), + &self.target_tlib_path, kind, ) } @@ -802,6 +800,18 @@ impl Session { ) } + /// Returns a list of directories where target-specific tool binaries are located. + pub fn get_tools_search_paths(&self, self_contained: bool) -> Vec { + let rustlib_path = rustc_target::target_rustlib_path(&self.sysroot, &config::host_triple()); + let p = std::array::IntoIter::new([ + Path::new(&self.sysroot), + Path::new(&rustlib_path), + Path::new("bin"), + ]) + .collect::(); + if self_contained { vec![p.clone(), p.join("self-contained")] } else { vec![p] } + } + pub fn init_incr_comp_session( &self, session_dir: PathBuf, @@ -1245,11 +1255,13 @@ pub fn build_session( let host_triple = config::host_triple(); let target_triple = sopts.target_triple.triple(); - let host_tlib_path = SearchPath::from_sysroot_and_triple(&sysroot, host_triple); + let host_tlib_path = Lrc::new(SearchPath::from_sysroot_and_triple(&sysroot, host_triple)); let target_tlib_path = if host_triple == target_triple { - None + // Use the same `SearchPath` if host and target triple are identical to avoid unnecessary + // rescanning of the target lib path and an unnecessary allocation. + host_tlib_path.clone() } else { - Some(SearchPath::from_sysroot_and_triple(&sysroot, target_triple)) + Lrc::new(SearchPath::from_sysroot_and_triple(&sysroot, target_triple)) }; let file_path_mapping = sopts.file_path_mapping();