Skip to content

Commit d32dc80

Browse files
committed
Auto merge of rust-lang#88559 - bjorn3:archive_logic_dedup, r=cjgillot
Move add_rlib and add_native_library to cg_ssa This deduplicates logic between codegen backends. cc `@antoyo` and `@khyperia` for cg_gcc and rust-gpu.
2 parents 0961e68 + 977f279 commit d32dc80

File tree

4 files changed

+84
-163
lines changed

4 files changed

+84
-163
lines changed

compiler/rustc_codegen_cranelift/src/archive.rs

+19-64
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@ use std::collections::BTreeMap;
44
use std::fs::File;
55
use std::path::{Path, PathBuf};
66

7-
use rustc_codegen_ssa::back::archive::{find_library, ArchiveBuilder};
8-
use rustc_codegen_ssa::METADATA_FILENAME;
7+
use rustc_codegen_ssa::back::archive::ArchiveBuilder;
98
use rustc_session::Session;
109

1110
use object::{Object, ObjectSymbol, SymbolKind};
@@ -19,7 +18,6 @@ enum ArchiveEntry {
1918
pub(crate) struct ArArchiveBuilder<'a> {
2019
sess: &'a Session,
2120
dst: PathBuf,
22-
lib_search_paths: Vec<PathBuf>,
2321
use_gnu_style_archive: bool,
2422
no_builtin_ranlib: bool,
2523

@@ -31,8 +29,6 @@ pub(crate) struct ArArchiveBuilder<'a> {
3129

3230
impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {
3331
fn new(sess: &'a Session, output: &Path, input: Option<&Path>) -> Self {
34-
use rustc_codegen_ssa::back::link::archive_search_paths;
35-
3632
let (src_archives, entries) = if let Some(input) = input {
3733
let mut archive = ar::Archive::new(File::open(input).unwrap());
3834
let mut entries = Vec::new();
@@ -55,7 +51,6 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {
5551
ArArchiveBuilder {
5652
sess,
5753
dst: output.to_path_buf(),
58-
lib_search_paths: archive_search_paths(sess),
5954
use_gnu_style_archive: sess.target.archive_format == "gnu",
6055
// FIXME fix builtin ranlib on macOS
6156
no_builtin_ranlib: sess.target.is_like_osx,
@@ -85,42 +80,27 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {
8580
));
8681
}
8782

88-
fn add_native_library(&mut self, name: rustc_span::symbol::Symbol, verbatim: bool) {
89-
let location = find_library(name, verbatim, &self.lib_search_paths, self.sess);
90-
self.add_archive(location.clone(), |_| false).unwrap_or_else(|e| {
91-
panic!("failed to add native library {}: {}", location.to_string_lossy(), e);
92-
});
93-
}
94-
95-
fn add_rlib(
96-
&mut self,
97-
rlib: &Path,
98-
name: &str,
99-
lto: bool,
100-
skip_objects: bool,
101-
) -> std::io::Result<()> {
102-
let obj_start = name.to_owned();
103-
104-
self.add_archive(rlib.to_owned(), move |fname: &str| {
105-
// Ignore metadata files, no matter the name.
106-
if fname == METADATA_FILENAME {
107-
return true;
108-
}
109-
110-
// Don't include Rust objects if LTO is enabled
111-
if lto && fname.starts_with(&obj_start) && fname.ends_with(".o") {
112-
return true;
113-
}
83+
fn add_archive<F>(&mut self, archive_path: &Path, mut skip: F) -> std::io::Result<()>
84+
where
85+
F: FnMut(&str) -> bool + 'static,
86+
{
87+
let mut archive = ar::Archive::new(std::fs::File::open(&archive_path)?);
88+
let archive_index = self.src_archives.len();
11489

115-
// Otherwise if this is *not* a rust object and we're skipping
116-
// objects then skip this file
117-
if skip_objects && (!fname.starts_with(&obj_start) || !fname.ends_with(".o")) {
118-
return true;
90+
let mut i = 0;
91+
while let Some(entry) = archive.next_entry() {
92+
let entry = entry?;
93+
let file_name = String::from_utf8(entry.header().identifier().to_vec())
94+
.map_err(|err| std::io::Error::new(std::io::ErrorKind::InvalidData, err))?;
95+
if !skip(&file_name) {
96+
self.entries
97+
.push((file_name, ArchiveEntry::FromArchive { archive_index, entry_index: i }));
11998
}
99+
i += 1;
100+
}
120101

121-
// ok, don't skip this
122-
false
123-
})
102+
self.src_archives.push((archive_path.to_owned(), archive));
103+
Ok(())
124104
}
125105

126106
fn update_symbols(&mut self) {}
@@ -264,28 +244,3 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {
264244
bug!("injecting dll imports is not supported");
265245
}
266246
}
267-
268-
impl<'a> ArArchiveBuilder<'a> {
269-
fn add_archive<F>(&mut self, archive_path: PathBuf, mut skip: F) -> std::io::Result<()>
270-
where
271-
F: FnMut(&str) -> bool + 'static,
272-
{
273-
let mut archive = ar::Archive::new(std::fs::File::open(&archive_path)?);
274-
let archive_index = self.src_archives.len();
275-
276-
let mut i = 0;
277-
while let Some(entry) = archive.next_entry() {
278-
let entry = entry?;
279-
let file_name = String::from_utf8(entry.header().identifier().to_vec())
280-
.map_err(|err| std::io::Error::new(std::io::ErrorKind::InvalidData, err))?;
281-
if !skip(&file_name) {
282-
self.entries
283-
.push((file_name, ArchiveEntry::FromArchive { archive_index, entry_index: i }));
284-
}
285-
i += 1;
286-
}
287-
288-
self.src_archives.push((archive_path, archive));
289-
Ok(())
290-
}
291-
}

compiler/rustc_codegen_llvm/src/back/archive.rs

+18-80
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,15 @@ use std::str;
99

1010
use crate::llvm::archive_ro::{ArchiveRO, Child};
1111
use crate::llvm::{self, ArchiveKind, LLVMMachineType, LLVMRustCOFFShortExport};
12-
use rustc_codegen_ssa::back::archive::{find_library, ArchiveBuilder};
13-
use rustc_codegen_ssa::{looks_like_rust_object_file, METADATA_FILENAME};
12+
use rustc_codegen_ssa::back::archive::ArchiveBuilder;
1413
use rustc_data_structures::temp_dir::MaybeTempDir;
1514
use rustc_middle::middle::cstore::{DllCallingConvention, DllImport};
1615
use rustc_session::Session;
17-
use rustc_span::symbol::Symbol;
1816

1917
struct ArchiveConfig<'a> {
2018
pub sess: &'a Session,
2119
pub dst: PathBuf,
2220
pub src: Option<PathBuf>,
23-
pub lib_search_paths: Vec<PathBuf>,
2421
}
2522

2623
/// Helper for adding many files to an archive.
@@ -54,13 +51,7 @@ fn is_relevant_child(c: &Child<'_>) -> bool {
5451
}
5552

5653
fn archive_config<'a>(sess: &'a Session, output: &Path, input: Option<&Path>) -> ArchiveConfig<'a> {
57-
use rustc_codegen_ssa::back::link::archive_search_paths;
58-
ArchiveConfig {
59-
sess,
60-
dst: output.to_path_buf(),
61-
src: input.map(|p| p.to_path_buf()),
62-
lib_search_paths: archive_search_paths(sess),
63-
}
54+
ArchiveConfig { sess, dst: output.to_path_buf(), src: input.map(|p| p.to_path_buf()) }
6455
}
6556

6657
/// Map machine type strings to values of LLVM's MachineTypes enum.
@@ -111,57 +102,23 @@ impl<'a> ArchiveBuilder<'a> for LlvmArchiveBuilder<'a> {
111102
.collect()
112103
}
113104

114-
/// Adds all of the contents of a native library to this archive. This will
115-
/// search in the relevant locations for a library named `name`.
116-
fn add_native_library(&mut self, name: Symbol, verbatim: bool) {
117-
let location =
118-
find_library(name, verbatim, &self.config.lib_search_paths, self.config.sess);
119-
self.add_archive(&location, |_| false).unwrap_or_else(|e| {
120-
self.config.sess.fatal(&format!(
121-
"failed to add native library {}: {}",
122-
location.to_string_lossy(),
123-
e
124-
));
105+
fn add_archive<F>(&mut self, archive: &Path, skip: F) -> io::Result<()>
106+
where
107+
F: FnMut(&str) -> bool + 'static,
108+
{
109+
let archive_ro = match ArchiveRO::open(archive) {
110+
Ok(ar) => ar,
111+
Err(e) => return Err(io::Error::new(io::ErrorKind::Other, e)),
112+
};
113+
if self.additions.iter().any(|ar| ar.path() == archive) {
114+
return Ok(());
115+
}
116+
self.additions.push(Addition::Archive {
117+
path: archive.to_path_buf(),
118+
archive: archive_ro,
119+
skip: Box::new(skip),
125120
});
126-
}
127-
128-
/// Adds all of the contents of the rlib at the specified path to this
129-
/// archive.
130-
///
131-
/// This ignores adding the bytecode from the rlib, and if LTO is enabled
132-
/// then the object file also isn't added.
133-
fn add_rlib(
134-
&mut self,
135-
rlib: &Path,
136-
name: &str,
137-
lto: bool,
138-
skip_objects: bool,
139-
) -> io::Result<()> {
140-
// Ignoring obj file starting with the crate name
141-
// as simple comparison is not enough - there
142-
// might be also an extra name suffix
143-
let obj_start = name.to_owned();
144-
145-
self.add_archive(rlib, move |fname: &str| {
146-
// Ignore metadata files, no matter the name.
147-
if fname == METADATA_FILENAME {
148-
return true;
149-
}
150-
151-
// Don't include Rust objects if LTO is enabled
152-
if lto && looks_like_rust_object_file(fname) {
153-
return true;
154-
}
155-
156-
// Otherwise if this is *not* a rust object and we're skipping
157-
// objects then skip this file
158-
if skip_objects && (!fname.starts_with(&obj_start) || !fname.ends_with(".o")) {
159-
return true;
160-
}
161-
162-
// ok, don't skip this
163-
false
164-
})
121+
Ok(())
165122
}
166123

167124
/// Adds an arbitrary file to this archive
@@ -270,25 +227,6 @@ impl<'a> LlvmArchiveBuilder<'a> {
270227
self.src_archive.as_ref().unwrap().as_ref()
271228
}
272229

273-
fn add_archive<F>(&mut self, archive: &Path, skip: F) -> io::Result<()>
274-
where
275-
F: FnMut(&str) -> bool + 'static,
276-
{
277-
let archive_ro = match ArchiveRO::open(archive) {
278-
Ok(ar) => ar,
279-
Err(e) => return Err(io::Error::new(io::ErrorKind::Other, e)),
280-
};
281-
if self.additions.iter().any(|ar| ar.path() == archive) {
282-
return Ok(());
283-
}
284-
self.additions.push(Addition::Archive {
285-
path: archive.to_path_buf(),
286-
archive: archive_ro,
287-
skip: Box::new(skip),
288-
});
289-
Ok(())
290-
}
291-
292230
fn llvm_archive_kind(&self) -> Result<ArchiveKind, &str> {
293231
let kind = &*self.config.sess.target.archive_format;
294232
kind.parse().map_err(|_| kind)

compiler/rustc_codegen_ssa/src/back/archive.rs

+4-9
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use rustc_span::symbol::Symbol;
66
use std::io;
77
use std::path::{Path, PathBuf};
88

9-
pub fn find_library(
9+
pub(super) fn find_library(
1010
name: Symbol,
1111
verbatim: bool,
1212
search_paths: &[PathBuf],
@@ -48,14 +48,9 @@ pub trait ArchiveBuilder<'a> {
4848
fn remove_file(&mut self, name: &str);
4949
fn src_files(&mut self) -> Vec<String>;
5050

51-
fn add_rlib(
52-
&mut self,
53-
path: &Path,
54-
name: &str,
55-
lto: bool,
56-
skip_objects: bool,
57-
) -> io::Result<()>;
58-
fn add_native_library(&mut self, name: Symbol, verbatim: bool);
51+
fn add_archive<F>(&mut self, archive: &Path, skip: F) -> io::Result<()>
52+
where
53+
F: FnMut(&str) -> bool + 'static;
5954
fn update_symbols(&mut self);
6055

6156
fn build(self);

compiler/rustc_codegen_ssa/src/back/link.rs

+43-10
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use rustc_target::spec::crt_objects::{CrtObjects, CrtObjectsFallback};
1919
use rustc_target::spec::{LinkOutputKind, LinkerFlavor, LldFlavor, SplitDebuginfo};
2020
use rustc_target::spec::{PanicStrategy, RelocModel, RelroLevel, SanitizerSet, Target};
2121

22-
use super::archive::ArchiveBuilder;
22+
use super::archive::{find_library, ArchiveBuilder};
2323
use super::command::Command;
2424
use super::linker::{self, Linker};
2525
use super::rpath::{self, RPathConfig};
@@ -230,6 +230,9 @@ fn link_rlib<'a, B: ArchiveBuilder<'a>>(
230230
tmpdir: &MaybeTempDir,
231231
) -> Result<B, ErrorReported> {
232232
info!("preparing rlib to {:?}", out_filename);
233+
234+
let lib_search_paths = archive_search_paths(sess);
235+
233236
let mut ab = <B as ArchiveBuilder>::new(sess, out_filename, None);
234237

235238
for obj in codegen_results.modules.iter().filter_map(|m| m.object.as_ref()) {
@@ -262,7 +265,15 @@ fn link_rlib<'a, B: ArchiveBuilder<'a>>(
262265
| NativeLibKind::Unspecified => continue,
263266
}
264267
if let Some(name) = lib.name {
265-
ab.add_native_library(name, lib.verbatim.unwrap_or(false));
268+
let location =
269+
find_library(name, lib.verbatim.unwrap_or(false), &lib_search_paths, sess);
270+
ab.add_archive(&location, |_| false).unwrap_or_else(|e| {
271+
sess.fatal(&format!(
272+
"failed to add native library {}: {}",
273+
location.to_string_lossy(),
274+
e
275+
));
276+
});
266277
}
267278
}
268279

@@ -541,13 +552,35 @@ fn link_staticlib<'a, B: ArchiveBuilder<'a>>(
541552
matches!(lib.kind, NativeLibKind::Static { bundle: None | Some(true), .. })
542553
&& !relevant_lib(sess, lib)
543554
});
544-
ab.add_rlib(
545-
path,
546-
&name.as_str(),
547-
are_upstream_rust_objects_already_included(sess)
548-
&& !ignored_for_lto(sess, &codegen_results.crate_info, cnum),
549-
skip_object_files,
550-
)
555+
556+
let lto = are_upstream_rust_objects_already_included(sess)
557+
&& !ignored_for_lto(sess, &codegen_results.crate_info, cnum);
558+
559+
// Ignoring obj file starting with the crate name
560+
// as simple comparison is not enough - there
561+
// might be also an extra name suffix
562+
let obj_start = name.as_str().to_owned();
563+
564+
ab.add_archive(path, move |fname: &str| {
565+
// Ignore metadata files, no matter the name.
566+
if fname == METADATA_FILENAME {
567+
return true;
568+
}
569+
570+
// Don't include Rust objects if LTO is enabled
571+
if lto && looks_like_rust_object_file(fname) {
572+
return true;
573+
}
574+
575+
// Otherwise if this is *not* a rust object and we're skipping
576+
// objects then skip this file
577+
if skip_object_files && (!fname.starts_with(&obj_start) || !fname.ends_with(".o")) {
578+
return true;
579+
}
580+
581+
// ok, don't skip this
582+
false
583+
})
551584
.unwrap();
552585

553586
all_native_libs.extend(codegen_results.crate_info.native_libraries[&cnum].iter().cloned());
@@ -1218,7 +1251,7 @@ fn preserve_objects_for_their_debuginfo(sess: &Session) -> bool {
12181251
sess.split_debuginfo() == SplitDebuginfo::Unpacked
12191252
}
12201253

1221-
pub fn archive_search_paths(sess: &Session) -> Vec<PathBuf> {
1254+
fn archive_search_paths(sess: &Session) -> Vec<PathBuf> {
12221255
sess.target_filesearch(PathKind::Native).search_path_dirs()
12231256
}
12241257

0 commit comments

Comments
 (0)