From aef8bcf7763cd098201d6b4b4c3e9e447188ae43 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 2 Aug 2023 11:05:35 -0700 Subject: std.Build.Step.Compile: fine-grained system lib search control For each library you can specify the preferred mode and search strategy. The old way of setting global state is eliminated. --- lib/std/Build/Step/Compile.zig | 139 +++++++++++++++++++---------------------- 1 file changed, 63 insertions(+), 76 deletions(-) (limited to 'lib/std') diff --git a/lib/std/Build/Step/Compile.zig b/lib/std/Build/Step/Compile.zig index 89cc2ecfd9..335a7e2df7 100644 --- a/lib/std/Build/Step/Compile.zig +++ b/lib/std/Build/Step/Compile.zig @@ -149,13 +149,6 @@ entitlements: ?[]const u8 = null, /// (Darwin) Size of the pagezero segment. pagezero_size: ?u64 = null, -/// (Darwin) Search strategy for searching system libraries. Either `paths_first` or `dylibs_first`. -/// The former lowers to `-search_paths_first` linker option, while the latter to `-search_dylibs_first` -/// option. -/// By default, if no option is specified, the linker assumes `paths_first` as the default -/// search strategy. -search_strategy: ?enum { paths_first, dylibs_first } = null, - /// (Darwin) Set size of the padding between the end of load commands /// and start of `__TEXT,__text` section. headerpad_size: ?u32 = null, @@ -242,7 +235,11 @@ pub const SystemLib = struct { name: []const u8, needed: bool, weak: bool, - use_pkg_config: enum { + use_pkg_config: UsePkgConfig, + preferred_link_mode: std.builtin.LinkMode, + search_strategy: SystemLib.SearchStrategy, + + pub const UsePkgConfig = enum { /// Don't use pkg-config, just pass -lfoo where foo is name. no, /// Try to get information on how to link the library from pkg-config. @@ -251,7 +248,9 @@ pub const SystemLib = struct { /// Try to get information on how to link the library from pkg-config. /// If that fails, error out. force, - }, + }; + + pub const SearchStrategy = enum { paths_first, mode_first, no_fallback }; }; const FrameworkLinkInfo = struct { @@ -718,74 +717,29 @@ pub fn defineCMacroRaw(self: *Compile, name_and_value: []const u8) void { self.c_macros.append(b.dupe(name_and_value)) catch @panic("OOM"); } -/// This one has no integration with anything, it just puts -lname on the command line. -/// Prefer to use `linkSystemLibrary` instead. +/// deprecated: use linkSystemLibrary2 pub fn linkSystemLibraryName(self: *Compile, name: []const u8) void { - const b = self.step.owner; - self.link_objects.append(.{ - .system_lib = .{ - .name = b.dupe(name), - .needed = false, - .weak = false, - .use_pkg_config = .no, - }, - }) catch @panic("OOM"); + return linkSystemLibrary2(self, name, .{ .use_pkg_config = .no }); } -/// This one has no integration with anything, it just puts -needed-lname on the command line. -/// Prefer to use `linkSystemLibraryNeeded` instead. +/// deprecated: use linkSystemLibrary2 pub fn linkSystemLibraryNeededName(self: *Compile, name: []const u8) void { - const b = self.step.owner; - self.link_objects.append(.{ - .system_lib = .{ - .name = b.dupe(name), - .needed = true, - .weak = false, - .use_pkg_config = .no, - }, - }) catch @panic("OOM"); + return linkSystemLibrary2(self, name, .{ .needed = true, .use_pkg_config = .no }); } -/// Darwin-only. This one has no integration with anything, it just puts -weak-lname on the -/// command line. Prefer to use `linkSystemLibraryWeak` instead. +/// deprecated: use linkSystemLibrary2 pub fn linkSystemLibraryWeakName(self: *Compile, name: []const u8) void { - const b = self.step.owner; - self.link_objects.append(.{ - .system_lib = .{ - .name = b.dupe(name), - .needed = false, - .weak = true, - .use_pkg_config = .no, - }, - }) catch @panic("OOM"); + return linkSystemLibrary2(self, name, .{ .weak = true, .use_pkg_config = .no }); } -/// This links against a system library, exclusively using pkg-config to find the library. -/// Prefer to use `linkSystemLibrary` instead. +/// deprecated: use linkSystemLibrary2 pub fn linkSystemLibraryPkgConfigOnly(self: *Compile, lib_name: []const u8) void { - const b = self.step.owner; - self.link_objects.append(.{ - .system_lib = .{ - .name = b.dupe(lib_name), - .needed = false, - .weak = false, - .use_pkg_config = .force, - }, - }) catch @panic("OOM"); + return linkSystemLibrary2(self, lib_name, .{ .use_pkg_config = .force }); } -/// This links against a system library, exclusively using pkg-config to find the library. -/// Prefer to use `linkSystemLibraryNeeded` instead. +/// deprecated: use linkSystemLibrary2 pub fn linkSystemLibraryNeededPkgConfigOnly(self: *Compile, lib_name: []const u8) void { - const b = self.step.owner; - self.link_objects.append(.{ - .system_lib = .{ - .name = b.dupe(lib_name), - .needed = true, - .weak = false, - .use_pkg_config = .force, - }, - }) catch @panic("OOM"); + return linkSystemLibrary2(self, lib_name, .{ .needed = true, .use_pkg_config = .force }); } /// Run pkg-config for the given library name and parse the output, returning the arguments @@ -885,21 +839,32 @@ fn runPkgConfig(self: *Compile, lib_name: []const u8) ![]const []const u8 { } pub fn linkSystemLibrary(self: *Compile, name: []const u8) void { - self.linkSystemLibraryInner(name, .{}); + self.linkSystemLibrary2(name, .{}); } +/// deprecated: use linkSystemLibrary2 pub fn linkSystemLibraryNeeded(self: *Compile, name: []const u8) void { - self.linkSystemLibraryInner(name, .{ .needed = true }); + return linkSystemLibrary2(self, name, .{ .needed = true }); } +/// deprecated: use linkSystemLibrary2 pub fn linkSystemLibraryWeak(self: *Compile, name: []const u8) void { - self.linkSystemLibraryInner(name, .{ .weak = true }); + return linkSystemLibrary2(self, name, .{ .weak = true }); } -fn linkSystemLibraryInner(self: *Compile, name: []const u8, opts: struct { +pub const LinkSystemLibraryOptions = struct { needed: bool = false, weak: bool = false, -}) void { + use_pkg_config: SystemLib.UsePkgConfig = .yes, + preferred_link_mode: std.builtin.LinkMode = .Dynamic, + search_strategy: SystemLib.SearchStrategy = .paths_first, +}; + +pub fn linkSystemLibrary2( + self: *Compile, + name: []const u8, + options: LinkSystemLibraryOptions, +) void { const b = self.step.owner; if (isLibCLibrary(name)) { self.linkLibC(); @@ -913,9 +878,11 @@ fn linkSystemLibraryInner(self: *Compile, name: []const u8, opts: struct { self.link_objects.append(.{ .system_lib = .{ .name = b.dupe(name), - .needed = opts.needed, - .weak = opts.weak, - .use_pkg_config = .yes, + .needed = options.needed, + .weak = options.weak, + .use_pkg_config = options.use_pkg_config, + .preferred_link_mode = options.preferred_link_mode, + .search_strategy = options.search_strategy, }, }) catch @panic("OOM"); } @@ -1385,6 +1352,8 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { try transitive_deps.add(self.link_objects.items); var prev_has_cflags = false; + var prev_search_strategy: SystemLib.SearchStrategy = .paths_first; + var prev_preferred_link_mode: std.builtin.LinkMode = .Dynamic; for (transitive_deps.link_objects.items) |link_object| { switch (link_object) { @@ -1420,6 +1389,28 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { }, .system_lib => |system_lib| { + if ((system_lib.search_strategy != prev_search_strategy or + system_lib.preferred_link_mode != prev_preferred_link_mode) and + self.linkage != .static) + { + switch (system_lib.search_strategy) { + .no_fallback => switch (system_lib.preferred_link_mode) { + .Dynamic => try zig_args.append("-search_dylibs_only"), + .Static => try zig_args.append("-search_static_only"), + }, + .paths_first => switch (system_lib.preferred_link_mode) { + .Dynamic => try zig_args.append("-search_paths_first"), + .Static => try zig_args.append("-search_paths_first_static"), + }, + .mode_first => switch (system_lib.preferred_link_mode) { + .Dynamic => try zig_args.append("-search_dylibs_first"), + .Static => try zig_args.append("-search_static_first"), + }, + } + prev_search_strategy = system_lib.search_strategy; + prev_preferred_link_mode = system_lib.preferred_link_mode; + } + const prefix: []const u8 = prefix: { if (system_lib.needed) break :prefix "-needed-l"; if (system_lib.weak) break :prefix "-weak-l"; @@ -1662,10 +1653,6 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { const size = try std.fmt.allocPrint(b.allocator, "{x}", .{pagezero_size}); try zig_args.appendSlice(&[_][]const u8{ "-pagezero_size", size }); } - if (self.search_strategy) |strat| switch (strat) { - .paths_first => try zig_args.append("-search_paths_first"), - .dylibs_first => try zig_args.append("-search_dylibs_first"), - }; if (self.headerpad_size) |headerpad_size| { const size = try std.fmt.allocPrint(b.allocator, "{x}", .{headerpad_size}); try zig_args.appendSlice(&[_][]const u8{ "-headerpad", size }); -- cgit v1.2.3 From c94bbebb9150f68ce179caa4f6beeab0622696a6 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 2 Aug 2023 18:35:18 -0700 Subject: std.zig.system.NativePaths: simplify and integrate with Darwin SDK --- lib/std/zig/system/NativePaths.zig | 108 ++++++++++++------------------------- src/Compilation.zig | 6 ++- src/main.zig | 25 +-------- 3 files changed, 40 insertions(+), 99 deletions(-) (limited to 'lib/std') diff --git a/lib/std/zig/system/NativePaths.zig b/lib/std/zig/system/NativePaths.zig index f9798695ad..61f71144ca 100644 --- a/lib/std/zig/system/NativePaths.zig +++ b/lib/std/zig/system/NativePaths.zig @@ -1,6 +1,5 @@ const std = @import("../../std.zig"); const builtin = @import("builtin"); -const ArrayList = std.ArrayList; const Allocator = std.mem.Allocator; const process = std.process; const mem = std.mem; @@ -8,28 +7,18 @@ const mem = std.mem; const NativePaths = @This(); const NativeTargetInfo = std.zig.system.NativeTargetInfo; -include_dirs: ArrayList([:0]u8), -lib_dirs: ArrayList([:0]u8), -framework_dirs: ArrayList([:0]u8), -rpaths: ArrayList([:0]u8), -warnings: ArrayList([:0]u8), +arena: Allocator, +include_dirs: std.ArrayListUnmanaged([]const u8) = .{}, +lib_dirs: std.ArrayListUnmanaged([]const u8) = .{}, +framework_dirs: std.ArrayListUnmanaged([]const u8) = .{}, +rpaths: std.ArrayListUnmanaged([]const u8) = .{}, +warnings: std.ArrayListUnmanaged([]const u8) = .{}, -pub fn detect(allocator: Allocator, native_info: NativeTargetInfo) !NativePaths { +pub fn detect(arena: Allocator, native_info: NativeTargetInfo) !NativePaths { const native_target = native_info.target; - - var self: NativePaths = .{ - .include_dirs = ArrayList([:0]u8).init(allocator), - .lib_dirs = ArrayList([:0]u8).init(allocator), - .framework_dirs = ArrayList([:0]u8).init(allocator), - .rpaths = ArrayList([:0]u8).init(allocator), - .warnings = ArrayList([:0]u8).init(allocator), - }; - errdefer self.deinit(); - + var self: NativePaths = .{ .arena = arena }; var is_nix = false; - if (process.getEnvVarOwned(allocator, "NIX_CFLAGS_COMPILE")) |nix_cflags_compile| { - defer allocator.free(nix_cflags_compile); - + if (process.getEnvVarOwned(arena, "NIX_CFLAGS_COMPILE")) |nix_cflags_compile| { is_nix = true; var it = mem.tokenizeScalar(u8, nix_cflags_compile, ' '); while (true) { @@ -58,9 +47,7 @@ pub fn detect(allocator: Allocator, native_info: NativeTargetInfo) !NativePaths error.EnvironmentVariableNotFound => {}, error.OutOfMemory => |e| return e, } - if (process.getEnvVarOwned(allocator, "NIX_LDFLAGS")) |nix_ldflags| { - defer allocator.free(nix_ldflags); - + if (process.getEnvVarOwned(arena, "NIX_LDFLAGS")) |nix_ldflags| { is_nix = true; var it = mem.tokenizeScalar(u8, nix_ldflags, ' '); while (true) { @@ -89,17 +76,18 @@ pub fn detect(allocator: Allocator, native_info: NativeTargetInfo) !NativePaths return self; } + // TODO: consider also adding homebrew paths + // TODO: consider also adding macports paths if (comptime builtin.target.isDarwin()) { - try self.addIncludeDir("/usr/include"); - try self.addLibDir("/usr/lib"); - try self.addFrameworkDir("/System/Library/Frameworks"); - - if (builtin.target.os.version_range.semver.min.major < 11) { - try self.addIncludeDir("/usr/local/include"); - try self.addLibDir("/usr/local/lib"); - try self.addFrameworkDir("/Library/Frameworks"); + if (std.zig.system.darwin.isDarwinSDKInstalled(arena)) sdk: { + const sdk = std.zig.system.darwin.getDarwinSDK(arena, native_target) orelse break :sdk; + try self.addLibDir(try std.fs.path.join(arena, &.{ sdk.path, "usr/lib" })); + try self.addFrameworkDir(try std.fs.path.join(arena, &.{ sdk.path, "System/Library/Frameworks" })); + try self.addIncludeDir(try std.fs.path.join(arena, &.{ sdk.path, "usr/include" })); + return self; } - + // These do not include headers, so the ones that come with the SDK are preferred. + try self.addFrameworkDir("/System/Library/Frameworks"); return self; } @@ -115,8 +103,7 @@ pub fn detect(allocator: Allocator, native_info: NativeTargetInfo) !NativePaths } if (builtin.os.tag != .windows) { - const triple = try native_target.linuxTriple(allocator); - defer allocator.free(triple); + const triple = try native_target.linuxTriple(arena); const qual = native_target.ptrBitWidth(); @@ -172,69 +159,42 @@ pub fn detect(allocator: Allocator, native_info: NativeTargetInfo) !NativePaths return self; } -pub fn deinit(self: *NativePaths) void { - deinitArray(&self.include_dirs); - deinitArray(&self.lib_dirs); - deinitArray(&self.framework_dirs); - deinitArray(&self.rpaths); - deinitArray(&self.warnings); - self.* = undefined; -} - -fn deinitArray(array: *ArrayList([:0]u8)) void { - for (array.items) |item| { - array.allocator.free(item); - } - array.deinit(); -} - pub fn addIncludeDir(self: *NativePaths, s: []const u8) !void { - return self.appendArray(&self.include_dirs, s); + return self.include_dirs.append(self.arena, s); } pub fn addIncludeDirFmt(self: *NativePaths, comptime fmt: []const u8, args: anytype) !void { - const item = try std.fmt.allocPrintZ(self.include_dirs.allocator, fmt, args); - errdefer self.include_dirs.allocator.free(item); - try self.include_dirs.append(item); + const item = try std.fmt.allocPrint(self.arena, fmt, args); + try self.include_dirs.append(self.arena, item); } pub fn addLibDir(self: *NativePaths, s: []const u8) !void { - return self.appendArray(&self.lib_dirs, s); + try self.lib_dirs.append(self.arena, s); } pub fn addLibDirFmt(self: *NativePaths, comptime fmt: []const u8, args: anytype) !void { - const item = try std.fmt.allocPrintZ(self.lib_dirs.allocator, fmt, args); - errdefer self.lib_dirs.allocator.free(item); - try self.lib_dirs.append(item); + const item = try std.fmt.allocPrint(self.arena, fmt, args); + try self.lib_dirs.append(self.arena, item); } pub fn addWarning(self: *NativePaths, s: []const u8) !void { - return self.appendArray(&self.warnings, s); + return self.warnings.append(self.arena, s); } pub fn addFrameworkDir(self: *NativePaths, s: []const u8) !void { - return self.appendArray(&self.framework_dirs, s); + return self.framework_dirs.append(self.arena, s); } pub fn addFrameworkDirFmt(self: *NativePaths, comptime fmt: []const u8, args: anytype) !void { - const item = try std.fmt.allocPrintZ(self.framework_dirs.allocator, fmt, args); - errdefer self.framework_dirs.allocator.free(item); - try self.framework_dirs.append(item); + const item = try std.fmt.allocPrint(self.arena, fmt, args); + try self.framework_dirs.append(self.arena, item); } pub fn addWarningFmt(self: *NativePaths, comptime fmt: []const u8, args: anytype) !void { - const item = try std.fmt.allocPrintZ(self.warnings.allocator, fmt, args); - errdefer self.warnings.allocator.free(item); - try self.warnings.append(item); + const item = try std.fmt.allocPrint(self.arena, fmt, args); + try self.warnings.append(self.arena, item); } pub fn addRPath(self: *NativePaths, s: []const u8) !void { - return self.appendArray(&self.rpaths, s); -} - -fn appendArray(self: *NativePaths, array: *ArrayList([:0]u8), s: []const u8) !void { - _ = self; - const item = try array.allocator.dupeZ(u8, s); - errdefer array.allocator.free(item); - try array.append(item); + try self.rpaths.append(self.arena, s); } diff --git a/src/Compilation.zig b/src/Compilation.zig index 91b31c6004..094275f749 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -857,8 +857,6 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { const sysroot = blk: { if (options.sysroot) |sysroot| { break :blk sysroot; - } else if (options.native_darwin_sdk) |sdk| { - break :blk sdk.path; } else { break :blk null; } @@ -4341,6 +4339,10 @@ pub fn addCCArgs( try argv.append("-ObjC++"); } + for (comp.bin_file.options.framework_dirs) |framework_dir| { + try argv.appendSlice(&.{ "-isystem", framework_dir }); + } + // According to Rich Felker libc headers are supposed to go before C language headers. // However as noted by @dimenus, appending libc headers before c_headers breaks intrinsics // and other compiler specific items. diff --git a/src/main.zig b/src/main.zig index 87db5c80ea..3bdcf0d2ce 100644 --- a/src/main.zig +++ b/src/main.zig @@ -2685,34 +2685,13 @@ fn buildOutputType( warn("{s}", .{warning}); } - const has_sysroot = if (comptime builtin.target.isDarwin()) outer: { - 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"); - clang_argv.appendAssumeCapacity(sdk.path); - break :outer true; - } else break :outer false; - } else false; - try clang_argv.ensureUnusedCapacity(paths.include_dirs.items.len * 2); - const isystem_flag = if (has_sysroot) "-iwithsysroot" else "-isystem"; for (paths.include_dirs.items) |include_dir| { - clang_argv.appendAssumeCapacity(isystem_flag); + clang_argv.appendAssumeCapacity("-isystem"); clang_argv.appendAssumeCapacity(include_dir); } - try clang_argv.ensureUnusedCapacity(paths.framework_dirs.items.len * 2); - try framework_dirs.ensureUnusedCapacity(paths.framework_dirs.items.len); - const iframework_flag = if (has_sysroot) "-iframeworkwithsysroot" else "-iframework"; - for (paths.framework_dirs.items) |framework_dir| { - clang_argv.appendAssumeCapacity(iframework_flag); - clang_argv.appendAssumeCapacity(framework_dir); - framework_dirs.appendAssumeCapacity(framework_dir); - } - + try framework_dirs.appendSlice(paths.framework_dirs.items); try lib_dirs.appendSlice(paths.lib_dirs.items); try rpath_list.appendSlice(paths.rpaths.items); } -- cgit v1.2.3 From e582a3642bb001a7a19ecb72b128f45ab7fc08aa Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 2 Aug 2023 16:25:45 -0700 Subject: std.zig.system.darwin: fix redundant names --- lib/std/zig/system/NativePaths.zig | 4 ++-- lib/std/zig/system/darwin.zig | 10 +++++----- src/libc_installation.zig | 4 ++-- src/main.zig | 3 --- test/link/macho/bugs/13056/build.zig | 2 +- 5 files changed, 10 insertions(+), 13 deletions(-) (limited to 'lib/std') diff --git a/lib/std/zig/system/NativePaths.zig b/lib/std/zig/system/NativePaths.zig index 61f71144ca..1fd92292f9 100644 --- a/lib/std/zig/system/NativePaths.zig +++ b/lib/std/zig/system/NativePaths.zig @@ -79,8 +79,8 @@ pub fn detect(arena: Allocator, native_info: NativeTargetInfo) !NativePaths { // TODO: consider also adding homebrew paths // TODO: consider also adding macports paths if (comptime builtin.target.isDarwin()) { - if (std.zig.system.darwin.isDarwinSDKInstalled(arena)) sdk: { - const sdk = std.zig.system.darwin.getDarwinSDK(arena, native_target) orelse break :sdk; + if (std.zig.system.darwin.isSdkInstalled(arena)) sdk: { + const sdk = std.zig.system.darwin.getSdk(arena, native_target) orelse break :sdk; try self.addLibDir(try std.fs.path.join(arena, &.{ sdk.path, "usr/lib" })); try self.addFrameworkDir(try std.fs.path.join(arena, &.{ sdk.path, "System/Library/Frameworks" })); try self.addIncludeDir(try std.fs.path.join(arena, &.{ sdk.path, "usr/include" })); diff --git a/lib/std/zig/system/darwin.zig b/lib/std/zig/system/darwin.zig index e29dc68d64..3857d4f46c 100644 --- a/lib/std/zig/system/darwin.zig +++ b/lib/std/zig/system/darwin.zig @@ -11,7 +11,7 @@ pub const macos = @import("darwin/macos.zig"); /// 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 { +pub fn isSdkInstalled(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 { @@ -29,7 +29,7 @@ pub fn isDarwinSDKInstalled(allocator: Allocator) bool { /// 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 getSdk(allocator: Allocator, target: Target) ?Sdk { const is_simulator_abi = target.abi == .simulator; const sdk = switch (target.os.tag) { .macos => "macosx", @@ -73,7 +73,7 @@ pub fn getDarwinSDK(allocator: Allocator, target: Target) ?DarwinSDK { }; break :version version; }; - return DarwinSDK{ + return Sdk{ .path = path, .version = version, }; @@ -96,11 +96,11 @@ fn parseSdkVersion(raw: []const u8) ?Version { return Version.parse(buffer[0..len]) catch null; } -pub const DarwinSDK = struct { +pub const Sdk = struct { path: []const u8, version: Version, - pub fn deinit(self: DarwinSDK, allocator: Allocator) void { + pub fn deinit(self: Sdk, allocator: Allocator) void { allocator.free(self.path); } }; diff --git a/src/libc_installation.zig b/src/libc_installation.zig index 4dbe9d9c57..2d42a03a32 100644 --- a/src/libc_installation.zig +++ b/src/libc_installation.zig @@ -183,9 +183,9 @@ pub const LibCInstallation = struct { var self: LibCInstallation = .{}; if (is_darwin) { - if (!std.zig.system.darwin.isDarwinSDKInstalled(args.allocator)) + if (!std.zig.system.darwin.isSdkInstalled(args.allocator)) return error.DarwinSdkNotFound; - const sdk = std.zig.system.darwin.getDarwinSDK(args.allocator, args.target) orelse + const sdk = std.zig.system.darwin.getSdk(args.allocator, args.target) orelse return error.DarwinSdkNotFound; defer args.allocator.free(sdk.path); diff --git a/src/main.zig b/src/main.zig index 3f06469a75..3c7d2c85be 100644 --- a/src/main.zig +++ b/src/main.zig @@ -2857,9 +2857,6 @@ fn buildOutputType( std.log.err("unable to find {s} system library '{s}' using strategy '{s}'. searched paths:{s}", .{ @tagName(f.preferred_mode), f.name, @tagName(f.strategy), searched_paths, }); - if (f.preferred_mode == .Dynamic and f.strategy == .no_fallback) { - std.log.info("to link statically, pass the library as a positional argument", .{}); - } } process.exit(1); } diff --git a/test/link/macho/bugs/13056/build.zig b/test/link/macho/bugs/13056/build.zig index eade752bc4..50eb990583 100644 --- a/test/link/macho/bugs/13056/build.zig +++ b/test/link/macho/bugs/13056/build.zig @@ -16,7 +16,7 @@ pub fn build(b: *std.Build) void { fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void { const target: std.zig.CrossTarget = .{ .os_tag = .macos }; const target_info = std.zig.system.NativeTargetInfo.detect(target) catch unreachable; - const sdk = std.zig.system.darwin.getDarwinSDK(b.allocator, target_info.target) orelse + const sdk = std.zig.system.darwin.getSdk(b.allocator, target_info.target) orelse @panic("macOS SDK is required to run the test"); const exe = b.addExecutable(.{ -- cgit v1.2.3 From c012f5d55dc59f80a3cd4fce22443a39fcbb67e9 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 2 Aug 2023 16:36:58 -0700 Subject: std.zig.system.darwin.isSdkInstalled: fix implementation * don't assert that the child process doesn't crash * don't give a false negative on warnings printed to stderr Also fix getSdk from the same file in the same way --- lib/std/zig/system/darwin.zig | 44 +++++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 20 deletions(-) (limited to 'lib/std') diff --git a/lib/std/zig/system/darwin.zig b/lib/std/zig/system/darwin.zig index 3857d4f46c..992c0d814d 100644 --- a/lib/std/zig/system/darwin.zig +++ b/lib/std/zig/system/darwin.zig @@ -8,27 +8,33 @@ 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 +/// Therefore, we resort to invoking `xcode-select --print-path` and checking +/// if the status is nonzero. +/// stderr from xcode-select is ignored. +/// If error.OutOfMemory occurs in Allocator, this function returns null. pub fn isSdkInstalled(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; + const result = std.process.Child.exec(.{ + .allocator = allocator, + .argv = &.{ "/usr/bin/xcode-select", "--print-path" }, + }) 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; + + return switch (result.term) { + .Exited => |code| if (code == 0) result.stdout.len > 0 else false, + else => false, + }; } /// 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. +/// stderr from xcrun is ignored. +/// If error.OutOfMemory occurs in Allocator, this function returns null. pub fn getSdk(allocator: Allocator, target: Target) ?Sdk { const is_simulator_abi = target.abi == .simulator; const sdk = switch (target.os.tag) { @@ -40,30 +46,28 @@ pub fn getSdk(allocator: Allocator, target: Target) ?Sdk { }; const path = path: { const argv = &[_][]const u8{ "/usr/bin/xcrun", "--sdk", sdk, "--show-sdk-path" }; - const result = std.ChildProcess.exec(.{ .allocator = allocator, .argv = argv }) catch return null; + const result = std.process.Child.exec(.{ .allocator = allocator, .argv = argv }) catch return null; 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; + switch (result.term) { + .Exited => |code| if (code != 0) return null, + else => return null, } 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{ "/usr/bin/xcrun", "--sdk", sdk, "--show-sdk-version" }; - const result = std.ChildProcess.exec(.{ .allocator = allocator, .argv = argv }) catch return null; + const result = std.process.Child.exec(.{ .allocator = allocator, .argv = argv }) catch return null; 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; + switch (result.term) { + .Exited => |code| if (code != 0) return null, + else => return null, } const raw_version = mem.trimRight(u8, result.stdout, "\r\n"); const version = parseSdkVersion(raw_version) orelse Version{ -- cgit v1.2.3 From d0fd67cffe664ff70d9a70dd4d2d28aba5a378e8 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Thu, 3 Aug 2023 09:51:21 -0700 Subject: std.zig.system.NativePaths: remove bad framework dir This path actually has nothing useful in it. --- lib/std/zig/system/NativePaths.zig | 2 -- 1 file changed, 2 deletions(-) (limited to 'lib/std') diff --git a/lib/std/zig/system/NativePaths.zig b/lib/std/zig/system/NativePaths.zig index 1fd92292f9..4c8f1286b8 100644 --- a/lib/std/zig/system/NativePaths.zig +++ b/lib/std/zig/system/NativePaths.zig @@ -86,8 +86,6 @@ pub fn detect(arena: Allocator, native_info: NativeTargetInfo) !NativePaths { try self.addIncludeDir(try std.fs.path.join(arena, &.{ sdk.path, "usr/include" })); return self; } - // These do not include headers, so the ones that come with the SDK are preferred. - try self.addFrameworkDir("/System/Library/Frameworks"); return self; } -- cgit v1.2.3