diff --git a/lib/std/macho.zig b/lib/std/macho.zig index 2dcc4b4b3..a4a8bbdd1 100644 --- a/lib/std/macho.zig +++ b/lib/std/macho.zig @@ -722,6 +722,19 @@ pub const version_min_command = extern struct { sdk: u32, }; +/// The source_version_command is an optional load command containing +/// the version of the sources used to build the binary. +pub const source_version_command = extern struct { + /// LC_SOURCE_VERSION + cmd: u32, + + /// sizeof(source_version_command) + cmdsize: u32, + + /// A.B.C.D.E packed as a24.b10.c10.d10.e10 + version: u64, +}; + /// After MacOS X 10.1 when a new load command is added that is required to be /// understood by the dynamic linker for the image to execute properly the /// LC_REQ_DYLD bit will be or'ed into the load command constant. If the dynamic diff --git a/src/link/MachO.zig b/src/link/MachO.zig index 611f3af54..5fa1dbbf4 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -34,6 +34,7 @@ const LoadCommand = union(enum) { Dylib: macho.dylib_command, EntryPoint: macho.entry_point_command, MinVersion: macho.version_min_command, + SourceVersion: macho.source_version_command, pub fn cmdsize(self: LoadCommand) u32 { return switch (self) { @@ -46,6 +47,7 @@ const LoadCommand = union(enum) { .Dylib => |x| x.cmdsize, .EntryPoint => |x| x.cmdsize, .MinVersion => |x| x.cmdsize, + .SourceVersion => |x| x.cmdsize, }; } @@ -60,6 +62,7 @@ const LoadCommand = union(enum) { .Dylib => |cmd| writeGeneric(cmd, file, offset), .EntryPoint => |cmd| writeGeneric(cmd, file, offset), .MinVersion => |cmd| writeGeneric(cmd, file, offset), + .SourceVersion => |cmd| writeGeneric(cmd, file, offset), }; } @@ -101,6 +104,8 @@ function_starts_cmd_index: ?u16 = null, main_cmd_index: ?u16 = null, /// Minimum OS version version_min_cmd_index: ?u16 = null, +/// Source version +source_version_cmd_index: ?u16 = null, /// Table of all sections sections: std.ArrayListUnmanaged(macho.section_64) = .{}, @@ -1377,6 +1382,16 @@ pub fn populateMissingMetadata(self: *MachO) !void { }, }); } + if (self.source_version_cmd_index == null) { + self.source_version_cmd_index = @intCast(u16, self.load_commands.items.len); + try self.load_commands.append(self.base.allocator, .{ + .SourceVersion = .{ + .cmd = macho.LC_SOURCE_VERSION, + .cmdsize = @sizeOf(macho.source_version_command), + .version = 0x0, + }, + }); + } { const linkedit = &self.load_commands.items[self.linkedit_segment_cmd_index.?].Segment; const dyld_info = &self.load_commands.items[self.dyld_info_cmd_index.?].DyldInfo;