@@ -21,7 +21,7 @@ use rustc_target::spec::Arch;
2121use tracing:: trace;
2222
2323use super :: metadata:: { create_compressed_metadata_file, search_for_section} ;
24- use super :: rmeta_link:: { self , RmetaLink } ;
24+ use super :: rmeta_link;
2525use crate :: common;
2626// Public for ArchiveBuilderBuilder::extract_bundled_libs
2727pub use crate :: errors:: ExtractBundledLibsError ;
@@ -308,14 +308,15 @@ fn find_binutils_dlltool(sess: &Session) -> OsString {
308308 tool_name
309309}
310310
311+ pub enum AddArchiveKind < ' a > {
312+ Rlib ( /*skip*/ & ' a dyn Fn ( & str , ArchiveEntryKind ) -> bool ) ,
313+ Other ,
314+ }
315+
311316pub trait ArchiveBuilder {
312- fn add_file ( & mut self , path : & Path ) ;
317+ fn add_file ( & mut self , path : & Path , kind : ArchiveEntryKind ) ;
313318
314- fn add_archive (
315- & mut self ,
316- archive : & Path ,
317- skip : Option < Box < dyn FnMut ( & str , Option < & RmetaLink > ) -> bool + ' static > > ,
318- ) -> io:: Result < ( ) > ;
319+ fn add_archive ( & mut self , archive : & Path , kind : AddArchiveKind < ' _ > ) -> io:: Result < ( ) > ;
319320
320321 fn build ( self : Box < Self > , output : & Path ) -> bool ;
321322}
@@ -383,12 +384,27 @@ pub struct ArArchiveBuilder<'a> {
383384 entries : Vec < ( Vec < u8 > , ArchiveEntry ) > ,
384385}
385386
387+ #[ derive( Clone , Copy , PartialEq , Debug ) ]
388+ pub enum ArchiveEntryKind {
389+ /// Object file produced from Rust code.
390+ RustObj ,
391+ /// Anything else, introduce new variants as needed.
392+ Other ,
393+ }
394+
386395#[ derive( Debug ) ]
387- enum ArchiveEntry {
388- FromArchive { archive_index : usize , file_range : ( u64 , u64 ) } ,
396+ enum ArchiveEntrySource {
397+ Archive { archive_index : usize , file_range : ( u64 , u64 ) } ,
389398 File ( PathBuf ) ,
390399}
391400
401+ #[ derive( Debug ) ]
402+ struct ArchiveEntry {
403+ source : ArchiveEntrySource ,
404+ #[ expect( dead_code) ] // used in #155338
405+ kind : ArchiveEntryKind ,
406+ }
407+
392408impl < ' a > ArArchiveBuilder < ' a > {
393409 pub fn new ( sess : & ' a Session , object_reader : & ' static ObjectReader ) -> ArArchiveBuilder < ' a > {
394410 ArArchiveBuilder { sess, object_reader, src_archives : vec ! [ ] , entries : vec ! [ ] }
@@ -443,11 +459,7 @@ pub fn try_extract_macho_fat_archive(
443459}
444460
445461impl < ' a > ArchiveBuilder for ArArchiveBuilder < ' a > {
446- fn add_archive (
447- & mut self ,
448- archive_path : & Path ,
449- mut skip : Option < Box < dyn FnMut ( & str , Option < & RmetaLink > ) -> bool + ' static > > ,
450- ) -> io:: Result < ( ) > {
462+ fn add_archive ( & mut self , archive_path : & Path , ar_kind : AddArchiveKind < ' _ > ) -> io:: Result < ( ) > {
451463 let mut archive_path = archive_path. to_path_buf ( ) ;
452464 if self . sess . target . llvm_target . contains ( "-apple-macosx" )
453465 && let Some ( new_archive_path) = try_extract_macho_fat_archive ( self . sess , & archive_path) ?
@@ -462,8 +474,10 @@ impl<'a> ArchiveBuilder for ArArchiveBuilder<'a> {
462474 let archive_map = unsafe { Mmap :: map ( File :: open ( & archive_path) ?) ? } ;
463475 let archive = ArchiveFile :: parse ( & * archive_map)
464476 . map_err ( |err| io:: Error :: new ( io:: ErrorKind :: InvalidData , err) ) ?;
465- let metadata_link =
466- skip. as_ref ( ) . and_then ( |_| rmeta_link:: read ( & archive, & archive_map, & archive_path) ) ;
477+ let metadata_link = match ar_kind {
478+ AddArchiveKind :: Rlib ( ..) => rmeta_link:: read ( & archive, & archive_map, & archive_path) ,
479+ AddArchiveKind :: Other => None ,
480+ } ;
467481 let archive_index = self . src_archives . len ( ) ;
468482
469483 if let Some ( expected_kind) =
@@ -483,17 +497,26 @@ impl<'a> ArchiveBuilder for ArArchiveBuilder<'a> {
483497 let entry = entry. map_err ( |err| io:: Error :: new ( io:: ErrorKind :: InvalidData , err) ) ?;
484498 let file_name = String :: from_utf8 ( entry. name ( ) . to_vec ( ) )
485499 . map_err ( |err| io:: Error :: new ( io:: ErrorKind :: InvalidData , err) ) ?;
486- let drop = skip. as_mut ( ) . is_some_and ( |f| f ( & file_name, metadata_link. as_ref ( ) ) ) ;
500+ let kind = if metadata_link
501+ . as_ref ( )
502+ . is_some_and ( |m| m. rust_object_files . iter ( ) . any ( |f| f == & file_name) )
503+ {
504+ ArchiveEntryKind :: RustObj
505+ } else {
506+ ArchiveEntryKind :: Other
507+ } ;
508+ let drop = match ar_kind {
509+ AddArchiveKind :: Rlib ( skip) => skip ( & file_name, kind) ,
510+ AddArchiveKind :: Other => false ,
511+ } ;
487512 if !drop {
488- if entry. is_thin ( ) {
513+ let source = if entry. is_thin ( ) {
489514 let member_path = archive_path. parent ( ) . unwrap ( ) . join ( Path :: new ( & file_name) ) ;
490- self . entries . push ( ( file_name . into_bytes ( ) , ArchiveEntry :: File ( member_path) ) ) ;
515+ ArchiveEntrySource :: File ( member_path)
491516 } else {
492- self . entries . push ( (
493- file_name. into_bytes ( ) ,
494- ArchiveEntry :: FromArchive { archive_index, file_range : entry. file_range ( ) } ,
495- ) ) ;
496- }
517+ ArchiveEntrySource :: Archive { archive_index, file_range : entry. file_range ( ) }
518+ } ;
519+ self . entries . push ( ( file_name. into_bytes ( ) , ArchiveEntry { source, kind } ) ) ;
497520 }
498521 }
499522
@@ -502,10 +525,10 @@ impl<'a> ArchiveBuilder for ArArchiveBuilder<'a> {
502525 }
503526
504527 /// Adds an arbitrary file to this archive
505- fn add_file ( & mut self , file : & Path ) {
528+ fn add_file ( & mut self , file : & Path , kind : ArchiveEntryKind ) {
506529 self . entries . push ( (
507530 file. file_name ( ) . unwrap ( ) . to_str ( ) . unwrap ( ) . to_string ( ) . into_bytes ( ) ,
508- ArchiveEntry :: File ( file. to_owned ( ) ) ,
531+ ArchiveEntry { source : ArchiveEntrySource :: File ( file. to_owned ( ) ) , kind } ,
509532 ) ) ;
510533 }
511534
@@ -539,8 +562,8 @@ impl<'a> ArArchiveBuilder<'a> {
539562
540563 for ( entry_name, entry) in self . entries {
541564 let data =
542- match entry {
543- ArchiveEntry :: FromArchive { archive_index, file_range } => {
565+ match entry. source {
566+ ArchiveEntrySource :: Archive { archive_index, file_range } => {
544567 let src_archive = & self . src_archives [ archive_index] ;
545568 let archive_data = & src_archive. 1 ;
546569 let start = file_range. 0 as usize ;
@@ -563,7 +586,7 @@ impl<'a> ArArchiveBuilder<'a> {
563586
564587 Box :: new ( data) as Box < dyn AsRef < [ u8 ] > >
565588 }
566- ArchiveEntry :: File ( file) => unsafe {
589+ ArchiveEntrySource :: File ( file) => unsafe {
567590 Box :: new (
568591 Mmap :: map ( File :: open ( file) . map_err ( |err| {
569592 io_error_context ( "failed to open object file" , err)
0 commit comments