From 83b57947e328163263bb1e581bdf790bc15e8395 Mon Sep 17 00:00:00 2001 From: Matthew Lugg Date: Sat, 8 Aug 2026 09:38:38 +0100 Subject: [PATCH] link: don't include static libraries in other static libraries Follow-up to 9aa93a045ebbf7d5c6349eb41e99ca516ab9ba65, which fixed this bug for *shared* library inputs, but not *static* library inputs. Supersedes https://codeberg.org/ziglang/zig/pulls/31383 by fixing the bug at the compiler level instead of working around it in the build system. This seems preferable because it is useful to the compiler to have full information about a compilation's link inputs---for instance this could interact with https://github.com/ziglang/zig/issues/20654 in the future by having the compiler learn about a static library's ABI even if that static library does not ultimately contribute to the link. Resolves: https://codeberg.org/ziglang/zig/issues/35624 --- src/link/Elf.zig | 15 +++++++-------- src/link/Lld.zig | 4 ++-- src/link/MachO.zig | 5 +++++ 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/link/Elf.zig b/src/link/Elf.zig index 04d4f9235e12f22c3ee7f012c48d43f323ea38a1..80844d3d8832b7b326411038a286cc2391b4d097 100644 --- a/src/link/Elf.zig +++ b/src/link/Elf.zig @@ -714,7 +714,6 @@ pub fn loadInput(self: *Elf, input: link.Input) !void { const target = self.getTarget(); const debug_fmt_strip = comp.config.debug_format == .strip; const default_sym_version = self.default_sym_version; - const is_static_lib = self.base.isStaticLib(); if (comp.verbose_link) { comp.mutex.lockUncancelable(io); // protect comp.arena @@ -733,7 +732,11 @@ pub fn loadInput(self: *Elf, input: link.Input) !void { .res => unreachable, .dso_exact => @panic("TODO"), .object => |obj| try parseObject(self, obj), - .archive => |obj| try parseArchive(gpa, io, diags, &self.file_handles, &self.files, target, debug_fmt_strip, default_sym_version, &self.objects, obj, is_static_lib), + .archive => |obj| if (self.base.isStaticLib()) { + // Ignore static library inputs when generating a static library. + } else { + try parseArchive(gpa, io, diags, &self.file_handles, &self.files, target, debug_fmt_strip, default_sym_version, &self.objects, obj); + }, .dso => |dso| try parseDso(gpa, io, diags, dso, &self.shared_objects, &self.files, target), } } @@ -1083,7 +1086,6 @@ fn parseArchive( default_sym_version: elf.Versym, objects: *std.ArrayList(File.Index), obj: link.Input.Object, - is_static_lib: bool, ) !void { const tracy = trace(@src()); defer tracy.end(); @@ -1092,17 +1094,14 @@ fn parseArchive( var archive = try Archive.parse(gpa, io, diags, file_handles, obj.path, fh); defer archive.deinit(gpa); - const init_alive = if (is_static_lib) true else obj.must_link; - for (archive.objects) |extracted| { const index: File.Index = @intCast(try files.addOne(gpa)); files.set(index, .{ .object = extracted }); const object = &files.items(.data)[index].object; object.index = index; - object.alive = init_alive; + object.alive = obj.must_link; try object.parseCommon(gpa, io, diags, obj.path, obj.file, target); - if (!is_static_lib) - try object.parse(gpa, io, diags, obj.path, obj.file, target, debug_fmt_strip, default_sym_version); + try object.parse(gpa, io, diags, obj.path, obj.file, target, debug_fmt_strip, default_sym_version); try objects.append(gpa, index); } } diff --git a/src/link/Lld.zig b/src/link/Lld.zig index 63b1df93c0d19823843c023c0ce185083668f013..894e21785c1ff5c5a969a12acff6538c8a752e12 100644 --- a/src/link/Lld.zig +++ b/src/link/Lld.zig @@ -306,8 +306,8 @@ fn linkAsArchive(lld: *Lld, arena: Allocator) link.Error!void { try object_files.ensureUnusedCapacity(arena, comp.link_inputs.len); for (comp.link_inputs) |input| switch (input) { - .res, .dso, .dso_exact => {}, // shared libraries should not be included in static archives - .object, .archive => { + .dso, .dso_exact, .archive => {}, // static archives should not contain shared libraries or other static archives + .res, .object => { const path = try input.path().?.toStringZ(arena); object_files.appendAssumeCapacity(path); }, diff --git a/src/link/MachO.zig b/src/link/MachO.zig index 3dddf5f78ebc396599c14c666f4b15c082fbce0f..eb94246a43fe3b4d38d2473f5d53a9512890a20a 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -992,6 +992,11 @@ fn addArchive(self: *MachO, lib: link.Input.Object, handle: File.HandleIndex, fa const tracy = trace(@src()); defer tracy.end(); + if (self.base.isStaticLib()) { + // Ignore static library inputs when generating a static library. + return; + } + const gpa = self.base.comp.gpa; var archive: Archive = .{}; -- 2.54.0