@@ -249,6 +249,7 @@ pub fn link(self: *MachO) !void {
249249 }
250250
251251 try self .parseInputFiles ();
252+ try self .dedupDylibs (resolved_objects .items );
252253 try self .parseDependentDylibs (arena , lib_dirs .items , framework_dirs .items );
253254
254255 if (! self .options .relocatable ) {
@@ -832,6 +833,41 @@ fn isHoisted(self: *MachO, install_name: []const u8) bool {
832833 return false ;
833834}
834835
836+ fn dedupDylibs (self : * MachO , resolved_objects : []const LinkObject ) ! void {
837+ const tracy = trace (@src ());
838+ defer tracy .end ();
839+
840+ var map = std .HashMap (Dylib .Id , void , struct {
841+ pub fn hash (ctx : @This (), id : Dylib .Id ) u64 {
842+ _ = ctx ;
843+ return id .hash ();
844+ }
845+
846+ pub fn eql (ctx : @This (), id : Dylib .Id , other : Dylib .Id ) bool {
847+ _ = ctx ;
848+ return id .eql (other );
849+ }
850+ }, std .hash_map .default_max_load_percentage ).init (self .allocator );
851+ defer map .deinit ();
852+ try map .ensureTotalCapacity (@intCast (self .dylibs .items .len ));
853+
854+ for (self .dylibs .items ) | index | {
855+ const dylib = self .getFile (index ).dylib ;
856+ const cmd_object = resolved_objects [@intFromEnum (index )];
857+
858+ const gop = map .getOrPutAssumeCapacity (dylib .id .? );
859+
860+ if (! gop .found_existing ) continue ;
861+ if (cmd_object .tag == .lib ) {
862+ self .warn ("ignoring duplicate libraries: {}" , .{cmd_object });
863+ }
864+
865+ dylib .markDead ();
866+ }
867+
868+ try self .removeDylibs ();
869+ }
870+
835871fn parseDependentDylibs (
836872 self : * MachO ,
837873 arena : Allocator ,
@@ -1036,6 +1072,10 @@ fn deadStripDylibs(self: *MachO) !void {
10361072 self .getFile (index ).dylib .markReferenced (self );
10371073 }
10381074
1075+ try self .removeDylibs ();
1076+ }
1077+
1078+ fn removeDylibs (self : * MachO ) ! void {
10391079 var stripped = std .AutoHashMap (File .Index , void ).init (self .allocator );
10401080 defer stripped .deinit ();
10411081 try stripped .ensureTotalCapacity (@intCast (self .dylibs .items .len ));
0 commit comments