Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Overhaul FileSearch and SearchPaths #56090

Merged
merged 6 commits into from
Dec 13, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/bootstrap/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -684,6 +684,11 @@ impl<'a> Builder<'a> {
.env("RUSTDOC_REAL", self.rustdoc(host))
.env("RUSTDOC_CRATE_VERSION", self.rust_version())
.env("RUSTC_BOOTSTRAP", "1");

// Remove make-related flags that can cause jobserver problems.
cmd.env_remove("MAKEFLAGS");
cmd.env_remove("MFLAGS");

if let Some(linker) = self.linker(host) {
cmd.env("RUSTC_TARGET_LINKER", linker);
}
Expand Down
51 changes: 26 additions & 25 deletions src/librustc/session/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
use std::str::FromStr;

use session::{early_error, early_warn, Session};
use session::search_paths::SearchPaths;
use session::search_paths::SearchPath;

use rustc_target::spec::{LinkerFlavor, PanicStrategy, RelroLevel};
use rustc_target::spec::{Target, TargetTriple};
Expand Down Expand Up @@ -374,7 +374,7 @@ top_level_options!(
lint_cap: Option<lint::Level> [TRACKED],
describe_lints: bool [UNTRACKED],
output_types: OutputTypes [TRACKED],
search_paths: SearchPaths [UNTRACKED],
search_paths: Vec<SearchPath> [UNTRACKED],
libs: Vec<(String, Option<String>, Option<cstore::NativeLibraryKind>)> [TRACKED],
maybe_sysroot: Option<PathBuf> [TRACKED],

Expand Down Expand Up @@ -593,7 +593,7 @@ impl Default for Options {
lint_cap: None,
describe_lints: false,
output_types: OutputTypes(BTreeMap::new()),
search_paths: SearchPaths::new(),
search_paths: vec![],
maybe_sysroot: None,
target_triple: TargetTriple::from_triple(host_triple()),
test: false,
Expand Down Expand Up @@ -2115,9 +2115,9 @@ pub fn build_session_options_and_crate_config(
}
};

let mut search_paths = SearchPaths::new();
let mut search_paths = vec![];
for s in &matches.opt_strs("L") {
search_paths.add_path(&s[..], error_format);
search_paths.push(SearchPath::from_cli_opt(&s[..], error_format));
}

let libs = matches
Expand Down Expand Up @@ -2535,6 +2535,7 @@ mod tests {
use session::config::{build_configuration, build_session_options_and_crate_config};
use session::config::{LtoCli, CrossLangLto};
use session::build_session;
use session::search_paths::SearchPath;
use std::collections::{BTreeMap, BTreeSet};
use std::iter::FromIterator;
use std::path::PathBuf;
Expand Down Expand Up @@ -2790,48 +2791,48 @@ mod tests {

// Reference
v1.search_paths
.add_path("native=abc", super::ErrorOutputType::Json(false));
.push(SearchPath::from_cli_opt("native=abc", super::ErrorOutputType::Json(false)));
v1.search_paths
.add_path("crate=def", super::ErrorOutputType::Json(false));
.push(SearchPath::from_cli_opt("crate=def", super::ErrorOutputType::Json(false)));
v1.search_paths
.add_path("dependency=ghi", super::ErrorOutputType::Json(false));
.push(SearchPath::from_cli_opt("dependency=ghi", super::ErrorOutputType::Json(false)));
v1.search_paths
.add_path("framework=jkl", super::ErrorOutputType::Json(false));
.push(SearchPath::from_cli_opt("framework=jkl", super::ErrorOutputType::Json(false)));
v1.search_paths
.add_path("all=mno", super::ErrorOutputType::Json(false));
.push(SearchPath::from_cli_opt("all=mno", super::ErrorOutputType::Json(false)));

v2.search_paths
.add_path("native=abc", super::ErrorOutputType::Json(false));
.push(SearchPath::from_cli_opt("native=abc", super::ErrorOutputType::Json(false)));
v2.search_paths
.add_path("dependency=ghi", super::ErrorOutputType::Json(false));
.push(SearchPath::from_cli_opt("dependency=ghi", super::ErrorOutputType::Json(false)));
v2.search_paths
.add_path("crate=def", super::ErrorOutputType::Json(false));
.push(SearchPath::from_cli_opt("crate=def", super::ErrorOutputType::Json(false)));
v2.search_paths
.add_path("framework=jkl", super::ErrorOutputType::Json(false));
.push(SearchPath::from_cli_opt("framework=jkl", super::ErrorOutputType::Json(false)));
v2.search_paths
.add_path("all=mno", super::ErrorOutputType::Json(false));
.push(SearchPath::from_cli_opt("all=mno", super::ErrorOutputType::Json(false)));

v3.search_paths
.add_path("crate=def", super::ErrorOutputType::Json(false));
.push(SearchPath::from_cli_opt("crate=def", super::ErrorOutputType::Json(false)));
v3.search_paths
.add_path("framework=jkl", super::ErrorOutputType::Json(false));
.push(SearchPath::from_cli_opt("framework=jkl", super::ErrorOutputType::Json(false)));
v3.search_paths
.add_path("native=abc", super::ErrorOutputType::Json(false));
.push(SearchPath::from_cli_opt("native=abc", super::ErrorOutputType::Json(false)));
v3.search_paths
.add_path("dependency=ghi", super::ErrorOutputType::Json(false));
.push(SearchPath::from_cli_opt("dependency=ghi", super::ErrorOutputType::Json(false)));
v3.search_paths
.add_path("all=mno", super::ErrorOutputType::Json(false));
.push(SearchPath::from_cli_opt("all=mno", super::ErrorOutputType::Json(false)));

v4.search_paths
.add_path("all=mno", super::ErrorOutputType::Json(false));
.push(SearchPath::from_cli_opt("all=mno", super::ErrorOutputType::Json(false)));
v4.search_paths
.add_path("native=abc", super::ErrorOutputType::Json(false));
.push(SearchPath::from_cli_opt("native=abc", super::ErrorOutputType::Json(false)));
v4.search_paths
.add_path("crate=def", super::ErrorOutputType::Json(false));
.push(SearchPath::from_cli_opt("crate=def", super::ErrorOutputType::Json(false)));
v4.search_paths
.add_path("dependency=ghi", super::ErrorOutputType::Json(false));
.push(SearchPath::from_cli_opt("dependency=ghi", super::ErrorOutputType::Json(false)));
v4.search_paths
.add_path("framework=jkl", super::ErrorOutputType::Json(false));
.push(SearchPath::from_cli_opt("framework=jkl", super::ErrorOutputType::Json(false)));

assert!(v1.dep_tracking_hash() == v2.dep_tracking_hash());
assert!(v1.dep_tracking_hash() == v3.dep_tracking_hash());
Expand Down
77 changes: 29 additions & 48 deletions src/librustc/session/filesearch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,12 @@

pub use self::FileMatch::*;

use rustc_data_structures::fx::FxHashSet;
use std::borrow::Cow;
use std::env;
use std::fs;
use std::path::{Path, PathBuf};

use session::search_paths::{SearchPaths, PathKind};
use session::search_paths::{SearchPath, PathKind};
use rustc_fs_util::fix_windows_verbatim_for_gcc;

#[derive(Copy, Clone)]
Expand All @@ -30,31 +29,19 @@ pub enum FileMatch {
// A module for searching for libraries

pub struct FileSearch<'a> {
pub sysroot: &'a Path,
pub search_paths: &'a SearchPaths,
pub triple: &'a str,
pub kind: PathKind,
sysroot: &'a Path,
triple: &'a str,
search_paths: &'a [SearchPath],
tlib_path: &'a SearchPath,
kind: PathKind,
}

impl<'a> FileSearch<'a> {
pub fn for_each_lib_search_path<F>(&self, mut f: F) where
F: FnMut(&Path, PathKind)
{
let mut visited_dirs = FxHashSet::default();
visited_dirs.reserve(self.search_paths.paths.len() + 1);
for (path, kind) in self.search_paths.iter(self.kind) {
f(path, kind);
visited_dirs.insert(path.to_path_buf());
}

debug!("filesearch: searching lib path");
let tlib_path = make_target_lib_path(self.sysroot,
self.triple);
if !visited_dirs.contains(&tlib_path) {
f(&tlib_path, PathKind::All);
}

visited_dirs.insert(tlib_path);
pub fn search_paths(&self) -> impl Iterator<Item = &'a SearchPath> {
let kind = self.kind;
self.search_paths.iter()
.filter(move |sp| sp.kind.matches(kind))
.chain(std::iter::once(self.tlib_path))
}

pub fn get_lib_path(&self) -> PathBuf {
Expand All @@ -64,26 +51,20 @@ impl<'a> FileSearch<'a> {
pub fn search<F>(&self, mut pick: F)
where F: FnMut(&Path, PathKind) -> FileMatch
{
self.for_each_lib_search_path(|lib_search_path, kind| {
debug!("searching {}", lib_search_path.display());
let files = match fs::read_dir(lib_search_path) {
Ok(files) => files,
Err(..) => return,
};
let files = files.filter_map(|p| p.ok().map(|s| s.path()))
.collect::<Vec<_>>();
for search_path in self.search_paths() {
debug!("searching {}", search_path.dir.display());
fn is_rlib(p: &Path) -> bool {
p.extension() == Some("rlib".as_ref())
}
// Reading metadata out of rlibs is faster, and if we find both
// an rlib and a dylib we only read one of the files of
// metadata, so in the name of speed, bring all rlib files to
// the front of the search list.
let files1 = files.iter().filter(|p| is_rlib(p));
let files2 = files.iter().filter(|p| !is_rlib(p));
let files1 = search_path.files.iter().filter(|p| is_rlib(p));
let files2 = search_path.files.iter().filter(|p| !is_rlib(p));
for path in files1.chain(files2) {
debug!("testing {}", path.display());
let maybe_picked = pick(path, kind);
let maybe_picked = pick(path, search_path.kind);
match maybe_picked {
FileMatches => {
debug!("picked {}", path.display());
Expand All @@ -93,29 +74,30 @@ impl<'a> FileSearch<'a> {
}
}
}
});
}
}

pub fn new(sysroot: &'a Path,
triple: &'a str,
search_paths: &'a SearchPaths,
kind: PathKind) -> FileSearch<'a> {
search_paths: &'a Vec<SearchPath>,
tlib_path: &'a SearchPath,
kind: PathKind)
-> FileSearch<'a> {
debug!("using sysroot = {}, triple = {}", sysroot.display(), triple);
FileSearch {
sysroot,
search_paths,
triple,
search_paths,
tlib_path,
kind,
}
}

// Returns a list of directories where target-specific dylibs might be located.
pub fn get_dylib_search_paths(&self) -> Vec<PathBuf> {
let mut paths = Vec::new();
self.for_each_lib_search_path(|lib_search_path, _| {
paths.push(lib_search_path.to_path_buf());
});
paths
// Returns just the directories within the search paths.
pub fn search_path_dirs(&self) -> Vec<PathBuf> {
self.search_paths()
.map(|sp| sp.dir.to_path_buf())
.collect()
nnethercote marked this conversation as resolved.
Show resolved Hide resolved
}

// Returns a list of directories where target-specific tool binaries are located.
Expand All @@ -138,8 +120,7 @@ pub fn relative_target_lib_path(sysroot: &Path, target_triple: &str) -> PathBuf
p
}

fn make_target_lib_path(sysroot: &Path,
target_triple: &str) -> PathBuf {
pub fn make_target_lib_path(sysroot: &Path, target_triple: &str) -> PathBuf {
sysroot.join(&relative_target_lib_path(sysroot, target_triple))
}

Expand Down
43 changes: 26 additions & 17 deletions src/librustc/session/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ use lint;
use lint::builtin::BuiltinLintDiagnostics;
use middle::allocator::AllocatorKind;
use middle::dependency_format;
use session::search_paths::PathKind;
use session::config::{OutputType, Lto};
use session::search_paths::{PathKind, SearchPath};
use util::nodemap::{FxHashMap, FxHashSet};
use util::common::{duration_to_secs_str, ErrorReported};
use util::common::ProfileQueriesMsg;
Expand Down Expand Up @@ -48,7 +48,7 @@ use std::cell::{self, Cell, RefCell};
use std::env;
use std::fmt;
use std::io::Write;
use std::path::{Path, PathBuf};
use std::path::PathBuf;
use std::time::Duration;
use std::sync::mpsc;
use std::sync::atomic::{AtomicUsize, Ordering};
Expand All @@ -64,12 +64,15 @@ pub struct Session {
pub target: config::Config,
pub host: Target,
pub opts: config::Options,
pub host_tlib_path: SearchPath,
/// This is `None` if the host and target are the same.
pub target_tlib_path: Option<SearchPath>,
pub parse_sess: ParseSess,
/// For a library crate, this is always none
pub entry_fn: Once<Option<(NodeId, Span, config::EntryFnType)>>,
pub plugin_registrar_fn: Once<Option<ast::NodeId>>,
pub proc_macro_decls_static: Once<Option<ast::NodeId>>,
pub default_sysroot: Option<PathBuf>,
pub sysroot: PathBuf,
nnethercote marked this conversation as resolved.
Show resolved Hide resolved
/// The name of the root source file of the crate, in the local file system.
/// `None` means that there is no source file.
pub local_crate_source_file: Option<PathBuf>,
Expand Down Expand Up @@ -694,27 +697,22 @@ impl Session {
)
}

pub fn sysroot<'a>(&'a self) -> &'a Path {
match self.opts.maybe_sysroot {
Some(ref sysroot) => sysroot,
None => self.default_sysroot
.as_ref()
.expect("missing sysroot and default_sysroot in Session"),
}
}
pub fn target_filesearch(&self, kind: PathKind) -> filesearch::FileSearch<'_> {
filesearch::FileSearch::new(
self.sysroot(),
&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),
kind,
)
}
pub fn host_filesearch(&self, kind: PathKind) -> filesearch::FileSearch<'_> {
filesearch::FileSearch::new(
self.sysroot(),
&self.sysroot,
config::host_triple(),
&self.opts.search_paths,
&self.host_tlib_path,
kind,
)
}
Expand Down Expand Up @@ -1109,9 +1107,18 @@ pub fn build_session_(
let target_cfg = config::build_target_config(&sopts, &span_diagnostic);

let p_s = parse::ParseSess::with_span_handler(span_diagnostic, source_map);
let default_sysroot = match sopts.maybe_sysroot {
Some(_) => None,
None => Some(filesearch::get_or_default_sysroot()),
let sysroot = match &sopts.maybe_sysroot {
Some(sysroot) => sysroot.clone(),
None => filesearch::get_or_default_sysroot(),
};

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 target_tlib_path = if host_triple == target_triple {
None
} else {
Some(SearchPath::from_sysroot_and_triple(&sysroot, target_triple))
};

let file_path_mapping = sopts.file_path_mapping();
Expand Down Expand Up @@ -1142,12 +1149,14 @@ pub fn build_session_(
target: target_cfg,
host,
opts: sopts,
host_tlib_path,
target_tlib_path,
parse_sess: p_s,
// For a library crate, this is always none
entry_fn: Once::new(),
plugin_registrar_fn: Once::new(),
proc_macro_decls_static: Once::new(),
default_sysroot,
sysroot,
local_crate_source_file,
working_dir,
lint_store: RwLock::new(lint::LintStore::new()),
Expand Down
Loading