Skip to content

Commit 5fc49b6

Browse files
authored
Unrolled build for #160449
Rollup merge of #160449 - Kobzol:filesearch-lookup-fix, r=petrochenkov Fix lookup of object files I broke this in #158823. I wanted to optimize the potentially O(n^2) object file lookup, but didn't realize that we have to search all search paths here, not only files that we already prefiltered for the lib prefixes. r? @petrochenkov Fixes: #160446
2 parents c9ff496 + 07e1398 commit 5fc49b6

3 files changed

Lines changed: 17 additions & 7 deletions

File tree

compiler/rustc_codegen_ssa/src/back/link.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
mod raw_dylib;
22

33
use std::collections::BTreeSet;
4-
use std::ffi::{OsStr, OsString};
4+
use std::ffi::OsString;
55
use std::fs::{File, OpenOptions, read};
66
use std::io::{BufReader, BufWriter, Write};
77
use std::ops::{ControlFlow, Deref};
@@ -2061,9 +2061,12 @@ fn get_object_file_path(sess: &Session, name: &str, self_contained: bool) -> Pat
20612061
}
20622062
}
20632063

2064-
for (_, path) in sess.target_filesearch().get_file_candidates(name, "", PathKind::Native) {
2065-
if path.file_name().map_or(false, |n| n == OsStr::new(name)) && path.exists() {
2066-
return path;
2064+
// Note: this is O(n^2), it could be expensive-ish if we lookup many object files for many
2065+
// search paths
2066+
for search_path in sess.target_filesearch().search_paths(PathKind::Native) {
2067+
let file_path = search_path.dir.join(name);
2068+
if file_path.exists() {
2069+
return file_path;
20672070
}
20682071
}
20692072
PathBuf::from(name)

compiler/rustc_metadata/src/locator.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -434,7 +434,7 @@ impl<'a> CrateLocator<'a> {
434434
}
435435

436436
for (hash, spf_path) in
437-
self.filesearch.get_file_candidates(prefix, suffix, self.path_kind)
437+
self.filesearch.get_library_candidates(prefix, suffix, self.path_kind)
438438
{
439439
info!("lib candidate: {}", spf_path.display());
440440

@@ -462,7 +462,7 @@ impl<'a> CrateLocator<'a> {
462462
}
463463

464464
if should_check_staticlibs {
465-
for (_, path) in self.filesearch.get_file_candidates(
465+
for (_, path) in self.filesearch.get_library_candidates(
466466
staticlib_prefix,
467467
staticlib_suffix,
468468
self.path_kind,

compiler/rustc_session/src/filesearch.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,11 @@ impl FileSearch {
3535

3636
/// Return files from the search dirs of this filesearch that match the given `prefix` and
3737
/// `suffix` and have the given `kind`.
38-
pub fn get_file_candidates<'b>(
38+
///
39+
/// Note that this function only searches files that match lib/staticlib/dlllib prefixes, not
40+
/// all files from the search paths!
41+
/// Access `search_paths` directly if you want to scan all files within them.
42+
pub fn get_library_candidates<'b>(
3943
&'b self,
4044
prefix: &'b str,
4145
suffix: &'b str,
@@ -65,6 +69,9 @@ impl FileSearch {
6569
target: &Target,
6670
use_implicit_sysroot_deps: bool,
6771
) -> Self {
72+
// We keep a list of all found paths that look like libraries in `FileSearch`, to optimize
73+
// lookup in `get_library_candidates`.
74+
// These prefixes should be kept in sync with `CrateLocator::find_library_crate`.
6875
let prefixes = ["lib", &target.staticlib_prefix, &target.dll_prefix];
6976

7077
// Load all files from all search paths, filter them by supported prefixes, and sort them,

0 commit comments

Comments
 (0)