Skip to content

Commit 004dc33

Browse files
committed
Refactor archive.rs for future usage of ar::GnuBuilder
1 parent 3fedac8 commit 004dc33

File tree

1 file changed

+54
-43
lines changed

1 file changed

+54
-43
lines changed

src/archive.rs

Lines changed: 54 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -14,25 +14,29 @@ struct ArchiveConfig<'a> {
1414
pub lib_search_paths: Vec<PathBuf>,
1515
}
1616

17+
enum ArchiveEntry {
18+
FromArchive { archive_index: usize, entry_index: usize },
19+
File(File),
20+
}
21+
1722
pub struct ArArchiveBuilder<'a> {
1823
config: ArchiveConfig<'a>,
19-
src_archive: Option<ar::Archive<File>>,
20-
src_entries: HashMap<String, usize>,
21-
builder: ar::Builder<File>,
24+
src_archives: Vec<ar::Archive<File>>,
25+
entries: HashMap<String, ArchiveEntry>,
2226
update_symbols: bool,
2327
}
2428

2529
impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {
2630
fn new(sess: &'a Session, output: &Path, input: Option<&Path>) -> Self {
2731
use rustc_codegen_ssa::back::link::archive_search_paths;
28-
let cfg = ArchiveConfig {
32+
let config = ArchiveConfig {
2933
sess,
3034
dst: output.to_path_buf(),
3135
src: input.map(|p| p.to_path_buf()),
3236
lib_search_paths: archive_search_paths(sess),
3337
};
3438

35-
let (src_archive, src_entries) = if let Some(src) = &cfg.src {
39+
let (src_archives, entries) = if let Some(src) = &config.src {
3640
let mut archive = ar::Archive::new(File::open(src).unwrap());
3741
let mut entries = HashMap::new();
3842

@@ -41,41 +45,41 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {
4145
let entry = entry.unwrap();
4246
entries.insert(
4347
String::from_utf8(entry.header().identifier().to_vec()).unwrap(),
44-
i,
48+
ArchiveEntry::FromArchive { archive_index: 0, entry_index: i },
4549
);
4650
i += 1;
4751
}
4852

49-
(Some(archive), entries)
53+
(vec![archive], entries)
5054
} else {
51-
(None, HashMap::new())
55+
(vec![], HashMap::new())
5256
};
5357

54-
let builder = ar::Builder::new(File::create(&cfg.dst).unwrap());
55-
5658
ArArchiveBuilder {
57-
config: cfg,
58-
src_archive,
59-
src_entries,
60-
builder,
59+
config,
60+
src_archives,
61+
entries,
6162
update_symbols: false,
6263
}
6364
}
6465

6566
fn src_files(&mut self) -> Vec<String> {
66-
self.src_entries.keys().cloned().collect()
67+
self.entries.keys().cloned().collect()
6768
}
6869

6970
fn remove_file(&mut self, name: &str) {
70-
let file = self.src_entries.remove(name);
71+
let file = self.entries.remove(name);
7172
assert!(
7273
file.is_some(),
7374
"Tried to remove file not existing in src archive",
7475
);
7576
}
7677

7778
fn add_file(&mut self, file: &Path) {
78-
self.builder.append_path(file).unwrap();
79+
self.entries.insert(
80+
file.file_name().unwrap().to_str().unwrap().to_string(),
81+
ArchiveEntry::File(File::open(file).unwrap()),
82+
);
7983
}
8084

8185
fn add_native_library(&mut self, name: &str) {
@@ -115,23 +119,30 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {
115119
}
116120

117121
fn build(mut self) {
118-
// Add files from original archive
119-
if let Some(mut src_archive) = self.src_archive {
120-
for (_entry_name, entry_idx) in self.src_entries.into_iter() {
121-
let entry = src_archive.jump_to_entry(entry_idx).unwrap();
122-
let orig_header = entry.header();
123-
let mut header =
124-
ar::Header::new(orig_header.identifier().to_vec(), orig_header.size());
125-
header.set_mtime(orig_header.mtime());
126-
header.set_uid(orig_header.uid());
127-
header.set_gid(orig_header.gid());
128-
header.set_mode(orig_header.mode());
129-
self.builder.append(&header, entry).unwrap();
122+
let mut builder = ar::Builder::new(File::create(&self.config.dst).unwrap());
123+
124+
// Add all files
125+
for (entry_name, entry) in self.entries.into_iter() {
126+
match entry {
127+
ArchiveEntry::FromArchive { archive_index, entry_index } => {
128+
let entry = self.src_archives[archive_index].jump_to_entry(entry_index).unwrap();
129+
let orig_header = entry.header();
130+
let mut header =
131+
ar::Header::new(orig_header.identifier().to_vec(), orig_header.size());
132+
header.set_mtime(orig_header.mtime());
133+
header.set_uid(orig_header.uid());
134+
header.set_gid(orig_header.gid());
135+
header.set_mode(orig_header.mode());
136+
builder.append(&header, entry).unwrap();
137+
}
138+
ArchiveEntry::File(mut file) => {
139+
builder.append_file(entry_name.as_bytes(), &mut file).unwrap();
140+
}
130141
}
131142
}
132143

133144
// Finalize archive
134-
std::mem::drop(self.builder);
145+
std::mem::drop(builder);
135146

136147
// Run ranlib to be able to link the archive
137148
let status = std::process::Command::new("ranlib")
@@ -151,22 +162,22 @@ impl<'a> ArArchiveBuilder<'a> {
151162
where F: FnMut(&str) -> bool + 'static
152163
{
153164
let mut archive = ar::Archive::new(std::fs::File::open(archive)?);
154-
while let Some(entry) = archive.next_entry() {
155-
let entry = entry?;
156-
let orig_header = entry.header();
165+
let archive_index = self.src_archives.len();
157166

158-
if skip(std::str::from_utf8(orig_header.identifier()).unwrap()) {
159-
continue;
167+
let mut i = 0;
168+
while let Some(entry) = archive.next_entry() {
169+
let entry = entry.unwrap();
170+
let file_name = String::from_utf8(entry.header().identifier().to_vec()).unwrap();
171+
if !skip(&file_name) {
172+
self.entries.insert(
173+
file_name,
174+
ArchiveEntry::FromArchive { archive_index, entry_index: i },
175+
);
160176
}
161-
162-
let mut header =
163-
ar::Header::new(orig_header.identifier().to_vec(), orig_header.size());
164-
header.set_mtime(orig_header.mtime());
165-
header.set_uid(orig_header.uid());
166-
header.set_gid(orig_header.gid());
167-
header.set_mode(orig_header.mode());
168-
self.builder.append(&header, entry).unwrap();
177+
i += 1;
169178
}
179+
180+
self.src_archives.push(archive);
170181
Ok(())
171182
}
172183
}

0 commit comments

Comments
 (0)