Skip to content

Commit 12224e8

Browse files
committed
Auto merge of #97485 - bjorn3:new_archive_writer, r=wesleywiser
Rewrite LLVM's archive writer in Rust This allows it to be used by other codegen backends. Fixes https://github.com/bjorn3/rustc_codegen_cranelift/issues/1155
2 parents f9805a2 + 690085c commit 12224e8

File tree

4 files changed

+8
-203
lines changed

4 files changed

+8
-203
lines changed

Cargo.lock

-14
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

-4
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,6 @@ gccjit = { git = "https://github.com/antoyo/gccjit.rs" }
2727
# Local copy.
2828
#gccjit = { path = "../gccjit.rs" }
2929

30-
target-lexicon = "0.10.0"
31-
32-
ar = "0.8.0"
33-
3430
[dev-dependencies]
3531
lang_tester = "0.3.9"
3632
tempfile = "3.1.0"

src/archive.rs

+6-171
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,17 @@
1-
use std::fs::File;
21
use std::path::{Path, PathBuf};
32

4-
use crate::errors::RanlibFailure;
5-
6-
use rustc_codegen_ssa::back::archive::{ArchiveBuilder, ArchiveBuilderBuilder};
3+
use rustc_codegen_ssa::back::archive::{
4+
get_native_object_symbols, ArArchiveBuilder, ArchiveBuilder, ArchiveBuilderBuilder,
5+
};
76
use rustc_session::Session;
87

98
use rustc_session::cstore::DllImport;
109

11-
struct ArchiveConfig<'a> {
12-
sess: &'a Session,
13-
use_native_ar: bool,
14-
use_gnu_style_archive: bool,
15-
}
16-
17-
#[derive(Debug)]
18-
enum ArchiveEntry {
19-
FromArchive {
20-
archive_index: usize,
21-
entry_index: usize,
22-
},
23-
File(PathBuf),
24-
}
25-
26-
pub struct ArArchiveBuilderBuilder;
10+
pub(crate) struct ArArchiveBuilderBuilder;
2711

2812
impl ArchiveBuilderBuilder for ArArchiveBuilderBuilder {
2913
fn new_archive_builder<'a>(&self, sess: &'a Session) -> Box<dyn ArchiveBuilder<'a> + 'a> {
30-
let config = ArchiveConfig {
31-
sess,
32-
use_native_ar: false,
33-
// FIXME test for linux and System V derivatives instead
34-
use_gnu_style_archive: sess.target.options.archive_format == "gnu",
35-
};
36-
37-
Box::new(ArArchiveBuilder {
38-
config,
39-
src_archives: vec![],
40-
entries: vec![],
41-
})
14+
Box::new(ArArchiveBuilder::new(sess, get_native_object_symbols))
4215
}
4316

4417
fn create_dll_import_lib(
@@ -49,144 +22,6 @@ impl ArchiveBuilderBuilder for ArArchiveBuilderBuilder {
4922
_tmpdir: &Path,
5023
_is_direct_dependency: bool,
5124
) -> PathBuf {
52-
unimplemented!();
53-
}
54-
}
55-
56-
pub struct ArArchiveBuilder<'a> {
57-
config: ArchiveConfig<'a>,
58-
src_archives: Vec<(PathBuf, ar::Archive<File>)>,
59-
// Don't use `HashMap` here, as the order is important. `rust.metadata.bin` must always be at
60-
// the end of an archive for linkers to not get confused.
61-
entries: Vec<(String, ArchiveEntry)>,
62-
}
63-
64-
impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {
65-
fn add_file(&mut self, file: &Path) {
66-
self.entries.push((
67-
file.file_name().unwrap().to_str().unwrap().to_string(),
68-
ArchiveEntry::File(file.to_owned()),
69-
));
70-
}
71-
72-
fn add_archive(
73-
&mut self,
74-
archive_path: &Path,
75-
mut skip: Box<dyn FnMut(&str) -> bool + 'static>,
76-
) -> std::io::Result<()> {
77-
let mut archive = ar::Archive::new(std::fs::File::open(&archive_path)?);
78-
let archive_index = self.src_archives.len();
79-
80-
let mut i = 0;
81-
while let Some(entry) = archive.next_entry() {
82-
let entry = entry?;
83-
let file_name = String::from_utf8(entry.header().identifier().to_vec())
84-
.map_err(|err| std::io::Error::new(std::io::ErrorKind::InvalidData, err))?;
85-
if !skip(&file_name) {
86-
self.entries
87-
.push((file_name, ArchiveEntry::FromArchive { archive_index, entry_index: i }));
88-
}
89-
i += 1;
90-
}
91-
92-
self.src_archives.push((archive_path.to_owned(), archive));
93-
Ok(())
94-
}
95-
96-
fn build(mut self: Box<Self>, output: &Path) -> bool {
97-
use std::process::Command;
98-
99-
fn add_file_using_ar(archive: &Path, file: &Path) {
100-
Command::new("ar")
101-
.arg("r") // add or replace file
102-
.arg("-c") // silence created file message
103-
.arg(archive)
104-
.arg(&file)
105-
.status()
106-
.unwrap();
107-
}
108-
109-
enum BuilderKind<'a> {
110-
Bsd(ar::Builder<File>),
111-
Gnu(ar::GnuBuilder<File>),
112-
NativeAr(&'a Path),
113-
}
114-
115-
let mut builder = if self.config.use_native_ar {
116-
BuilderKind::NativeAr(output)
117-
} else if self.config.use_gnu_style_archive {
118-
BuilderKind::Gnu(ar::GnuBuilder::new(
119-
File::create(output).unwrap(),
120-
self.entries
121-
.iter()
122-
.map(|(name, _)| name.as_bytes().to_vec())
123-
.collect(),
124-
))
125-
} else {
126-
BuilderKind::Bsd(ar::Builder::new(File::create(output).unwrap()))
127-
};
128-
129-
let any_members = !self.entries.is_empty();
130-
131-
// Add all files
132-
for (entry_name, entry) in self.entries.into_iter() {
133-
match entry {
134-
ArchiveEntry::FromArchive {
135-
archive_index,
136-
entry_index,
137-
} => {
138-
let (ref src_archive_path, ref mut src_archive) =
139-
self.src_archives[archive_index];
140-
let entry = src_archive.jump_to_entry(entry_index).unwrap();
141-
let header = entry.header().clone();
142-
143-
match builder {
144-
BuilderKind::Bsd(ref mut builder) => {
145-
builder.append(&header, entry).unwrap()
146-
}
147-
BuilderKind::Gnu(ref mut builder) => {
148-
builder.append(&header, entry).unwrap()
149-
}
150-
BuilderKind::NativeAr(archive_file) => {
151-
Command::new("ar")
152-
.arg("x")
153-
.arg(src_archive_path)
154-
.arg(&entry_name)
155-
.status()
156-
.unwrap();
157-
add_file_using_ar(archive_file, Path::new(&entry_name));
158-
std::fs::remove_file(entry_name).unwrap();
159-
}
160-
}
161-
}
162-
ArchiveEntry::File(file) =>
163-
match builder {
164-
BuilderKind::Bsd(ref mut builder) => {
165-
builder
166-
.append_file(entry_name.as_bytes(), &mut File::open(file).expect("file for bsd builder"))
167-
.unwrap()
168-
},
169-
BuilderKind::Gnu(ref mut builder) => {
170-
builder
171-
.append_file(entry_name.as_bytes(), &mut File::open(&file).expect(&format!("file {:?} for gnu builder", file)))
172-
.unwrap()
173-
},
174-
BuilderKind::NativeAr(archive_file) => add_file_using_ar(archive_file, &file),
175-
},
176-
}
177-
}
178-
179-
// Finalize archive
180-
std::mem::drop(builder);
181-
182-
// Run ranlib to be able to link the archive
183-
let status =
184-
std::process::Command::new("ranlib").arg(output).status().expect("Couldn't run ranlib");
185-
186-
if !status.success() {
187-
self.config.sess.emit_fatal(RanlibFailure::new(status.code()));
188-
}
189-
190-
any_members
25+
unimplemented!("creating dll imports is not yet supported");
19126
}
19227
}

src/errors.rs

+2-14
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,6 @@ impl IntoDiagnosticArg for ExitCode {
1616
}
1717
}
1818

19-
#[derive(Diagnostic)]
20-
#[diag(codegen_gcc_ranlib_failure)]
21-
pub(crate) struct RanlibFailure {
22-
exit_code: ExitCode,
23-
}
24-
25-
impl RanlibFailure {
26-
pub fn new(exit_code: Option<i32>) -> Self {
27-
RanlibFailure { exit_code: ExitCode(exit_code) }
28-
}
29-
}
30-
3119
#[derive(Diagnostic)]
3220
#[diag(codegen_gcc_invalid_monomorphization_basic_integer, code = "E0511")]
3321
pub(crate) struct InvalidMonomorphizationBasicInteger<'a> {
@@ -227,7 +215,7 @@ pub(crate) struct InvalidMonomorphizationUnsupportedOperation<'a> {
227215
#[diag(codegen_gcc_linkage_const_or_mut_type)]
228216
pub(crate) struct LinkageConstOrMutType {
229217
#[primary_span]
230-
pub span: Span
218+
pub span: Span,
231219
}
232220

233221
#[derive(Diagnostic)]
@@ -238,5 +226,5 @@ pub(crate) struct LTONotSupported;
238226
#[diag(codegen_gcc_unwinding_inline_asm)]
239227
pub(crate) struct UnwindingInlineAsm {
240228
#[primary_span]
241-
pub span: Span
229+
pub span: Span,
242230
}

0 commit comments

Comments
 (0)