From 6418840f90d71a3c991bbb207ccdde4c9dc21d17 Mon Sep 17 00:00:00 2001 From: Matthew Lugg Date: Thu, 24 Sep 2026 21:36:36 +0100 Subject: [PATCH] link.MachO: work around non-deterministic link input order This commit should be reverted when https://codeberg.org/ziglang/zig/issues/36946 is fixed. --- src/link/MachO.zig | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/link/MachO.zig b/src/link/MachO.zig index b2b90f4d5091feee962fe301dfe6346692faa1b1..eb3e6d05432ca0c7af4a86b2468041229bccf414 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -354,6 +354,30 @@ pub fn flush( const sub_prog_node = prog_node.start("MachO Flush", 0); defer sub_prog_node.end(); + // TODO: due to https://codeberg.org/ziglang/zig/issues/36946, we receive link inputs in a + // non-deterministic order. To ensure that this linker behaves deterministically, sort the + // inputs into a consistent order now. + { + const InputSortContext = struct { + fn lessThan(ctx: @This(), lhs: link.Input, rhs: link.Input) bool { + _ = ctx; + // We can't sort by full path because that could vary between runs where we still + // want reproducibility (e.g. the path is affected by cwd). So instead, let's sort + // by basename---that's good enough for our purposes since we never link two + // vendored libraries/objects with the same name. + const lhs_name = fs.path.basename(lhs.path().sub_path); + const rhs_name = fs.path.basename(rhs.path().sub_path); + return std.mem.order(u8, lhs_name, rhs_name).compare(.lt); + } + }; + std.mem.sort( + link.Input, + self.all_inputs.items, + @as(InputSortContext, .{}), + InputSortContext.lessThan, + ); + } + // --verbose-link if (comp.verbose_link) try self.dumpArgv(comp); -- 2.54.0