authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-08-05 16:57:59+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-08-10 13:41:10+02:00
log700768498488dbae1c737b484f330b86f116cb62
tree0cdad2422e62753dfe9b38599c1fe864c7e2f375
parentace9b3de642ab89dd356d877ee6b46ce88640e1d

macho: swap out VERSION_MIN for BUILD_VERSION

this makes the app successfully run on the iOS simluator!

4 files changed, 87 insertions(+), 38 deletions(-)

lib/std/macho.zig+15
...@@ -116,6 +116,21 @@ pub const build_tool_version = extern struct {...@@ -116,6 +116,21 @@ pub const build_tool_version = extern struct {
116 version: u32,116 version: u32,
117};117};
118118
119pub const PLATFORM_MACOS: u32 = 0x1;
120pub const PLATFORM_IOS: u32 = 0x2;
121pub const PLATFORM_TVOS: u32 = 0x3;
122pub const PLATFORM_WATCHOS: u32 = 0x4;
123pub const PLATFORM_BRIDGEOS: u32 = 0x5;
124pub const PLATFORM_MACCATALYST: u32 = 0x6;
125pub const PLATFORM_IOSSIMULATOR: u32 = 0x7;
126pub const PLATFORM_TVOSSIMULATOR: u32 = 0x8;
127pub const PLATFORM_WATCHOSSIMULATOR: u32 = 0x9;
128pub const PLATFORM_DRIVERKIT: u32 = 0x10;
129
130pub const TOOL_CLANG: u32 = 0x1;
131pub const TOOL_SWIFT: u32 = 0x2;
132pub const TOOL_LD: u32 = 0x3;
133
119/// The entry_point_command is a replacement for thread_command.134/// The entry_point_command is a replacement for thread_command.
120/// It is used for main executables to specify the location (file offset)135/// It is used for main executables to specify the location (file offset)
121/// of main(). If -stack_size was used at link time, the stacksize136/// of main(). If -stack_size was used at link time, the stacksize
src/link/MachO.zig+61-38
...@@ -82,8 +82,8 @@ data_in_code_cmd_index: ?u16 = null,...@@ -82,8 +82,8 @@ data_in_code_cmd_index: ?u16 = null,
82function_starts_cmd_index: ?u16 = null,82function_starts_cmd_index: ?u16 = null,
83main_cmd_index: ?u16 = null,83main_cmd_index: ?u16 = null,
84dylib_id_cmd_index: ?u16 = null,84dylib_id_cmd_index: ?u16 = null,
85version_min_cmd_index: ?u16 = null,
86source_version_cmd_index: ?u16 = null,85source_version_cmd_index: ?u16 = null,
86build_version_cmd_index: ?u16 = null,
87uuid_cmd_index: ?u16 = null,87uuid_cmd_index: ?u16 = null,
88code_signature_cmd_index: ?u16 = null,88code_signature_cmd_index: ?u16 = null,
89/// Path to libSystem89/// Path to libSystem
...@@ -2716,27 +2716,6 @@ fn populateMetadata(self: *MachO) !void {...@@ -2716,27 +2716,6 @@ fn populateMetadata(self: *MachO) !void {
2716 try self.load_commands.append(self.base.allocator, .{ .Dylib = dylib_cmd });2716 try self.load_commands.append(self.base.allocator, .{ .Dylib = dylib_cmd });
2717 }2717 }
27182718
2719 if (self.version_min_cmd_index == null) {
2720 self.version_min_cmd_index = @intCast(u16, self.load_commands.items.len);
2721 const cmd: u32 = switch (self.base.options.target.os.tag) {
2722 .macos => macho.LC_VERSION_MIN_MACOSX,
2723 .ios => macho.LC_VERSION_MIN_IPHONEOS,
2724 .tvos => macho.LC_VERSION_MIN_TVOS,
2725 .watchos => macho.LC_VERSION_MIN_WATCHOS,
2726 else => unreachable, // wrong OS
2727 };
2728 const ver = self.base.options.target.os.version_range.semver.min;
2729 const version = ver.major << 16 | ver.minor << 8 | ver.patch;
2730 try self.load_commands.append(self.base.allocator, .{
2731 .VersionMin = .{
2732 .cmd = cmd,
2733 .cmdsize = @sizeOf(macho.version_min_command),
2734 .version = version,
2735 .sdk = version,
2736 },
2737 });
2738 }
2739
2740 if (self.source_version_cmd_index == null) {2719 if (self.source_version_cmd_index == null) {
2741 self.source_version_cmd_index = @intCast(u16, self.load_commands.items.len);2720 self.source_version_cmd_index = @intCast(u16, self.load_commands.items.len);
2742 try self.load_commands.append(self.base.allocator, .{2721 try self.load_commands.append(self.base.allocator, .{
...@@ -2748,6 +2727,39 @@ fn populateMetadata(self: *MachO) !void {...@@ -2748,6 +2727,39 @@ fn populateMetadata(self: *MachO) !void {
2748 });2727 });
2749 }2728 }
27502729
2730 if (self.build_version_cmd_index == null) {
2731 self.build_version_cmd_index = @intCast(u16, self.load_commands.items.len);
2732 const cmdsize = @intCast(u32, mem.alignForwardGeneric(
2733 u64,
2734 @sizeOf(macho.build_version_command) + @sizeOf(macho.build_tool_version),
2735 @sizeOf(u64),
2736 ));
2737 const ver = self.base.options.target.os.version_range.semver.min;
2738 const version = ver.major << 16 | ver.minor << 8 | ver.patch;
2739 var cmd = commands.emptyGenericCommandWithData(macho.build_version_command{
2740 .cmd = macho.LC_BUILD_VERSION,
2741 .cmdsize = cmdsize,
2742 .platform = switch (self.base.options.target.os.tag) {
2743 .macos => macho.PLATFORM_MACOS,
2744 .ios => macho.PLATFORM_IOSSIMULATOR,
2745 .watchos => macho.PLATFORM_WATCHOS,
2746 .tvos => macho.PLATFORM_TVOS,
2747 else => unreachable,
2748 },
2749 .minos = version,
2750 .sdk = version,
2751 .ntools = 1,
2752 });
2753 const ld_ver = macho.build_tool_version{
2754 .tool = macho.TOOL_LD,
2755 .version = 0x0,
2756 };
2757 cmd.data = try self.base.allocator.alloc(u8, cmdsize - @sizeOf(macho.build_version_command));
2758 mem.set(u8, cmd.data, 0);
2759 mem.copy(u8, cmd.data, mem.asBytes(&ld_ver));
2760 try self.load_commands.append(self.base.allocator, .{ .BuildVersion = cmd });
2761 }
2762
2751 if (self.uuid_cmd_index == null) {2763 if (self.uuid_cmd_index == null) {
2752 self.uuid_cmd_index = @intCast(u16, self.load_commands.items.len);2764 self.uuid_cmd_index = @intCast(u16, self.load_commands.items.len);
2753 var uuid_cmd: macho.uuid_command = .{2765 var uuid_cmd: macho.uuid_command = .{
...@@ -4334,26 +4346,37 @@ pub fn populateMissingMetadata(self: *MachO) !void {...@@ -4334,26 +4346,37 @@ pub fn populateMissingMetadata(self: *MachO) !void {
4334 });4346 });
4335 self.load_commands_dirty = true;4347 self.load_commands_dirty = true;
4336 }4348 }
4337 if (self.version_min_cmd_index == null) {4349 if (self.build_version_cmd_index == null) {
4338 self.version_min_cmd_index = @intCast(u16, self.load_commands.items.len);4350 self.build_version_cmd_index = @intCast(u16, self.load_commands.items.len);
4339 const cmd: u32 = switch (self.base.options.target.os.tag) {4351 const cmdsize = @intCast(u32, mem.alignForwardGeneric(
4340 .macos => macho.LC_VERSION_MIN_MACOSX,4352 u64,
4341 .ios => macho.LC_VERSION_MIN_IPHONEOS,4353 @sizeOf(macho.build_version_command) + @sizeOf(macho.build_tool_version),
4342 .tvos => macho.LC_VERSION_MIN_TVOS,4354 @sizeOf(u64),
4343 .watchos => macho.LC_VERSION_MIN_WATCHOS,4355 ));
4344 else => unreachable, // wrong OS
4345 };
4346 const ver = self.base.options.target.os.version_range.semver.min;4356 const ver = self.base.options.target.os.version_range.semver.min;
4347 const version = ver.major << 16 | ver.minor << 8 | ver.patch;4357 const version = ver.major << 16 | ver.minor << 8 | ver.patch;
4348 try self.load_commands.append(self.base.allocator, .{4358 var cmd = commands.emptyGenericCommandWithData(macho.build_version_command{
4349 .VersionMin = .{4359 .cmd = macho.LC_BUILD_VERSION,
4350 .cmd = cmd,4360 .cmdsize = cmdsize,
4351 .cmdsize = @sizeOf(macho.version_min_command),4361 .platform = switch (self.base.options.target.os.tag) {
4352 .version = version,4362 .macos => macho.PLATFORM_MACOS,
4353 .sdk = version,4363 .ios => macho.PLATFORM_IOSSIMULATOR,
4364 .watchos => macho.PLATFORM_WATCHOS,
4365 .tvos => macho.PLATFORM_TVOS,
4366 else => unreachable,
4354 },4367 },
4368 .minos = version,
4369 .sdk = version,
4370 .ntools = 1,
4355 });4371 });
4356 self.load_commands_dirty = true;4372 const ld_ver = macho.build_tool_version{
4373 .tool = macho.TOOL_LD,
4374 .version = 0x0,
4375 };
4376 cmd.data = try self.base.allocator.alloc(u8, cmdsize - @sizeOf(macho.build_version_command));
4377 mem.set(u8, cmd.data, 0);
4378 mem.copy(u8, cmd.data, mem.asBytes(&ld_ver));
4379 try self.load_commands.append(self.base.allocator, .{ .BuildVersion = cmd });
4357 }4380 }
4358 if (self.source_version_cmd_index == null) {4381 if (self.source_version_cmd_index == null) {
4359 self.source_version_cmd_index = @intCast(u16, self.load_commands.items.len);4382 self.source_version_cmd_index = @intCast(u16, self.load_commands.items.len);
src/link/MachO/Dylib.zig+3
...@@ -340,6 +340,9 @@ fn targetToAppleString(allocator: *Allocator, target: std.Target) ![]const u8 {...@@ -340,6 +340,9 @@ fn targetToAppleString(allocator: *Allocator, target: std.Target) ![]const u8 {
340 .x86_64 => "x86_64",340 .x86_64 => "x86_64",
341 else => unreachable,341 else => unreachable,
342 };342 };
343 if (target.os.tag == .ios) {
344 return std.fmt.allocPrint(allocator, "{s}-{s}-simulator", .{ arch, @tagName(target.os.tag) });
345 }
343 return std.fmt.allocPrint(allocator, "{s}-{s}", .{ arch, @tagName(target.os.tag) });346 return std.fmt.allocPrint(allocator, "{s}-{s}", .{ arch, @tagName(target.os.tag) });
344}347}
345348
src/link/MachO/commands.zig+8
...@@ -43,6 +43,7 @@ pub const LoadCommand = union(enum) {...@@ -43,6 +43,7 @@ pub const LoadCommand = union(enum) {
43 Main: macho.entry_point_command,43 Main: macho.entry_point_command,
44 VersionMin: macho.version_min_command,44 VersionMin: macho.version_min_command,
45 SourceVersion: macho.source_version_command,45 SourceVersion: macho.source_version_command,
46 BuildVersion: GenericCommandWithData(macho.build_version_command),
46 Uuid: macho.uuid_command,47 Uuid: macho.uuid_command,
47 LinkeditData: macho.linkedit_data_command,48 LinkeditData: macho.linkedit_data_command,
48 Rpath: GenericCommandWithData(macho.rpath_command),49 Rpath: GenericCommandWithData(macho.rpath_command),
...@@ -97,6 +98,9 @@ pub const LoadCommand = union(enum) {...@@ -97,6 +98,9 @@ pub const LoadCommand = union(enum) {
97 macho.LC_SOURCE_VERSION => LoadCommand{98 macho.LC_SOURCE_VERSION => LoadCommand{
98 .SourceVersion = try stream.reader().readStruct(macho.source_version_command),99 .SourceVersion = try stream.reader().readStruct(macho.source_version_command),
99 },100 },
101 macho.LC_BUILD_VERSION => LoadCommand{
102 .BuildVersion = try GenericCommandWithData(macho.build_version_command).read(allocator, stream.reader()),
103 },
100 macho.LC_UUID => LoadCommand{104 macho.LC_UUID => LoadCommand{
101 .Uuid = try stream.reader().readStruct(macho.uuid_command),105 .Uuid = try stream.reader().readStruct(macho.uuid_command),
102 },106 },
...@@ -129,6 +133,7 @@ pub const LoadCommand = union(enum) {...@@ -129,6 +133,7 @@ pub const LoadCommand = union(enum) {
129 .Dylinker => |x| x.write(writer),133 .Dylinker => |x| x.write(writer),
130 .Dylib => |x| x.write(writer),134 .Dylib => |x| x.write(writer),
131 .Rpath => |x| x.write(writer),135 .Rpath => |x| x.write(writer),
136 .BuildVersion => |x| x.write(writer),
132 .Unknown => |x| x.write(writer),137 .Unknown => |x| x.write(writer),
133 };138 };
134 }139 }
...@@ -147,6 +152,7 @@ pub const LoadCommand = union(enum) {...@@ -147,6 +152,7 @@ pub const LoadCommand = union(enum) {
147 .Dylinker => |x| x.inner.cmd,152 .Dylinker => |x| x.inner.cmd,
148 .Dylib => |x| x.inner.cmd,153 .Dylib => |x| x.inner.cmd,
149 .Rpath => |x| x.inner.cmd,154 .Rpath => |x| x.inner.cmd,
155 .BuildVersion => |x| x.inner.cmd,
150 .Unknown => |x| x.inner.cmd,156 .Unknown => |x| x.inner.cmd,
151 };157 };
152 }158 }
...@@ -165,6 +171,7 @@ pub const LoadCommand = union(enum) {...@@ -165,6 +171,7 @@ pub const LoadCommand = union(enum) {
165 .Dylinker => |x| x.inner.cmdsize,171 .Dylinker => |x| x.inner.cmdsize,
166 .Dylib => |x| x.inner.cmdsize,172 .Dylib => |x| x.inner.cmdsize,
167 .Rpath => |x| x.inner.cmdsize,173 .Rpath => |x| x.inner.cmdsize,
174 .BuildVersion => |x| x.inner.cmdsize,
168 .Unknown => |x| x.inner.cmdsize,175 .Unknown => |x| x.inner.cmdsize,
169 };176 };
170 }177 }
...@@ -193,6 +200,7 @@ pub const LoadCommand = union(enum) {...@@ -193,6 +200,7 @@ pub const LoadCommand = union(enum) {
193 .Main => |x| meta.eql(x, other.Main),200 .Main => |x| meta.eql(x, other.Main),
194 .VersionMin => |x| meta.eql(x, other.VersionMin),201 .VersionMin => |x| meta.eql(x, other.VersionMin),
195 .SourceVersion => |x| meta.eql(x, other.SourceVersion),202 .SourceVersion => |x| meta.eql(x, other.SourceVersion),
203 .BuildVersion => |x| x.eql(other.BuildVersion),
196 .Uuid => |x| meta.eql(x, other.Uuid),204 .Uuid => |x| meta.eql(x, other.Uuid),
197 .LinkeditData => |x| meta.eql(x, other.LinkeditData),205 .LinkeditData => |x| meta.eql(x, other.LinkeditData),
198 .Segment => |x| x.eql(other.Segment),206 .Segment => |x| x.eql(other.Segment),