Skip to content

Commit aeecb45

Browse files
committed
Preserve the order files are added to archives
rust.metadata.bin could have been at the start of an .rlib file confusing ld
1 parent 11d816c commit aeecb45

File tree

2 files changed

+19
-18
lines changed

2 files changed

+19
-18
lines changed

example/alloc_example.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#![feature(start, box_syntax, alloc_system, core_intrinsics, alloc, alloc_prelude, alloc_error_handler)]
1+
#![feature(start, box_syntax, alloc_system, core_intrinsics, alloc_prelude, alloc_error_handler)]
22
#![no_std]
33

44
extern crate alloc;

src/archive.rs

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
use std::collections::HashMap;
21
use std::fs::File;
32
use std::path::{Path, PathBuf};
43

@@ -24,7 +23,9 @@ enum ArchiveEntry {
2423
pub struct ArArchiveBuilder<'a> {
2524
config: ArchiveConfig<'a>,
2625
src_archives: Vec<ar::Archive<File>>,
27-
entries: HashMap<String, ArchiveEntry>,
26+
// Don't use `HashMap` here, as the order is important. `rust.metadata.bin` must always be at
27+
// the end of an archive for linkers to not get confused.
28+
entries: Vec<(String, ArchiveEntry)>,
2829
update_symbols: bool,
2930
}
3031

@@ -42,21 +43,21 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {
4243

4344
let (src_archives, entries) = if let Some(src) = &config.src {
4445
let mut archive = ar::Archive::new(File::open(src).unwrap());
45-
let mut entries = HashMap::new();
46+
let mut entries = Vec::new();
4647

4748
let mut i = 0;
4849
while let Some(entry) = archive.next_entry() {
4950
let entry = entry.unwrap();
50-
entries.insert(
51+
entries.push((
5152
String::from_utf8(entry.header().identifier().to_vec()).unwrap(),
5253
ArchiveEntry::FromArchive { archive_index: 0, entry_index: i },
53-
);
54+
));
5455
i += 1;
5556
}
5657

5758
(vec![archive], entries)
5859
} else {
59-
(vec![], HashMap::new())
60+
(vec![], Vec::new())
6061
};
6162

6263
ArArchiveBuilder {
@@ -68,22 +69,22 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {
6869
}
6970

7071
fn src_files(&mut self) -> Vec<String> {
71-
self.entries.keys().cloned().collect()
72+
self.entries.iter().map(|(name, _)| name.clone()).collect()
7273
}
7374

7475
fn remove_file(&mut self, name: &str) {
75-
let file = self.entries.remove(name);
76-
assert!(
77-
file.is_some(),
78-
"Tried to remove file not existing in src archive",
79-
);
76+
let index = self.entries
77+
.iter()
78+
.position(|(entry_name, _)| entry_name == name)
79+
.expect("Tried to remove file not existing in src archive");
80+
self.entries.remove(index);
8081
}
8182

8283
fn add_file(&mut self, file: &Path) {
83-
self.entries.insert(
84+
self.entries.push((
8485
file.file_name().unwrap().to_str().unwrap().to_string(),
8586
ArchiveEntry::File(File::open(file).unwrap()),
86-
);
87+
));
8788
}
8889

8990
fn add_native_library(&mut self, name: &str) {
@@ -132,7 +133,7 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {
132133
let mut builder = if self.config.use_gnu_style_archive {
133134
BuilderKind::Gnu(ar::GnuBuilder::new(
134135
archive_file,
135-
self.entries.keys().map(|key| key.as_bytes().to_vec()).collect(),
136+
self.entries.iter().map(|(name, _)| name.as_bytes().to_vec()).collect(),
136137
))
137138
} else {
138139
BuilderKind::Bsd(ar::Builder::new(archive_file))
@@ -193,10 +194,10 @@ impl<'a> ArArchiveBuilder<'a> {
193194
let entry = entry.unwrap();
194195
let file_name = String::from_utf8(entry.header().identifier().to_vec()).unwrap();
195196
if !skip(&file_name) {
196-
self.entries.insert(
197+
self.entries.push((
197198
file_name,
198199
ArchiveEntry::FromArchive { archive_index, entry_index: i },
199-
);
200+
));
200201
}
201202
i += 1;
202203
}

0 commit comments

Comments
 (0)