1 use std::collections::HashMap;
3 use std::path::PathBuf;
7 pub struct ArchiveConfig<'a> {
10 pub src: Option<PathBuf>,
11 pub lib_search_paths: Vec<PathBuf>,
14 pub struct ArchiveBuilder<'a> {
15 cfg: ArchiveConfig<'a>,
16 src_archive: Option<ar::Archive<File>>,
17 src_entries: HashMap<String, usize>,
18 builder: ar::Builder<File>,
22 impl<'a> ArchiveBuilder<'a> {
23 pub fn new(cfg: ArchiveConfig<'a>) -> Self {
24 let (src_archive, src_entries) = if let Some(src) = &cfg.src {
25 let mut archive = ar::Archive::new(File::open(src).unwrap());
26 let mut entries = HashMap::new();
29 while let Some(entry) = archive.next_entry() {
30 let entry = entry.unwrap();
32 String::from_utf8(entry.header().identifier().to_vec()).unwrap(),
38 (Some(archive), entries)
40 (None, HashMap::new())
43 let builder = ar::Builder::new(File::create(&cfg.dst).unwrap());
50 update_symbols: false,
54 pub fn src_files(&self) -> Vec<String> {
55 self.src_entries.keys().cloned().collect()
58 pub fn remove_file(&mut self, name: &str) {
59 let file = self.src_entries.remove(name);
62 "Tried to remove file not existing in src archive",
66 pub fn update_symbols(&mut self) {
67 self.update_symbols = true;
70 pub fn build(mut self) {
71 // Add files from original archive
72 if let Some(mut src_archive) = self.src_archive {
73 for (_entry_name, entry_idx) in self.src_entries.into_iter() {
74 let entry = src_archive.jump_to_entry(entry_idx).unwrap();
75 let orig_header = entry.header();
77 ar::Header::new(orig_header.identifier().to_vec(), orig_header.size());
78 header.set_mtime(orig_header.mtime());
79 header.set_uid(orig_header.uid());
80 header.set_gid(orig_header.gid());
81 header.set_mode(orig_header.mode());
82 self.builder.append(&header, entry).unwrap();
87 std::mem::drop(self.builder);
89 // Run ranlib to be able to link the archive
90 let status = std::process::Command::new("ranlib")
93 .expect("Couldn't run ranlib");
96 "Ranlib exited with code {:?}",