Skip to content

Commit 530f481

Browse files
authored
Rollup merge of rust-lang#128936 - bjorn3:fix_thin_archive_reading, r=jieyouxu
Support reading thin archives in ArArchiveBuilder And switch to using ArArchiveBuilder with the LLVM backend too now that all regressions are fixed. Fixes rust-lang#107407 Fixes rust-lang#107162 rust-lang#107495 has been fixed in a previous PR already.
2 parents cb9e0df + db68a19 commit 530f481

File tree

7 files changed

+63
-7
lines changed

7 files changed

+63
-7
lines changed

compiler/rustc_codegen_llvm/src/back/archive.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -106,9 +106,11 @@ pub struct LlvmArchiveBuilderBuilder;
106106

107107
impl ArchiveBuilderBuilder for LlvmArchiveBuilderBuilder {
108108
fn new_archive_builder<'a>(&self, sess: &'a Session) -> Box<dyn ArchiveBuilder + 'a> {
109-
// FIXME use ArArchiveBuilder on most targets again once reading thin archives is
110-
// implemented
111-
if true {
109+
// Keeping LlvmArchiveBuilder around in case of a regression caused by using
110+
// ArArchiveBuilder.
111+
// FIXME(#128955) remove a couple of months after #128936 gets merged in case
112+
// no regression is found.
113+
if false {
112114
Box::new(LlvmArchiveBuilder { sess, additions: Vec::new() })
113115
} else {
114116
Box::new(ArArchiveBuilder::new(sess, &LLVM_OBJECT_READER))

compiler/rustc_codegen_ssa/src/back/archive.rs

+9-4
Original file line numberDiff line numberDiff line change
@@ -307,10 +307,15 @@ impl<'a> ArchiveBuilder for ArArchiveBuilder<'a> {
307307
let file_name = String::from_utf8(entry.name().to_vec())
308308
.map_err(|err| io::Error::new(io::ErrorKind::InvalidData, err))?;
309309
if !skip(&file_name) {
310-
self.entries.push((
311-
file_name.into_bytes(),
312-
ArchiveEntry::FromArchive { archive_index, file_range: entry.file_range() },
313-
));
310+
if entry.is_thin() {
311+
let member_path = archive_path.parent().unwrap().join(Path::new(&file_name));
312+
self.entries.push((file_name.into_bytes(), ArchiveEntry::File(member_path)));
313+
} else {
314+
self.entries.push((
315+
file_name.into_bytes(),
316+
ArchiveEntry::FromArchive { archive_index, file_range: entry.file_range() },
317+
));
318+
}
314319
}
315320
}
316321

src/tools/run-make-support/src/external_deps/llvm.rs

+6
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,12 @@ impl LlvmAr {
271271
self
272272
}
273273

274+
/// Like `obj_to_ar` except creating a thin archive.
275+
pub fn obj_to_thin_ar(&mut self) -> &mut Self {
276+
self.cmd.arg("rcus").arg("--thin");
277+
self
278+
}
279+
274280
/// Extract archive members back to files.
275281
pub fn extract(&mut self) -> &mut Self {
276282
self.cmd.arg("x");
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
fn main() {
2+
unsafe {
3+
rust_lib::simple_fn();
4+
}
5+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Regression test for https://github.com/rust-lang/rust/issues/107407 which
2+
// checks that rustc can read thin archive. Before the object crate added thin
3+
// archive support rustc would add emit object files to the staticlib and after
4+
// the object crate added thin archive support it would previously crash the
5+
// compiler due to a missing special case for thin archive members.
6+
use std::path::Path;
7+
8+
use run_make_support::{llvm_ar, rust_lib_name, rustc, static_lib_name};
9+
10+
fn main() {
11+
std::fs::create_dir("archive").unwrap();
12+
13+
// Build a thin archive
14+
rustc().input("simple_obj.rs").emit("obj").output("archive/simple_obj.o").run();
15+
llvm_ar()
16+
.obj_to_thin_ar()
17+
.output_input(
18+
Path::new("archive").join(static_lib_name("thin_archive")),
19+
"archive/simple_obj.o",
20+
)
21+
.run();
22+
23+
// Build an rlib which includes the members of this thin archive
24+
rustc().input("rust_lib.rs").library_search_path("archive").run();
25+
26+
// Build a binary which requires a symbol from the thin archive
27+
rustc().input("bin.rs").extern_("rust_lib", rust_lib_name("rust_lib")).run();
28+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#![crate_type = "rlib"]
2+
3+
#[link(name = "thin_archive", kind = "static")]
4+
extern "C" {
5+
pub fn simple_fn();
6+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#![crate_type = "staticlib"]
2+
3+
#[no_mangle]
4+
extern "C" fn simple_fn() {}

0 commit comments

Comments
 (0)