| author | |
| committer | |
| log | 7c2cc45ad87b621831ac4b8cada809c2d88cdf0d |
| tree | d831a33e04f90fb27558bce226985095ef981546 |
| parent | a2c546fea30de2caf1efb454d327e70270c07338 |
| parent | e2b6dfa6087f2e63bbc03e0430b73e900c95a193 |
| signature |
macos: improved SDK detection and linker integration with _mh_execute_header5 files changed, 184 insertions(+), 67 deletions(-)
lib/std/zig/system/darwin.zig+71-18| ... | @@ -2,14 +2,34 @@ const std = @import("std"); | ... | @@ -2,14 +2,34 @@ const std = @import("std"); |
| 2 | const mem = std.mem; | 2 | const mem = std.mem; |
| 3 | const Allocator = mem.Allocator; | 3 | const Allocator = mem.Allocator; |
| 4 | const Target = std.Target; | 4 | const Target = std.Target; |
| 5 | const Version = std.builtin.Version; | ||
| 5 | 6 | ||
| 6 | pub const macos = @import("darwin/macos.zig"); | 7 | pub const macos = @import("darwin/macos.zig"); |
| 7 | 8 | ||
| 8 | /// Detect SDK path on Darwin. | 9 | /// Check if SDK is installed on Darwin without triggering CLT installation popup window. |
| 9 | /// Calls `xcrun --sdk <target_sdk> --show-sdk-path` which result can be used to specify | 10 | /// Note: simply invoking `xcrun` will inevitably trigger the CLT installation popup. |
| 10 | /// `--sysroot` of the compiler. | 11 | /// Therefore, we resort to the same tool used by Homebrew, namely, invoking `xcode-select --print-path` |
| 11 | /// The caller needs to free the resulting path slice. | 12 | /// and checking if the status is nonzero or the returned string in nonempty. |
| 12 | pub fn getSDKPath(allocator: *Allocator, target: Target) !?[]u8 { | 13 | /// https://github.com/Homebrew/brew/blob/e119bdc571dcb000305411bc1e26678b132afb98/Library/Homebrew/brew.sh#L630 |
| 14 | pub fn isDarwinSDKInstalled(allocator: *Allocator) bool { | ||
| 15 | const argv = &[_][]const u8{ "/usr/bin/xcode-select", "--print-path" }; | ||
| 16 | const result = std.ChildProcess.exec(.{ .allocator = allocator, .argv = argv }) catch return false; | ||
| 17 | defer { | ||
| 18 | allocator.free(result.stderr); | ||
| 19 | allocator.free(result.stdout); | ||
| 20 | } | ||
| 21 | if (result.stderr.len != 0 or result.term.Exited != 0) { | ||
| 22 | // We don't actually care if there were errors as this is best-effort check anyhow. | ||
| 23 | return false; | ||
| 24 | } | ||
| 25 | return result.stdout.len > 0; | ||
| 26 | } | ||
| 27 | |||
| 28 | /// Detect SDK on Darwin. | ||
| 29 | /// Calls `xcrun --sdk <target_sdk> --show-sdk-path` which fetches the path to the SDK sysroot (if any). | ||
| 30 | /// Subsequently calls `xcrun --sdk <target_sdk> --show-sdk-version` which fetches version of the SDK. | ||
| 31 | /// The caller needs to deinit the resulting struct. | ||
| 32 | pub fn getDarwinSDK(allocator: *Allocator, target: Target) ?DarwinSDK { | ||
| 13 | const is_simulator_abi = target.abi == .simulator; | 33 | const is_simulator_abi = target.abi == .simulator; |
| 14 | const sdk = switch (target.os.tag) { | 34 | const sdk = switch (target.os.tag) { |
| 15 | .macos => "macosx", | 35 | .macos => "macosx", |
| ... | @@ -18,21 +38,54 @@ pub fn getSDKPath(allocator: *Allocator, target: Target) !?[]u8 { | ... | @@ -18,21 +38,54 @@ pub fn getSDKPath(allocator: *Allocator, target: Target) !?[]u8 { |
| 18 | .tvos => if (is_simulator_abi) "appletvsimulator" else "appletvos", | 38 | .tvos => if (is_simulator_abi) "appletvsimulator" else "appletvos", |
| 19 | else => return null, | 39 | else => return null, |
| 20 | }; | 40 | }; |
| 41 | const path = path: { | ||
| 42 | const argv = &[_][]const u8{ "/usr/bin/xcrun", "--sdk", sdk, "--show-sdk-path" }; | ||
| 43 | const result = std.ChildProcess.exec(.{ .allocator = allocator, .argv = argv }) catch return null; | ||
| 44 | defer { | ||
| 45 | allocator.free(result.stderr); | ||
| 46 | allocator.free(result.stdout); | ||
| 47 | } | ||
| 48 | if (result.stderr.len != 0 or result.term.Exited != 0) { | ||
| 49 | // We don't actually care if there were errors as this is best-effort check anyhow | ||
| 50 | // and in the worst case the user can specify the sysroot manually. | ||
| 51 | return null; | ||
| 52 | } | ||
| 53 | const path = allocator.dupe(u8, mem.trimRight(u8, result.stdout, "\r\n")) catch return null; | ||
| 54 | break :path path; | ||
| 55 | }; | ||
| 56 | const version = version: { | ||
| 57 | const argv = &[_][]const u8{ "/usr/bin/xcrun", "--sdk", sdk, "--show-sdk-version" }; | ||
| 58 | const result = std.ChildProcess.exec(.{ .allocator = allocator, .argv = argv }) catch return null; | ||
| 59 | defer { | ||
| 60 | allocator.free(result.stderr); | ||
| 61 | allocator.free(result.stdout); | ||
| 62 | } | ||
| 63 | if (result.stderr.len != 0 or result.term.Exited != 0) { | ||
| 64 | // We don't actually care if there were errors as this is best-effort check anyhow | ||
| 65 | // and in the worst case the user can specify the sysroot manually. | ||
| 66 | return null; | ||
| 67 | } | ||
| 68 | const raw_version = mem.trimRight(u8, result.stdout, "\r\n"); | ||
| 69 | const version = Version.parse(raw_version) catch Version{ | ||
| 70 | .major = 0, | ||
| 71 | .minor = 0, | ||
| 72 | }; | ||
| 73 | break :version version; | ||
| 74 | }; | ||
| 75 | return DarwinSDK{ | ||
| 76 | .path = path, | ||
| 77 | .version = version, | ||
| 78 | }; | ||
| 79 | } | ||
| 21 | 80 | ||
| 22 | const argv = &[_][]const u8{ "xcrun", "--sdk", sdk, "--show-sdk-path" }; | 81 | pub const DarwinSDK = struct { |
| 23 | const result = try std.ChildProcess.exec(.{ .allocator = allocator, .argv = argv }); | 82 | path: []const u8, |
| 24 | defer { | 83 | version: Version, |
| 25 | allocator.free(result.stderr); | 84 | |
| 26 | allocator.free(result.stdout); | 85 | pub fn deinit(self: DarwinSDK, allocator: *Allocator) void { |
| 27 | } | 86 | allocator.free(self.path); |
| 28 | if (result.stderr.len != 0 or result.term.Exited != 0) { | ||
| 29 | // We don't actually care if there were errors as this is best-effort check anyhow | ||
| 30 | // and in the worst case the user can specify the sysroot manually. | ||
| 31 | return null; | ||
| 32 | } | 87 | } |
| 33 | const sysroot = try allocator.dupe(u8, mem.trimRight(u8, result.stdout, "\r\n")); | 88 | }; |
| 34 | return sysroot; | ||
| 35 | } | ||
| 36 | 89 | ||
| 37 | test "" { | 90 | test "" { |
| 38 | _ = @import("darwin/macos.zig"); | 91 | _ = @import("darwin/macos.zig"); |
src/Compilation.zig+53-43| ... | @@ -773,6 +773,8 @@ pub const InitOptions = struct { | ... | @@ -773,6 +773,8 @@ pub const InitOptions = struct { |
| 773 | wasi_exec_model: ?std.builtin.WasiExecModel = null, | 773 | wasi_exec_model: ?std.builtin.WasiExecModel = null, |
| 774 | /// (Zig compiler development) Enable dumping linker's state as JSON. | 774 | /// (Zig compiler development) Enable dumping linker's state as JSON. |
| 775 | enable_link_snapshots: bool = false, | 775 | enable_link_snapshots: bool = false, |
| 776 | /// (Darwin) Path and version of the native SDK if detected. | ||
| 777 | native_darwin_sdk: ?std.zig.system.darwin.DarwinSDK = null, | ||
| 776 | }; | 778 | }; |
| 777 | 779 | ||
| 778 | fn addPackageTableToCacheHash( | 780 | fn addPackageTableToCacheHash( |
| ... | @@ -962,18 +964,11 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { | ... | @@ -962,18 +964,11 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { |
| 962 | break :blk false; | 964 | break :blk false; |
| 963 | }; | 965 | }; |
| 964 | 966 | ||
| 965 | const darwin_use_system_sdk = blk: { | ||
| 966 | if (comptime !builtin.target.isDarwin()) break :blk false; | ||
| 967 | if (!options.is_native_os) break :blk false; | ||
| 968 | if (builtin.os.tag != .macos or !options.target.isDarwin()) break :blk false; | ||
| 969 | break :blk options.frameworks.len > 0 or options.framework_dirs.len > 0; | ||
| 970 | }; | ||
| 971 | |||
| 972 | const sysroot = blk: { | 967 | const sysroot = blk: { |
| 973 | if (options.sysroot) |sysroot| { | 968 | if (options.sysroot) |sysroot| { |
| 974 | break :blk sysroot; | 969 | break :blk sysroot; |
| 975 | } else if (darwin_use_system_sdk) { | 970 | } else if (options.native_darwin_sdk) |sdk| { |
| 976 | break :blk try std.zig.system.darwin.getSDKPath(arena, options.target); | 971 | break :blk sdk.path; |
| 977 | } else { | 972 | } else { |
| 978 | break :blk null; | 973 | break :blk null; |
| 979 | } | 974 | } |
| ... | @@ -1060,6 +1055,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { | ... | @@ -1060,6 +1055,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { |
| 1060 | link_libc, | 1055 | link_libc, |
| 1061 | options.system_lib_names.len != 0 or options.frameworks.len != 0, | 1056 | options.system_lib_names.len != 0 or options.frameworks.len != 0, |
| 1062 | options.libc_installation, | 1057 | options.libc_installation, |
| 1058 | options.native_darwin_sdk != null, | ||
| 1063 | ); | 1059 | ); |
| 1064 | 1060 | ||
| 1065 | const must_pie = target_util.requiresPIE(options.target); | 1061 | const must_pie = target_util.requiresPIE(options.target); |
| ... | @@ -1496,6 +1492,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { | ... | @@ -1496,6 +1492,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { |
| 1496 | .wasi_exec_model = wasi_exec_model, | 1492 | .wasi_exec_model = wasi_exec_model, |
| 1497 | .use_stage1 = use_stage1, | 1493 | .use_stage1 = use_stage1, |
| 1498 | .enable_link_snapshots = options.enable_link_snapshots, | 1494 | .enable_link_snapshots = options.enable_link_snapshots, |
| 1495 | .native_darwin_sdk = options.native_darwin_sdk, | ||
| 1499 | }); | 1496 | }); |
| 1500 | errdefer bin_file.destroy(); | 1497 | errdefer bin_file.destroy(); |
| 1501 | comp.* = .{ | 1498 | comp.* = .{ |
| ... | @@ -3776,6 +3773,37 @@ const LibCDirs = struct { | ... | @@ -3776,6 +3773,37 @@ const LibCDirs = struct { |
| 3776 | libc_installation: ?*const LibCInstallation, | 3773 | libc_installation: ?*const LibCInstallation, |
| 3777 | }; | 3774 | }; |
| 3778 | 3775 | ||
| 3776 | fn getZigShippedLibCIncludeDirsDarwin(arena: *Allocator, zig_lib_dir: []const u8, target: Target) !LibCDirs { | ||
| 3777 | const arch_name = @tagName(target.cpu.arch); | ||
| 3778 | const os_name = try std.fmt.allocPrint(arena, "{s}.{d}", .{ | ||
| 3779 | @tagName(target.os.tag), | ||
| 3780 | target.os.version_range.semver.min.major, | ||
| 3781 | }); | ||
| 3782 | const s = std.fs.path.sep_str; | ||
| 3783 | const list = try arena.alloc([]const u8, 3); | ||
| 3784 | |||
| 3785 | list[0] = try std.fmt.allocPrint( | ||
| 3786 | arena, | ||
| 3787 | "{s}" ++ s ++ "libc" ++ s ++ "include" ++ s ++ "{s}-{s}-gnu", | ||
| 3788 | .{ zig_lib_dir, arch_name, os_name }, | ||
| 3789 | ); | ||
| 3790 | list[1] = try std.fmt.allocPrint( | ||
| 3791 | arena, | ||
| 3792 | "{s}" ++ s ++ "libc" ++ s ++ "include" ++ s ++ "any-{s}-any", | ||
| 3793 | .{ zig_lib_dir, os_name }, | ||
| 3794 | ); | ||
| 3795 | list[2] = try std.fmt.allocPrint( | ||
| 3796 | arena, | ||
| 3797 | "{s}" ++ s ++ "libc" ++ s ++ "include" ++ s ++ "any-macos-any", | ||
| 3798 | .{zig_lib_dir}, | ||
| 3799 | ); | ||
| 3800 | |||
| 3801 | return LibCDirs{ | ||
| 3802 | .libc_include_dir_list = list, | ||
| 3803 | .libc_installation = null, | ||
| 3804 | }; | ||
| 3805 | } | ||
| 3806 | |||
| 3779 | fn detectLibCIncludeDirs( | 3807 | fn detectLibCIncludeDirs( |
| 3780 | arena: *Allocator, | 3808 | arena: *Allocator, |
| 3781 | zig_lib_dir: []const u8, | 3809 | zig_lib_dir: []const u8, |
| ... | @@ -3784,6 +3812,7 @@ fn detectLibCIncludeDirs( | ... | @@ -3784,6 +3812,7 @@ fn detectLibCIncludeDirs( |
| 3784 | link_libc: bool, | 3812 | link_libc: bool, |
| 3785 | link_system_libs: bool, | 3813 | link_system_libs: bool, |
| 3786 | libc_installation: ?*const LibCInstallation, | 3814 | libc_installation: ?*const LibCInstallation, |
| 3815 | has_macos_sdk: bool, | ||
| 3787 | ) !LibCDirs { | 3816 | ) !LibCDirs { |
| 3788 | if (!link_libc) { | 3817 | if (!link_libc) { |
| 3789 | return LibCDirs{ | 3818 | return LibCDirs{ |
| ... | @@ -3800,11 +3829,14 @@ fn detectLibCIncludeDirs( | ... | @@ -3800,11 +3829,14 @@ fn detectLibCIncludeDirs( |
| 3800 | // using the system libc installation. | 3829 | // using the system libc installation. |
| 3801 | if (link_system_libs and is_native_abi and !target.isMinGW()) { | 3830 | if (link_system_libs and is_native_abi and !target.isMinGW()) { |
| 3802 | if (target.isDarwin()) { | 3831 | if (target.isDarwin()) { |
| 3803 | // For Darwin/macOS, we are all set with getSDKPath found earlier. | 3832 | return if (has_macos_sdk) |
| 3804 | return LibCDirs{ | 3833 | // For Darwin/macOS, we are all set with getDarwinSDK found earlier. |
| 3805 | .libc_include_dir_list = &[0][]u8{}, | 3834 | LibCDirs{ |
| 3806 | .libc_installation = null, | 3835 | .libc_include_dir_list = &[0][]u8{}, |
| 3807 | }; | 3836 | .libc_installation = null, |
| 3837 | } | ||
| 3838 | else | ||
| 3839 | getZigShippedLibCIncludeDirsDarwin(arena, zig_lib_dir, target); | ||
| 3808 | } | 3840 | } |
| 3809 | const libc = try arena.create(LibCInstallation); | 3841 | const libc = try arena.create(LibCInstallation); |
| 3810 | libc.* = try LibCInstallation.findNative(.{ .allocator = arena, .verbose = true }); | 3842 | libc.* = try LibCInstallation.findNative(.{ .allocator = arena, .verbose = true }); |
| ... | @@ -3815,36 +3847,14 @@ fn detectLibCIncludeDirs( | ... | @@ -3815,36 +3847,14 @@ fn detectLibCIncludeDirs( |
| 3815 | // default if possible. | 3847 | // default if possible. |
| 3816 | if (target_util.canBuildLibC(target)) { | 3848 | if (target_util.canBuildLibC(target)) { |
| 3817 | switch (target.os.tag) { | 3849 | switch (target.os.tag) { |
| 3818 | .macos => { | 3850 | .macos => return if (has_macos_sdk) |
| 3819 | const arch_name = @tagName(target.cpu.arch); | 3851 | // For Darwin/macOS, we are all set with getDarwinSDK found earlier. |
| 3820 | const os_name = try std.fmt.allocPrint(arena, "{s}.{d}", .{ | 3852 | LibCDirs{ |
| 3821 | @tagName(target.os.tag), | 3853 | .libc_include_dir_list = &[0][]u8{}, |
| 3822 | target.os.version_range.semver.min.major, | ||
| 3823 | }); | ||
| 3824 | const s = std.fs.path.sep_str; | ||
| 3825 | const list = try arena.alloc([]const u8, 3); | ||
| 3826 | |||
| 3827 | list[0] = try std.fmt.allocPrint( | ||
| 3828 | arena, | ||
| 3829 | "{s}" ++ s ++ "libc" ++ s ++ "include" ++ s ++ "{s}-{s}-gnu", | ||
| 3830 | .{ zig_lib_dir, arch_name, os_name }, | ||
| 3831 | ); | ||
| 3832 | list[1] = try std.fmt.allocPrint( | ||
| 3833 | arena, | ||
| 3834 | "{s}" ++ s ++ "libc" ++ s ++ "include" ++ s ++ "any-{s}-any", | ||
| 3835 | .{ zig_lib_dir, os_name }, | ||
| 3836 | ); | ||
| 3837 | list[2] = try std.fmt.allocPrint( | ||
| 3838 | arena, | ||
| 3839 | "{s}" ++ s ++ "libc" ++ s ++ "include" ++ s ++ "any-macos-any", | ||
| 3840 | .{zig_lib_dir}, | ||
| 3841 | ); | ||
| 3842 | |||
| 3843 | return LibCDirs{ | ||
| 3844 | .libc_include_dir_list = list, | ||
| 3845 | .libc_installation = null, | 3854 | .libc_installation = null, |
| 3846 | }; | 3855 | } |
| 3847 | }, | 3856 | else |
| 3857 | getZigShippedLibCIncludeDirsDarwin(arena, zig_lib_dir, target), | ||
| 3848 | else => { | 3858 | else => { |
| 3849 | const generic_name = target_util.libCGenericName(target); | 3859 | const generic_name = target_util.libCGenericName(target); |
| 3850 | // Some architectures are handled by the same set of headers. | 3860 | // Some architectures are handled by the same set of headers. |
src/link.zig+3| ... | @@ -153,6 +153,9 @@ pub const Options = struct { | ... | @@ -153,6 +153,9 @@ pub const Options = struct { |
| 153 | /// (Zig compiler development) Enable dumping of linker's state as JSON. | 153 | /// (Zig compiler development) Enable dumping of linker's state as JSON. |
| 154 | enable_link_snapshots: bool = false, | 154 | enable_link_snapshots: bool = false, |
| 155 | 155 | ||
| 156 | /// (Darwin) Path and version of the native SDK if detected. | ||
| 157 | native_darwin_sdk: ?std.zig.system.darwin.DarwinSDK = null, | ||
| 158 | |||
| 156 | pub fn effectiveOutputMode(options: Options) std.builtin.OutputMode { | 159 | pub fn effectiveOutputMode(options: Options) std.builtin.OutputMode { |
| 157 | return if (options.use_lld) .Obj else options.output_mode; | 160 | return if (options.use_lld) .Obj else options.output_mode; |
| 158 | } | 161 | } |
src/link/MachO.zig+50-4| ... | @@ -154,6 +154,7 @@ tentatives: std.AutoArrayHashMapUnmanaged(u32, void) = .{}, | ... | @@ -154,6 +154,7 @@ tentatives: std.AutoArrayHashMapUnmanaged(u32, void) = .{}, |
| 154 | locals_free_list: std.ArrayListUnmanaged(u32) = .{}, | 154 | locals_free_list: std.ArrayListUnmanaged(u32) = .{}, |
| 155 | globals_free_list: std.ArrayListUnmanaged(u32) = .{}, | 155 | globals_free_list: std.ArrayListUnmanaged(u32) = .{}, |
| 156 | 156 | ||
| 157 | mh_execute_header_index: ?u32 = null, | ||
| 157 | dyld_stub_binder_index: ?u32 = null, | 158 | dyld_stub_binder_index: ?u32 = null, |
| 158 | dyld_private_atom: ?*Atom = null, | 159 | dyld_private_atom: ?*Atom = null, |
| 159 | stub_helper_preamble_atom: ?*Atom = null, | 160 | stub_helper_preamble_atom: ?*Atom = null, |
| ... | @@ -863,6 +864,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void { | ... | @@ -863,6 +864,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void { |
| 863 | sect.offset = self.tlv_bss_file_offset; | 864 | sect.offset = self.tlv_bss_file_offset; |
| 864 | } | 865 | } |
| 865 | 866 | ||
| 867 | try self.createMhExecuteHeaderAtom(); | ||
| 866 | for (self.objects.items) |*object, object_id| { | 868 | for (self.objects.items) |*object, object_id| { |
| 867 | if (object.analyzed) continue; | 869 | if (object.analyzed) continue; |
| 868 | try self.resolveSymbolsInObject(@intCast(u16, object_id)); | 870 | try self.resolveSymbolsInObject(@intCast(u16, object_id)); |
| ... | @@ -2725,6 +2727,42 @@ fn resolveSymbolsInDylibs(self: *MachO) !void { | ... | @@ -2725,6 +2727,42 @@ fn resolveSymbolsInDylibs(self: *MachO) !void { |
| 2725 | } | 2727 | } |
| 2726 | } | 2728 | } |
| 2727 | 2729 | ||
| 2730 | fn createMhExecuteHeaderAtom(self: *MachO) !void { | ||
| 2731 | if (self.mh_execute_header_index != null) return; | ||
| 2732 | |||
| 2733 | const match: MatchingSection = .{ | ||
| 2734 | .seg = self.text_segment_cmd_index.?, | ||
| 2735 | .sect = self.text_section_index.?, | ||
| 2736 | }; | ||
| 2737 | const n_strx = try self.makeString("__mh_execute_header"); | ||
| 2738 | const local_sym_index = @intCast(u32, self.locals.items.len); | ||
| 2739 | var nlist = macho.nlist_64{ | ||
| 2740 | .n_strx = n_strx, | ||
| 2741 | .n_type = macho.N_SECT, | ||
| 2742 | .n_sect = @intCast(u8, self.section_ordinals.getIndex(match).? + 1), | ||
| 2743 | .n_desc = 0, | ||
| 2744 | .n_value = 0, | ||
| 2745 | }; | ||
| 2746 | try self.locals.append(self.base.allocator, nlist); | ||
| 2747 | |||
| 2748 | nlist.n_type |= macho.N_EXT; | ||
| 2749 | const global_sym_index = @intCast(u32, self.globals.items.len); | ||
| 2750 | try self.globals.append(self.base.allocator, nlist); | ||
| 2751 | try self.symbol_resolver.putNoClobber(self.base.allocator, n_strx, .{ | ||
| 2752 | .where = .global, | ||
| 2753 | .where_index = global_sym_index, | ||
| 2754 | .local_sym_index = local_sym_index, | ||
| 2755 | .file = null, | ||
| 2756 | }); | ||
| 2757 | |||
| 2758 | const atom = try self.createEmptyAtom(local_sym_index, 0, 0); | ||
| 2759 | const sym = &self.locals.items[local_sym_index]; | ||
| 2760 | const vaddr = try self.allocateAtom(atom, 0, 1, match); | ||
| 2761 | sym.n_value = vaddr; | ||
| 2762 | atom.dirty = false; | ||
| 2763 | self.mh_execute_header_index = local_sym_index; | ||
| 2764 | } | ||
| 2765 | |||
| 2728 | fn resolveDyldStubBinder(self: *MachO) !void { | 2766 | fn resolveDyldStubBinder(self: *MachO) !void { |
| 2729 | if (self.dyld_stub_binder_index != null) return; | 2767 | if (self.dyld_stub_binder_index != null) return; |
| 2730 | 2768 | ||
| ... | @@ -4077,8 +4115,16 @@ pub fn populateMissingMetadata(self: *MachO) !void { | ... | @@ -4077,8 +4115,16 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 4077 | @sizeOf(macho.build_version_command) + @sizeOf(macho.build_tool_version), | 4115 | @sizeOf(macho.build_version_command) + @sizeOf(macho.build_tool_version), |
| 4078 | @sizeOf(u64), | 4116 | @sizeOf(u64), |
| 4079 | )); | 4117 | )); |
| 4080 | const ver = self.base.options.target.os.version_range.semver.min; | 4118 | const platform_version = blk: { |
| 4081 | const version = ver.major << 16 | ver.minor << 8 | ver.patch; | 4119 | const ver = self.base.options.target.os.version_range.semver.min; |
| 4120 | const platform_version = ver.major << 16 | ver.minor << 8; | ||
| 4121 | break :blk platform_version; | ||
| 4122 | }; | ||
| 4123 | const sdk_version = if (self.base.options.native_darwin_sdk) |sdk| blk: { | ||
| 4124 | const ver = sdk.version; | ||
| 4125 | const sdk_version = ver.major << 16 | ver.minor << 8; | ||
| 4126 | break :blk sdk_version; | ||
| 4127 | } else platform_version; | ||
| 4082 | const is_simulator_abi = self.base.options.target.abi == .simulator; | 4128 | const is_simulator_abi = self.base.options.target.abi == .simulator; |
| 4083 | var cmd = commands.emptyGenericCommandWithData(macho.build_version_command{ | 4129 | var cmd = commands.emptyGenericCommandWithData(macho.build_version_command{ |
| 4084 | .cmd = macho.LC_BUILD_VERSION, | 4130 | .cmd = macho.LC_BUILD_VERSION, |
| ... | @@ -4090,8 +4136,8 @@ pub fn populateMissingMetadata(self: *MachO) !void { | ... | @@ -4090,8 +4136,8 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 4090 | .tvos => if (is_simulator_abi) macho.PLATFORM_TVOSSIMULATOR else macho.PLATFORM_TVOS, | 4136 | .tvos => if (is_simulator_abi) macho.PLATFORM_TVOSSIMULATOR else macho.PLATFORM_TVOS, |
| 4091 | else => unreachable, | 4137 | else => unreachable, |
| 4092 | }, | 4138 | }, |
| 4093 | .minos = version, | 4139 | .minos = platform_version, |
| 4094 | .sdk = version, | 4140 | .sdk = sdk_version, |
| 4095 | .ntools = 1, | 4141 | .ntools = 1, |
| 4096 | }); | 4142 | }); |
| 4097 | const ld_ver = macho.build_tool_version{ | 4143 | const ld_ver = macho.build_tool_version{ |
src/main.zig+7-2| ... | @@ -663,6 +663,7 @@ fn buildOutputType( | ... | @@ -663,6 +663,7 @@ fn buildOutputType( |
| 663 | var minor_subsystem_version: ?u32 = null; | 663 | var minor_subsystem_version: ?u32 = null; |
| 664 | var wasi_exec_model: ?std.builtin.WasiExecModel = null; | 664 | var wasi_exec_model: ?std.builtin.WasiExecModel = null; |
| 665 | var enable_link_snapshots: bool = false; | 665 | var enable_link_snapshots: bool = false; |
| 666 | var native_darwin_sdk: ?std.zig.system.darwin.DarwinSDK = null; | ||
| 666 | 667 | ||
| 667 | var system_libs = std.StringArrayHashMap(Compilation.SystemLib).init(gpa); | 668 | var system_libs = std.StringArrayHashMap(Compilation.SystemLib).init(gpa); |
| 668 | defer system_libs.deinit(); | 669 | defer system_libs.deinit(); |
| ... | @@ -1857,10 +1858,13 @@ fn buildOutputType( | ... | @@ -1857,10 +1858,13 @@ fn buildOutputType( |
| 1857 | } | 1858 | } |
| 1858 | 1859 | ||
| 1859 | const has_sysroot = if (comptime builtin.target.isDarwin()) outer: { | 1860 | const has_sysroot = if (comptime builtin.target.isDarwin()) outer: { |
| 1860 | if (try std.zig.system.darwin.getSDKPath(arena, target_info.target)) |sdk_path| { | 1861 | if (std.zig.system.darwin.isDarwinSDKInstalled(arena)) { |
| 1862 | const sdk = std.zig.system.darwin.getDarwinSDK(arena, target_info.target) orelse | ||
| 1863 | break :outer false; | ||
| 1864 | native_darwin_sdk = sdk; | ||
| 1861 | try clang_argv.ensureUnusedCapacity(2); | 1865 | try clang_argv.ensureUnusedCapacity(2); |
| 1862 | clang_argv.appendAssumeCapacity("-isysroot"); | 1866 | clang_argv.appendAssumeCapacity("-isysroot"); |
| 1863 | clang_argv.appendAssumeCapacity(sdk_path); | 1867 | clang_argv.appendAssumeCapacity(sdk.path); |
| 1864 | break :outer true; | 1868 | break :outer true; |
| 1865 | } else break :outer false; | 1869 | } else break :outer false; |
| 1866 | } else false; | 1870 | } else false; |
| ... | @@ -2340,6 +2344,7 @@ fn buildOutputType( | ... | @@ -2340,6 +2344,7 @@ fn buildOutputType( |
| 2340 | .wasi_exec_model = wasi_exec_model, | 2344 | .wasi_exec_model = wasi_exec_model, |
| 2341 | .debug_compile_errors = debug_compile_errors, | 2345 | .debug_compile_errors = debug_compile_errors, |
| 2342 | .enable_link_snapshots = enable_link_snapshots, | 2346 | .enable_link_snapshots = enable_link_snapshots, |
| 2347 | .native_darwin_sdk = native_darwin_sdk, | ||
| 2343 | }) catch |err| { | 2348 | }) catch |err| { |
| 2344 | fatal("unable to create compilation: {s}", .{@errorName(err)}); | 2349 | fatal("unable to create compilation: {s}", .{@errorName(err)}); |
| 2345 | }; | 2350 | }; |