| ... | @@ -707,34 +707,36 @@ pub const TargetMatcher = struct { | ... | @@ -707,34 +707,36 @@ pub const TargetMatcher = struct { |
| 707 | .cpu_arch = cpu_arch, | 707 | .cpu_arch = cpu_arch, |
| 708 | .platform = platform, | 708 | .platform = platform, |
| 709 | }; | 709 | }; |
| 710 | const apple_string = try targetToAppleString(allocator, cpu_arch, platform); | | |
| 711 | try self.target_strings.append(allocator, apple_string); | | |
| 712 | | 710 | |
| 713 | switch (platform) { | 711 | try self.addTargetStrings(cpuArchToAppleString(cpu_arch)); |
| 714 | .IOSSIMULATOR, .TVOSSIMULATOR, .WATCHOSSIMULATOR, .VISIONOSSIMULATOR => { | 712 | // In Xcode 26.4, Apple unified their TBD files from having separate `arm64-macos` and `arm64e-macos` |
| 715 | // For Apple simulator targets, linking gets tricky as we need to link against the simulator | 713 | // entries to having just the latter, presumably because the symbol lists are identical anyway. It |
| 716 | // hosts dylibs too. | 714 | // sure would have been nice if they settled on the former as the unified name so as not to break the |
| 717 | const host_target = try targetToAppleString(allocator, cpu_arch, .MACOS); | 715 | // world, but evidently we can't have nice things. |
| 718 | try self.target_strings.append(allocator, host_target); | 716 | if (cpu_arch == .aarch64) try self.addTargetStrings("arm64e"); |
| 719 | }, | 717 | |
| | 718 | return self; |
| | 719 | } |
| | 720 | |
| | 721 | fn addTargetStrings(self: *TargetMatcher, arch: []const u8) !void { |
| | 722 | try self.target_strings.append(self.allocator, try std.fmt.allocPrint( |
| | 723 | self.allocator, |
| | 724 | "{s}-{s}", |
| | 725 | .{ arch, platformToAppleString(self.platform) }, |
| | 726 | )); |
| | 727 | |
| | 728 | switch (self.platform) { |
| 720 | .MACCATALYST => { | 729 | .MACCATALYST => { |
| 721 | // Mac Catalyst is allowed to link macOS libraries in a TBD because Apple were apparently too lazy | 730 | // Mac Catalyst is allowed to link macOS libraries in a TBD because Apple were apparently too lazy |
| 722 | // to add the proper target strings despite doing so in other places in the format??? | 731 | // to add the proper target strings despite doing so in other places in the format??? |
| 723 | try self.target_strings.append(allocator, try targetToAppleString(allocator, cpu_arch, .MACOS)); | 732 | try self.target_strings.append(self.allocator, try std.fmt.allocPrint(self.allocator, "{s}-macos", .{arch})); |
| 724 | }, | 733 | }, |
| 725 | .MACOS => { | 734 | .IOSSIMULATOR, .TVOSSIMULATOR, .WATCHOSSIMULATOR, .VISIONOSSIMULATOR => { |
| 726 | // Turns out that around 10.13/10.14 macOS release version, Apple changed the target tags in | 735 | // For Apple simulator targets, we need to link against the simulator host's libraries too. |
| 727 | // tbd files from `macosx` to `macos`. In order to be compliant and therefore actually support | 736 | try self.target_strings.append(self.allocator, try std.fmt.allocPrint(self.allocator, "{s}-macos", .{arch})); |
| 728 | // linking on older platforms against `libSystem.tbd`, we add `<cpu_arch>-macosx` to target_strings. | | |
| 729 | const fallback_target = try std.fmt.allocPrint(allocator, "{s}-macosx", .{ | | |
| 730 | cpuArchToAppleString(cpu_arch), | | |
| 731 | }); | | |
| 732 | try self.target_strings.append(allocator, fallback_target); | | |
| 733 | }, | 737 | }, |
| 734 | else => {}, | 738 | else => {}, |
| 735 | } | 739 | } |
| 736 | | | |
| 737 | return self; | | |
| 738 | } | 740 | } |
| 739 | | 741 | |
| 740 | pub fn deinit(self: *TargetMatcher) void { | 742 | pub fn deinit(self: *TargetMatcher) void { |
| ... | @@ -744,7 +746,7 @@ pub const TargetMatcher = struct { | ... | @@ -744,7 +746,7 @@ pub const TargetMatcher = struct { |
| 744 | self.target_strings.deinit(self.allocator); | 746 | self.target_strings.deinit(self.allocator); |
| 745 | } | 747 | } |
| 746 | | 748 | |
| 747 | inline fn cpuArchToAppleString(cpu_arch: std.Target.Cpu.Arch) []const u8 { | 749 | fn cpuArchToAppleString(cpu_arch: std.Target.Cpu.Arch) []const u8 { |
| 748 | return switch (cpu_arch) { | 750 | return switch (cpu_arch) { |
| 749 | .aarch64 => "arm64", | 751 | .aarch64 => "arm64", |
| 750 | .x86_64 => "x86_64", | 752 | .x86_64 => "x86_64", |
| ... | @@ -752,9 +754,8 @@ pub const TargetMatcher = struct { | ... | @@ -752,9 +754,8 @@ pub const TargetMatcher = struct { |
| 752 | }; | 754 | }; |
| 753 | } | 755 | } |
| 754 | | 756 | |
| 755 | pub fn targetToAppleString(allocator: Allocator, cpu_arch: std.Target.Cpu.Arch, platform: macho.PLATFORM) ![]const u8 { | 757 | fn platformToAppleString(platform: macho.PLATFORM) []const u8 { |
| 756 | const arch = cpuArchToAppleString(cpu_arch); | 758 | return switch (platform) { |
| 757 | const plat = switch (platform) { | | |
| 758 | .MACOS => "macos", | 759 | .MACOS => "macos", |
| 759 | .IOS => "ios", | 760 | .IOS => "ios", |
| 760 | .TVOS => "tvos", | 761 | .TVOS => "tvos", |
| ... | @@ -769,7 +770,6 @@ pub const TargetMatcher = struct { | ... | @@ -769,7 +770,6 @@ pub const TargetMatcher = struct { |
| 769 | .DRIVERKIT => "driverkit", | 770 | .DRIVERKIT => "driverkit", |
| 770 | else => unreachable, | 771 | else => unreachable, |
| 771 | }; | 772 | }; |
| 772 | return std.fmt.allocPrint(allocator, "{s}-{s}", .{ arch, plat }); | | |
| 773 | } | 773 | } |
| 774 | | 774 | |
| 775 | fn hasValue(stack: []const []const u8, needle: []const u8) bool { | 775 | fn hasValue(stack: []const []const u8, needle: []const u8) bool { |