}
impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {
- fn new(sess: &'a Session, output: &Path, input: Option<&Path>) -> Self {
- let (src_archives, entries) = if let Some(input) = input {
- let read_cache = ReadCache::new(File::open(input).unwrap());
- let archive = ArchiveFile::parse(&read_cache).unwrap();
- let mut entries = Vec::new();
-
- for entry in archive.members() {
- let entry = entry.unwrap();
- entries.push((
- entry.name().to_vec(),
- ArchiveEntry::FromArchive { archive_index: 0, file_range: entry.file_range() },
- ));
- }
-
- (vec![read_cache.into_inner()], entries)
- } else {
- (vec![], Vec::new())
- };
-
+ fn new(sess: &'a Session, output: &Path) -> Self {
ArArchiveBuilder {
sess,
dst: output.to_path_buf(),
// FIXME fix builtin ranlib on macOS
no_builtin_ranlib: sess.target.is_like_osx,
- src_archives,
- entries,
+ src_archives: vec![],
+ entries: vec![],
}
}
let mut entries = Vec::new();
- for (entry_name, entry) in self.entries {
+ for (mut entry_name, entry) in self.entries {
// FIXME only read the symbol table of the object files to avoid having to keep all
// object files in memory at once, or read them twice.
let data = match entry {
};
if !self.no_builtin_ranlib {
+ if symbol_table.contains_key(&entry_name) {
+ // The ar crate can't handle creating a symbol table in case of multiple archive
+ // members with the same name. Work around this by prepending a number until we
+ // get a unique name.
+ for i in 1.. {
+ let new_name = format!("{}_", i)
+ .into_bytes()
+ .into_iter()
+ .chain(entry_name.iter().copied())
+ .collect::<Vec<_>>();
+ if !symbol_table.contains_key(&new_name) {
+ entry_name = new_name;
+ break;
+ }
+ }
+ }
+
match object::File::parse(&*data) {
Ok(object) => {
symbol_table.insert(