From 02d8ca71f98800df08754ce3d2d2e39541178f64 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Fri, 26 Nov 2021 12:44:49 +0100 Subject: [PATCH 1/4] macos: always use Zig shipped libc headers when no native SDK If Zig didn't detect native SDK, always use shipped libc headers when targeting macOS. --- src/Compilation.zig | 90 +++++++++++++++++++++++---------------------- src/main.zig | 3 ++ 2 files changed, 49 insertions(+), 44 deletions(-) diff --git a/src/Compilation.zig b/src/Compilation.zig index 64e08c62be073fd12e8a5dfc8f8507f8a15242d7..0d299d6572a87c330d11306dd1cacf7af4d01ebc 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -773,6 +773,8 @@ pub const InitOptions = struct { wasi_exec_model: ?std.builtin.WasiExecModel = null, /// (Zig compiler development) Enable dumping linker's state as JSON. enable_link_snapshots: bool = false, + /// (Darwin). Path to native macOS SDK if detected. + native_macos_sdk_path: ?[]const u8 = null, }; fn addPackageTableToCacheHash( @@ -962,18 +964,11 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { break :blk false; }; - const darwin_use_system_sdk = blk: { - if (comptime !builtin.target.isDarwin()) break :blk false; - if (!options.is_native_os) break :blk false; - if (builtin.os.tag != .macos or !options.target.isDarwin()) break :blk false; - break :blk options.frameworks.len > 0 or options.framework_dirs.len > 0; - }; - const sysroot = blk: { if (options.sysroot) |sysroot| { break :blk sysroot; - } else if (darwin_use_system_sdk) { - break :blk try std.zig.system.darwin.getSDKPath(arena, options.target); + } else if (options.native_macos_sdk_path) |sdk_path| { + break :blk sdk_path; } else { break :blk null; } @@ -1060,6 +1055,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { link_libc, options.system_lib_names.len != 0 or options.frameworks.len != 0, options.libc_installation, + options.native_macos_sdk_path != null, ); const must_pie = target_util.requiresPIE(options.target); @@ -3776,6 +3772,37 @@ const LibCDirs = struct { libc_installation: ?*const LibCInstallation, }; +fn getZigShippedLibCIncludeDirsDarwin(arena: *Allocator, zig_lib_dir: []const u8, target: Target) !LibCDirs { + const arch_name = @tagName(target.cpu.arch); + const os_name = try std.fmt.allocPrint(arena, "{s}.{d}", .{ + @tagName(target.os.tag), + target.os.version_range.semver.min.major, + }); + const s = std.fs.path.sep_str; + const list = try arena.alloc([]const u8, 3); + + list[0] = try std.fmt.allocPrint( + arena, + "{s}" ++ s ++ "libc" ++ s ++ "include" ++ s ++ "{s}-{s}-gnu", + .{ zig_lib_dir, arch_name, os_name }, + ); + list[1] = try std.fmt.allocPrint( + arena, + "{s}" ++ s ++ "libc" ++ s ++ "include" ++ s ++ "any-{s}-any", + .{ zig_lib_dir, os_name }, + ); + list[2] = try std.fmt.allocPrint( + arena, + "{s}" ++ s ++ "libc" ++ s ++ "include" ++ s ++ "any-macos-any", + .{zig_lib_dir}, + ); + + return LibCDirs{ + .libc_include_dir_list = list, + .libc_installation = null, + }; +} + fn detectLibCIncludeDirs( arena: *Allocator, zig_lib_dir: []const u8, @@ -3784,6 +3811,7 @@ fn detectLibCIncludeDirs( link_libc: bool, link_system_libs: bool, libc_installation: ?*const LibCInstallation, + has_macos_sdk: bool, ) !LibCDirs { if (!link_libc) { return LibCDirs{ @@ -3800,11 +3828,14 @@ fn detectLibCIncludeDirs( // using the system libc installation. if (link_system_libs and is_native_abi and !target.isMinGW()) { if (target.isDarwin()) { - // For Darwin/macOS, we are all set with getSDKPath found earlier. - return LibCDirs{ - .libc_include_dir_list = &[0][]u8{}, - .libc_installation = null, - }; + return if (has_macos_sdk) + // For Darwin/macOS, we are all set with getSDKPath found earlier. + LibCDirs{ + .libc_include_dir_list = &[0][]u8{}, + .libc_installation = null, + } + else + getZigShippedLibCIncludeDirsDarwin(arena, zig_lib_dir, target); } const libc = try arena.create(LibCInstallation); libc.* = try LibCInstallation.findNative(.{ .allocator = arena, .verbose = true }); @@ -3815,36 +3846,7 @@ fn detectLibCIncludeDirs( // default if possible. if (target_util.canBuildLibC(target)) { switch (target.os.tag) { - .macos => { - const arch_name = @tagName(target.cpu.arch); - const os_name = try std.fmt.allocPrint(arena, "{s}.{d}", .{ - @tagName(target.os.tag), - target.os.version_range.semver.min.major, - }); - const s = std.fs.path.sep_str; - const list = try arena.alloc([]const u8, 3); - - list[0] = try std.fmt.allocPrint( - arena, - "{s}" ++ s ++ "libc" ++ s ++ "include" ++ s ++ "{s}-{s}-gnu", - .{ zig_lib_dir, arch_name, os_name }, - ); - list[1] = try std.fmt.allocPrint( - arena, - "{s}" ++ s ++ "libc" ++ s ++ "include" ++ s ++ "any-{s}-any", - .{ zig_lib_dir, os_name }, - ); - list[2] = try std.fmt.allocPrint( - arena, - "{s}" ++ s ++ "libc" ++ s ++ "include" ++ s ++ "any-macos-any", - .{zig_lib_dir}, - ); - - return LibCDirs{ - .libc_include_dir_list = list, - .libc_installation = null, - }; - }, + .macos => return getZigShippedLibCIncludeDirsDarwin(arena, zig_lib_dir, target), else => { const generic_name = target_util.libCGenericName(target); // Some architectures are handled by the same set of headers. diff --git a/src/main.zig b/src/main.zig index 20ea5cadeda9208c30e5e47aea8e8ba7e6d3c346..3c291048d6ee83db5671e982beab3f482d881571 100644 --- a/src/main.zig +++ b/src/main.zig @@ -663,6 +663,7 @@ fn buildOutputType( var minor_subsystem_version: ?u32 = null; var wasi_exec_model: ?std.builtin.WasiExecModel = null; var enable_link_snapshots: bool = false; + var native_macos_sdk_path: ?[]const u8 = null; var system_libs = std.StringArrayHashMap(Compilation.SystemLib).init(gpa); defer system_libs.deinit(); @@ -1858,6 +1859,7 @@ fn buildOutputType( const has_sysroot = if (comptime builtin.target.isDarwin()) outer: { if (try std.zig.system.darwin.getSDKPath(arena, target_info.target)) |sdk_path| { + native_macos_sdk_path = sdk_path; try clang_argv.ensureUnusedCapacity(2); clang_argv.appendAssumeCapacity("-isysroot"); clang_argv.appendAssumeCapacity(sdk_path); @@ -2340,6 +2342,7 @@ fn buildOutputType( .wasi_exec_model = wasi_exec_model, .debug_compile_errors = debug_compile_errors, .enable_link_snapshots = enable_link_snapshots, + .native_macos_sdk_path = native_macos_sdk_path, }) catch |err| { fatal("unable to create compilation: {s}", .{@errorName(err)}); }; -- 2.54.0 From 8317dbd1cb32eaeafa509e7142766f3d9a82de5f Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Fri, 26 Nov 2021 16:08:44 +0100 Subject: [PATCH 2/4] macos: detect SDK path and version, then pass to the linker Since we are already detecting the path to the native SDK, if available, also fetch SDK's version and route that to the linker. The linker can then use it to correctly populate LC_BUILD_VERSION load command. --- lib/std/zig/system/darwin.zig | 72 ++++++++++++++++++++++++++--------- src/Compilation.zig | 22 +++++++---- src/link.zig | 3 ++ src/link/MachO.zig | 16 ++++++-- src/main.zig | 10 ++--- 5 files changed, 88 insertions(+), 35 deletions(-) diff --git a/lib/std/zig/system/darwin.zig b/lib/std/zig/system/darwin.zig index 30496e7d26dfd699726fab6a113ed06307e58722..9f3428a3ee86c8a9a6d15833357118de9e0c65a7 100644 --- a/lib/std/zig/system/darwin.zig +++ b/lib/std/zig/system/darwin.zig @@ -2,14 +2,15 @@ const std = @import("std"); const mem = std.mem; const Allocator = mem.Allocator; const Target = std.Target; +const Version = std.builtin.Version; pub const macos = @import("darwin/macos.zig"); -/// Detect SDK path on Darwin. -/// Calls `xcrun --sdk --show-sdk-path` which result can be used to specify -/// `--sysroot` of the compiler. -/// The caller needs to free the resulting path slice. -pub fn getSDKPath(allocator: *Allocator, target: Target) !?[]u8 { +/// Detect SDK on Darwin. +/// Calls `xcrun --sdk --show-sdk-path` which fetches the path to the SDK sysroot (if any). +/// Subsequently calls `xcrun --sdk --show-sdk-version` which fetches version of the SDK. +/// The caller needs to deinit the resulting struct. +pub fn getDarwinSDK(allocator: *Allocator, target: Target) !?DarwinSDK { const is_simulator_abi = target.abi == .simulator; const sdk = switch (target.os.tag) { .macos => "macosx", @@ -18,22 +19,55 @@ pub fn getSDKPath(allocator: *Allocator, target: Target) !?[]u8 { .tvos => if (is_simulator_abi) "appletvsimulator" else "appletvos", else => return null, }; - - const argv = &[_][]const u8{ "xcrun", "--sdk", sdk, "--show-sdk-path" }; - const result = try std.ChildProcess.exec(.{ .allocator = allocator, .argv = argv }); - defer { - allocator.free(result.stderr); - allocator.free(result.stdout); - } - if (result.stderr.len != 0 or result.term.Exited != 0) { - // We don't actually care if there were errors as this is best-effort check anyhow - // and in the worst case the user can specify the sysroot manually. - return null; - } - const sysroot = try allocator.dupe(u8, mem.trimRight(u8, result.stdout, "\r\n")); - return sysroot; + const path = path: { + const argv = &[_][]const u8{ "xcrun", "--sdk", sdk, "--show-sdk-path" }; + const result = try std.ChildProcess.exec(.{ .allocator = allocator, .argv = argv }); + defer { + allocator.free(result.stderr); + allocator.free(result.stdout); + } + if (result.stderr.len != 0 or result.term.Exited != 0) { + // We don't actually care if there were errors as this is best-effort check anyhow + // and in the worst case the user can specify the sysroot manually. + return null; + } + const path = try allocator.dupe(u8, mem.trimRight(u8, result.stdout, "\r\n")); + break :path path; + }; + const version = version: { + const argv = &[_][]const u8{ "xcrun", "--sdk", sdk, "--show-sdk-version" }; + const result = try std.ChildProcess.exec(.{ .allocator = allocator, .argv = argv }); + defer { + allocator.free(result.stderr); + allocator.free(result.stdout); + } + if (result.stderr.len != 0 or result.term.Exited != 0) { + // We don't actually care if there were errors as this is best-effort check anyhow + // and in the worst case the user can specify the sysroot manually. + return null; + } + const raw_version = mem.trimRight(u8, result.stdout, "\r\n"); + const version = Version.parse(raw_version) catch Version{ + .major = 0, + .minor = 0, + }; + break :version version; + }; + return DarwinSDK{ + .path = path, + .version = version, + }; } +pub const DarwinSDK = struct { + path: []const u8, + version: Version, + + pub fn deinit(self: DarwinSDK, allocator: *Allocator) void { + allocator.free(self.path); + } +}; + test "" { _ = @import("darwin/macos.zig"); } diff --git a/src/Compilation.zig b/src/Compilation.zig index 0d299d6572a87c330d11306dd1cacf7af4d01ebc..ac25519190cc96205c257372bde66a8e6be58da7 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -773,8 +773,8 @@ pub const InitOptions = struct { wasi_exec_model: ?std.builtin.WasiExecModel = null, /// (Zig compiler development) Enable dumping linker's state as JSON. enable_link_snapshots: bool = false, - /// (Darwin). Path to native macOS SDK if detected. - native_macos_sdk_path: ?[]const u8 = null, + /// (Darwin) Path and version of the native SDK if detected. + native_darwin_sdk: ?std.zig.system.darwin.DarwinSDK = null, }; fn addPackageTableToCacheHash( @@ -967,8 +967,8 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { const sysroot = blk: { if (options.sysroot) |sysroot| { break :blk sysroot; - } else if (options.native_macos_sdk_path) |sdk_path| { - break :blk sdk_path; + } else if (options.native_darwin_sdk) |sdk| { + break :blk sdk.path; } else { break :blk null; } @@ -1055,7 +1055,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { link_libc, options.system_lib_names.len != 0 or options.frameworks.len != 0, options.libc_installation, - options.native_macos_sdk_path != null, + options.native_darwin_sdk != null, ); const must_pie = target_util.requiresPIE(options.target); @@ -1492,6 +1492,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { .wasi_exec_model = wasi_exec_model, .use_stage1 = use_stage1, .enable_link_snapshots = options.enable_link_snapshots, + .native_darwin_sdk = options.native_darwin_sdk, }); errdefer bin_file.destroy(); comp.* = .{ @@ -3829,7 +3830,7 @@ fn detectLibCIncludeDirs( if (link_system_libs and is_native_abi and !target.isMinGW()) { if (target.isDarwin()) { return if (has_macos_sdk) - // For Darwin/macOS, we are all set with getSDKPath found earlier. + // For Darwin/macOS, we are all set with getDarwinSDK found earlier. LibCDirs{ .libc_include_dir_list = &[0][]u8{}, .libc_installation = null, @@ -3846,7 +3847,14 @@ fn detectLibCIncludeDirs( // default if possible. if (target_util.canBuildLibC(target)) { switch (target.os.tag) { - .macos => return getZigShippedLibCIncludeDirsDarwin(arena, zig_lib_dir, target), + .macos => return if (has_macos_sdk) + // For Darwin/macOS, we are all set with getDarwinSDK found earlier. + LibCDirs{ + .libc_include_dir_list = &[0][]u8{}, + .libc_installation = null, + } + else + getZigShippedLibCIncludeDirsDarwin(arena, zig_lib_dir, target), else => { const generic_name = target_util.libCGenericName(target); // Some architectures are handled by the same set of headers. diff --git a/src/link.zig b/src/link.zig index 38b91c9e397e257bcf95249bd41eb035535a6561..77464737b083f243922820fa608c20528ad0b8dd 100644 --- a/src/link.zig +++ b/src/link.zig @@ -153,6 +153,9 @@ pub const Options = struct { /// (Zig compiler development) Enable dumping of linker's state as JSON. enable_link_snapshots: bool = false, + /// (Darwin) Path and version of the native SDK if detected. + native_darwin_sdk: ?std.zig.system.darwin.DarwinSDK = null, + pub fn effectiveOutputMode(options: Options) std.builtin.OutputMode { return if (options.use_lld) .Obj else options.output_mode; } diff --git a/src/link/MachO.zig b/src/link/MachO.zig index 4d5133a95924206f83c4ea0c13bb9f0f6be756cd..b718afe1f7a9b511c9b4f8619b554e401baf7c0d 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -4077,8 +4077,16 @@ pub fn populateMissingMetadata(self: *MachO) !void { @sizeOf(macho.build_version_command) + @sizeOf(macho.build_tool_version), @sizeOf(u64), )); - const ver = self.base.options.target.os.version_range.semver.min; - const version = ver.major << 16 | ver.minor << 8 | ver.patch; + const platform_version = blk: { + const ver = self.base.options.target.os.version_range.semver.min; + const platform_version = ver.major << 16 | ver.minor << 8; + break :blk platform_version; + }; + const sdk_version = if (self.base.options.native_darwin_sdk) |sdk| blk: { + const ver = sdk.version; + const sdk_version = ver.major << 16 | ver.minor << 8; + break :blk sdk_version; + } else platform_version; const is_simulator_abi = self.base.options.target.abi == .simulator; var cmd = commands.emptyGenericCommandWithData(macho.build_version_command{ .cmd = macho.LC_BUILD_VERSION, @@ -4090,8 +4098,8 @@ pub fn populateMissingMetadata(self: *MachO) !void { .tvos => if (is_simulator_abi) macho.PLATFORM_TVOSSIMULATOR else macho.PLATFORM_TVOS, else => unreachable, }, - .minos = version, - .sdk = version, + .minos = platform_version, + .sdk = sdk_version, .ntools = 1, }); const ld_ver = macho.build_tool_version{ diff --git a/src/main.zig b/src/main.zig index 3c291048d6ee83db5671e982beab3f482d881571..ee1bd324d5995ec75dc26e0ee98285716d3235d9 100644 --- a/src/main.zig +++ b/src/main.zig @@ -663,7 +663,7 @@ fn buildOutputType( var minor_subsystem_version: ?u32 = null; var wasi_exec_model: ?std.builtin.WasiExecModel = null; var enable_link_snapshots: bool = false; - var native_macos_sdk_path: ?[]const u8 = null; + var native_darwin_sdk: ?std.zig.system.darwin.DarwinSDK = null; var system_libs = std.StringArrayHashMap(Compilation.SystemLib).init(gpa); defer system_libs.deinit(); @@ -1858,11 +1858,11 @@ fn buildOutputType( } const has_sysroot = if (comptime builtin.target.isDarwin()) outer: { - if (try std.zig.system.darwin.getSDKPath(arena, target_info.target)) |sdk_path| { - native_macos_sdk_path = sdk_path; + if (try std.zig.system.darwin.getDarwinSDK(arena, target_info.target)) |sdk| { + native_darwin_sdk = sdk; try clang_argv.ensureUnusedCapacity(2); clang_argv.appendAssumeCapacity("-isysroot"); - clang_argv.appendAssumeCapacity(sdk_path); + clang_argv.appendAssumeCapacity(sdk.path); break :outer true; } else break :outer false; } else false; @@ -2342,7 +2342,7 @@ fn buildOutputType( .wasi_exec_model = wasi_exec_model, .debug_compile_errors = debug_compile_errors, .enable_link_snapshots = enable_link_snapshots, - .native_macos_sdk_path = native_macos_sdk_path, + .native_darwin_sdk = native_darwin_sdk, }) catch |err| { fatal("unable to create compilation: {s}", .{@errorName(err)}); }; -- 2.54.0 From a956958ba9186edb612fbecc5205d6b35cd419a6 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Fri, 26 Nov 2021 17:04:04 +0100 Subject: [PATCH 3/4] macho: define __mh_execute_header as a linker synthetic global --- src/link/MachO.zig | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/src/link/MachO.zig b/src/link/MachO.zig index b718afe1f7a9b511c9b4f8619b554e401baf7c0d..37f905cdd490102574983126bdf1fb834c1dd875 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -154,6 +154,7 @@ tentatives: std.AutoArrayHashMapUnmanaged(u32, void) = .{}, locals_free_list: std.ArrayListUnmanaged(u32) = .{}, globals_free_list: std.ArrayListUnmanaged(u32) = .{}, +mh_execute_header_index: ?u32 = null, dyld_stub_binder_index: ?u32 = null, dyld_private_atom: ?*Atom = null, stub_helper_preamble_atom: ?*Atom = null, @@ -863,6 +864,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void { sect.offset = self.tlv_bss_file_offset; } + try self.createMhExecuteHeaderAtom(); for (self.objects.items) |*object, object_id| { if (object.analyzed) continue; try self.resolveSymbolsInObject(@intCast(u16, object_id)); @@ -2725,6 +2727,42 @@ fn resolveSymbolsInDylibs(self: *MachO) !void { } } +fn createMhExecuteHeaderAtom(self: *MachO) !void { + if (self.mh_execute_header_index != null) return; + + const match: MatchingSection = .{ + .seg = self.text_segment_cmd_index.?, + .sect = self.text_section_index.?, + }; + const n_strx = try self.makeString("__mh_execute_header"); + const local_sym_index = @intCast(u32, self.locals.items.len); + var nlist = macho.nlist_64{ + .n_strx = n_strx, + .n_type = macho.N_SECT, + .n_sect = @intCast(u8, self.section_ordinals.getIndex(match).? + 1), + .n_desc = 0, + .n_value = 0, + }; + try self.locals.append(self.base.allocator, nlist); + + nlist.n_type |= macho.N_EXT; + const global_sym_index = @intCast(u32, self.globals.items.len); + try self.globals.append(self.base.allocator, nlist); + try self.symbol_resolver.putNoClobber(self.base.allocator, n_strx, .{ + .where = .global, + .where_index = global_sym_index, + .local_sym_index = local_sym_index, + .file = null, + }); + + const atom = try self.createEmptyAtom(local_sym_index, 0, 0); + const sym = &self.locals.items[local_sym_index]; + const vaddr = try self.allocateAtom(atom, 0, 1, match); + sym.n_value = vaddr; + atom.dirty = false; + self.mh_execute_header_index = local_sym_index; +} + fn resolveDyldStubBinder(self: *MachO) !void { if (self.dyld_stub_binder_index != null) return; -- 2.54.0 From e2b6dfa6087f2e63bbc03e0430b73e900c95a193 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Fri, 26 Nov 2021 18:09:14 +0100 Subject: [PATCH 4/4] macos: do not trigger CLT installation popup when using zig cc On a bare macOS, when there is no CLT/Xcode installed, do not trigger the CLT installation popup when building with zig cc. --- lib/std/zig/system/darwin.zig | 31 +++++++++++++++++++++++++------ src/main.zig | 4 +++- 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/lib/std/zig/system/darwin.zig b/lib/std/zig/system/darwin.zig index 9f3428a3ee86c8a9a6d15833357118de9e0c65a7..5ce769a7921085508b3d84edbf252c47f1abca3a 100644 --- a/lib/std/zig/system/darwin.zig +++ b/lib/std/zig/system/darwin.zig @@ -6,11 +6,30 @@ const Version = std.builtin.Version; pub const macos = @import("darwin/macos.zig"); +/// Check if SDK is installed on Darwin without triggering CLT installation popup window. +/// Note: simply invoking `xcrun` will inevitably trigger the CLT installation popup. +/// Therefore, we resort to the same tool used by Homebrew, namely, invoking `xcode-select --print-path` +/// and checking if the status is nonzero or the returned string in nonempty. +/// https://github.com/Homebrew/brew/blob/e119bdc571dcb000305411bc1e26678b132afb98/Library/Homebrew/brew.sh#L630 +pub fn isDarwinSDKInstalled(allocator: *Allocator) bool { + const argv = &[_][]const u8{ "/usr/bin/xcode-select", "--print-path" }; + const result = std.ChildProcess.exec(.{ .allocator = allocator, .argv = argv }) catch return false; + defer { + allocator.free(result.stderr); + allocator.free(result.stdout); + } + if (result.stderr.len != 0 or result.term.Exited != 0) { + // We don't actually care if there were errors as this is best-effort check anyhow. + return false; + } + return result.stdout.len > 0; +} + /// Detect SDK on Darwin. /// Calls `xcrun --sdk --show-sdk-path` which fetches the path to the SDK sysroot (if any). /// Subsequently calls `xcrun --sdk --show-sdk-version` which fetches version of the SDK. /// The caller needs to deinit the resulting struct. -pub fn getDarwinSDK(allocator: *Allocator, target: Target) !?DarwinSDK { +pub fn getDarwinSDK(allocator: *Allocator, target: Target) ?DarwinSDK { const is_simulator_abi = target.abi == .simulator; const sdk = switch (target.os.tag) { .macos => "macosx", @@ -20,8 +39,8 @@ pub fn getDarwinSDK(allocator: *Allocator, target: Target) !?DarwinSDK { else => return null, }; const path = path: { - const argv = &[_][]const u8{ "xcrun", "--sdk", sdk, "--show-sdk-path" }; - const result = try std.ChildProcess.exec(.{ .allocator = allocator, .argv = argv }); + const argv = &[_][]const u8{ "/usr/bin/xcrun", "--sdk", sdk, "--show-sdk-path" }; + const result = std.ChildProcess.exec(.{ .allocator = allocator, .argv = argv }) catch return null; defer { allocator.free(result.stderr); allocator.free(result.stdout); @@ -31,12 +50,12 @@ pub fn getDarwinSDK(allocator: *Allocator, target: Target) !?DarwinSDK { // and in the worst case the user can specify the sysroot manually. return null; } - const path = try allocator.dupe(u8, mem.trimRight(u8, result.stdout, "\r\n")); + const path = allocator.dupe(u8, mem.trimRight(u8, result.stdout, "\r\n")) catch return null; break :path path; }; const version = version: { - const argv = &[_][]const u8{ "xcrun", "--sdk", sdk, "--show-sdk-version" }; - const result = try std.ChildProcess.exec(.{ .allocator = allocator, .argv = argv }); + const argv = &[_][]const u8{ "/usr/bin/xcrun", "--sdk", sdk, "--show-sdk-version" }; + const result = std.ChildProcess.exec(.{ .allocator = allocator, .argv = argv }) catch return null; defer { allocator.free(result.stderr); allocator.free(result.stdout); diff --git a/src/main.zig b/src/main.zig index ee1bd324d5995ec75dc26e0ee98285716d3235d9..5590e14d0e1415473fc1c82a87dd57d4d8e4c47a 100644 --- a/src/main.zig +++ b/src/main.zig @@ -1858,7 +1858,9 @@ fn buildOutputType( } const has_sysroot = if (comptime builtin.target.isDarwin()) outer: { - if (try std.zig.system.darwin.getDarwinSDK(arena, target_info.target)) |sdk| { + if (std.zig.system.darwin.isDarwinSDKInstalled(arena)) { + const sdk = std.zig.system.darwin.getDarwinSDK(arena, target_info.target) orelse + break :outer false; native_darwin_sdk = sdk; try clang_argv.ensureUnusedCapacity(2); clang_argv.appendAssumeCapacity("-isysroot"); -- 2.54.0