linker: Avoid some allocations in search directory iteration
This commit is contained in:
parent
aa6a697a1c
commit
4ded0b82ca
@ -56,8 +56,13 @@
|
|||||||
pub struct SearchPaths(OnceCell<Vec<PathBuf>>);
|
pub struct SearchPaths(OnceCell<Vec<PathBuf>>);
|
||||||
|
|
||||||
impl SearchPaths {
|
impl SearchPaths {
|
||||||
pub(super) fn get(&self, sess: &Session) -> &[PathBuf] {
|
pub(super) fn get(&self, sess: &Session) -> impl Iterator<Item = &Path> {
|
||||||
self.0.get_or_init(|| archive_search_paths(sess))
|
let native_search_paths = || {
|
||||||
|
Vec::from_iter(
|
||||||
|
sess.target_filesearch(PathKind::Native).search_path_dirs().map(|p| p.to_owned()),
|
||||||
|
)
|
||||||
|
};
|
||||||
|
self.0.get_or_init(native_search_paths).iter().map(|p| &**p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -310,8 +315,6 @@ fn link_rlib<'a>(
|
|||||||
flavor: RlibFlavor,
|
flavor: RlibFlavor,
|
||||||
tmpdir: &MaybeTempDir,
|
tmpdir: &MaybeTempDir,
|
||||||
) -> Result<Box<dyn ArchiveBuilder + 'a>, ErrorGuaranteed> {
|
) -> Result<Box<dyn ArchiveBuilder + 'a>, ErrorGuaranteed> {
|
||||||
let lib_search_paths = archive_search_paths(sess);
|
|
||||||
|
|
||||||
let mut ab = archive_builder_builder.new_archive_builder(sess);
|
let mut ab = archive_builder_builder.new_archive_builder(sess);
|
||||||
|
|
||||||
let trailing_metadata = match flavor {
|
let trailing_metadata = match flavor {
|
||||||
@ -378,26 +381,24 @@ fn link_rlib<'a>(
|
|||||||
// feature then we'll need to figure out how to record what objects were
|
// feature then we'll need to figure out how to record what objects were
|
||||||
// loaded from the libraries found here and then encode that into the
|
// loaded from the libraries found here and then encode that into the
|
||||||
// metadata of the rlib we're generating somehow.
|
// metadata of the rlib we're generating somehow.
|
||||||
|
let search_paths = SearchPaths::default();
|
||||||
for lib in codegen_results.crate_info.used_libraries.iter() {
|
for lib in codegen_results.crate_info.used_libraries.iter() {
|
||||||
let NativeLibKind::Static { bundle: None | Some(true), .. } = lib.kind else {
|
let NativeLibKind::Static { bundle: None | Some(true), .. } = lib.kind else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
let search_paths = search_paths.get(sess);
|
||||||
if flavor == RlibFlavor::Normal
|
if flavor == RlibFlavor::Normal
|
||||||
&& let Some(filename) = lib.filename
|
&& let Some(filename) = lib.filename
|
||||||
{
|
{
|
||||||
let path = find_native_static_library(filename.as_str(), true, &lib_search_paths, sess);
|
let path = find_native_static_library(filename.as_str(), true, search_paths, sess);
|
||||||
let src = read(path)
|
let src = read(path)
|
||||||
.map_err(|e| sess.dcx().emit_fatal(errors::ReadFileError { message: e }))?;
|
.map_err(|e| sess.dcx().emit_fatal(errors::ReadFileError { message: e }))?;
|
||||||
let (data, _) = create_wrapper_file(sess, ".bundled_lib".to_string(), &src);
|
let (data, _) = create_wrapper_file(sess, ".bundled_lib".to_string(), &src);
|
||||||
let wrapper_file = emit_wrapper_file(sess, &data, tmpdir, filename.as_str());
|
let wrapper_file = emit_wrapper_file(sess, &data, tmpdir, filename.as_str());
|
||||||
packed_bundled_libs.push(wrapper_file);
|
packed_bundled_libs.push(wrapper_file);
|
||||||
} else {
|
} else {
|
||||||
let path = find_native_static_library(
|
let path =
|
||||||
lib.name.as_str(),
|
find_native_static_library(lib.name.as_str(), lib.verbatim, search_paths, sess);
|
||||||
lib.verbatim,
|
|
||||||
&lib_search_paths,
|
|
||||||
sess,
|
|
||||||
);
|
|
||||||
ab.add_archive(&path, Box::new(|_| false)).unwrap_or_else(|error| {
|
ab.add_archive(&path, Box::new(|_| false)).unwrap_or_else(|error| {
|
||||||
sess.dcx().emit_fatal(errors::AddNativeLibrary { library_path: path, error })
|
sess.dcx().emit_fatal(errors::AddNativeLibrary { library_path: path, error })
|
||||||
});
|
});
|
||||||
@ -1445,10 +1446,6 @@ fn preserve_objects_for_their_debuginfo(sess: &Session) -> (bool, bool) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn archive_search_paths(sess: &Session) -> Vec<PathBuf> {
|
|
||||||
sess.target_filesearch(PathKind::Native).search_path_dirs()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(PartialEq)]
|
#[derive(PartialEq)]
|
||||||
enum RlibFlavor {
|
enum RlibFlavor {
|
||||||
Normal,
|
Normal,
|
||||||
|
@ -170,7 +170,9 @@ fn configure_and_expand(
|
|||||||
let mut old_path = OsString::new();
|
let mut old_path = OsString::new();
|
||||||
if cfg!(windows) {
|
if cfg!(windows) {
|
||||||
old_path = env::var_os("PATH").unwrap_or(old_path);
|
old_path = env::var_os("PATH").unwrap_or(old_path);
|
||||||
let mut new_path = sess.host_filesearch(PathKind::All).search_path_dirs();
|
let mut new_path = Vec::from_iter(
|
||||||
|
sess.host_filesearch(PathKind::All).search_path_dirs().map(|p| p.to_owned()),
|
||||||
|
);
|
||||||
for path in env::split_paths(&old_path) {
|
for path in env::split_paths(&old_path) {
|
||||||
if !new_path.contains(&path) {
|
if !new_path.contains(&path) {
|
||||||
new_path.push(path);
|
new_path.push(path);
|
||||||
|
@ -17,12 +17,12 @@
|
|||||||
|
|
||||||
use crate::errors;
|
use crate::errors;
|
||||||
|
|
||||||
use std::path::PathBuf;
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
pub fn find_native_static_library(
|
pub fn find_native_static_library<'a>(
|
||||||
name: &str,
|
name: &str,
|
||||||
verbatim: bool,
|
verbatim: bool,
|
||||||
search_paths: &[PathBuf],
|
search_paths: impl Iterator<Item = &'a Path>,
|
||||||
sess: &Session,
|
sess: &Session,
|
||||||
) -> PathBuf {
|
) -> PathBuf {
|
||||||
let formats = if verbatim {
|
let formats = if verbatim {
|
||||||
@ -60,7 +60,7 @@ fn find_bundled_library(
|
|||||||
&& (sess.opts.unstable_opts.packed_bundled_libs || has_cfg || whole_archive == Some(true))
|
&& (sess.opts.unstable_opts.packed_bundled_libs || has_cfg || whole_archive == Some(true))
|
||||||
{
|
{
|
||||||
let verbatim = verbatim.unwrap_or(false);
|
let verbatim = verbatim.unwrap_or(false);
|
||||||
let search_paths = &sess.target_filesearch(PathKind::Native).search_path_dirs();
|
let search_paths = sess.target_filesearch(PathKind::Native).search_path_dirs();
|
||||||
return find_native_static_library(name.as_str(), verbatim, search_paths, sess)
|
return find_native_static_library(name.as_str(), verbatim, search_paths, sess)
|
||||||
.file_name()
|
.file_name()
|
||||||
.and_then(|s| s.to_str())
|
.and_then(|s| s.to_str())
|
||||||
|
@ -47,8 +47,8 @@ pub fn new(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns just the directories within the search paths.
|
/// Returns just the directories within the search paths.
|
||||||
pub fn search_path_dirs(&self) -> Vec<PathBuf> {
|
pub fn search_path_dirs(&self) -> impl Iterator<Item = &'a Path> {
|
||||||
self.search_paths().map(|sp| sp.dir.to_path_buf()).collect()
|
self.search_paths().map(|sp| &*sp.dir)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user