authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-08-02 19:17:07-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-08-03 09:52:15-07:00
logda91ef5c28bd11823bd84b6f54df9ca601f03e21
treeec6e830b6062bb2ce8e88a9e9b7e8d06f79979eb
parentc94bbebb9150f68ce179caa4f6beeab0622696a6

zig libc: restore functionality on macOS

Regressed in 2006add8496c47804ee3b6c562f420871cb4ea0a. References to native_darwin_sdk are no longer kept in the frontend. Instead the darwin SDK is detected as part of NativePaths and as part of LibCInstallation.

5 files changed, 77 insertions(+), 90 deletions(-)

src/Compilation.zig+55-79
......@@ -637,8 +637,6 @@ pub const InitOptions = struct {
637637 wasi_exec_model: ?std.builtin.WasiExecModel = null,
638638 /// (Zig compiler development) Enable dumping linker's state as JSON.
639639 enable_link_snapshots: bool = false,
640 /// (Darwin) Path and version of the native SDK if detected.
641 native_darwin_sdk: ?std.zig.system.darwin.DarwinSDK = null,
642640 /// (Darwin) Install name of the dylib
643641 install_name: ?[]const u8 = null,
644642 /// (Darwin) Path to entitlements file
......@@ -945,7 +943,6 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
945943 options.is_native_abi,
946944 link_libc,
947945 options.libc_installation,
948 options.native_darwin_sdk != null,
949946 );
950947
951948 const must_pie = target_util.requiresPIE(options.target);
......@@ -1560,7 +1557,6 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
15601557 .wasi_exec_model = wasi_exec_model,
15611558 .hash_style = options.hash_style,
15621559 .enable_link_snapshots = options.enable_link_snapshots,
1563 .native_darwin_sdk = options.native_darwin_sdk,
15641560 .install_name = options.install_name,
15651561 .entitlements = options.entitlements,
15661562 .pagezero_size = options.pagezero_size,
......@@ -4865,7 +4861,6 @@ fn detectLibCIncludeDirs(
48654861 is_native_abi: bool,
48664862 link_libc: bool,
48674863 libc_installation: ?*const LibCInstallation,
4868 has_macos_sdk: bool,
48694864) !LibCDirs {
48704865 if (!link_libc) {
48714866 return LibCDirs{
......@@ -4881,28 +4876,19 @@ fn detectLibCIncludeDirs(
48814876 // If linking system libraries and targeting the native abi, default to
48824877 // using the system libc installation.
48834878 if (is_native_abi and !target.isMinGW()) {
4884 if (target.isDarwin()) {
4885 return if (has_macos_sdk)
4886 // For Darwin/macOS, we are all set with getDarwinSDK found earlier.
4887 LibCDirs{
4888 .libc_include_dir_list = &[0][]u8{},
4889 .libc_installation = null,
4890 }
4891 else
4892 getZigShippedLibCIncludeDirsDarwin(arena, zig_lib_dir, target);
4893 }
48944879 const libc = try arena.create(LibCInstallation);
4895 libc.* = LibCInstallation.findNative(.{ .allocator = arena }) catch |err| switch (err) {
4880 libc.* = LibCInstallation.findNative(.{ .allocator = arena, .target = target }) catch |err| switch (err) {
48964881 error.CCompilerExitCode,
48974882 error.CCompilerCrashed,
48984883 error.CCompilerCannotFindHeaders,
48994884 error.UnableToSpawnCCompiler,
4885 error.DarwinSdkNotFound,
49004886 => |e| {
49014887 // We tried to integrate with the native system C compiler,
49024888 // however, it is not installed. So we must rely on our bundled
49034889 // libc files.
49044890 if (target_util.canBuildLibC(target)) {
4905 return detectLibCFromBuilding(arena, zig_lib_dir, target, has_macos_sdk);
4891 return detectLibCFromBuilding(arena, zig_lib_dir, target);
49064892 }
49074893 return e;
49084894 },
......@@ -4914,7 +4900,7 @@ fn detectLibCIncludeDirs(
49144900 // If not linking system libraries, build and provide our own libc by
49154901 // default if possible.
49164902 if (target_util.canBuildLibC(target)) {
4917 return detectLibCFromBuilding(arena, zig_lib_dir, target, has_macos_sdk);
4903 return detectLibCFromBuilding(arena, zig_lib_dir, target);
49184904 }
49194905
49204906 // If zig can't build the libc for the target and we are targeting the
......@@ -4928,7 +4914,7 @@ fn detectLibCIncludeDirs(
49284914
49294915 if (use_system_abi) {
49304916 const libc = try arena.create(LibCInstallation);
4931 libc.* = try LibCInstallation.findNative(.{ .allocator = arena, .verbose = true });
4917 libc.* = try LibCInstallation.findNative(.{ .allocator = arena, .verbose = true, .target = target });
49324918 return detectLibCFromLibCInstallation(arena, target, libc);
49334919 }
49344920
......@@ -4977,69 +4963,59 @@ fn detectLibCFromBuilding(
49774963 arena: Allocator,
49784964 zig_lib_dir: []const u8,
49794965 target: std.Target,
4980 has_macos_sdk: bool,
49814966) !LibCDirs {
4982 switch (target.os.tag) {
4983 .macos => return if (has_macos_sdk)
4984 // For Darwin/macOS, we are all set with getDarwinSDK found earlier.
4985 LibCDirs{
4986 .libc_include_dir_list = &[0][]u8{},
4987 .libc_installation = null,
4988 }
4989 else
4990 getZigShippedLibCIncludeDirsDarwin(arena, zig_lib_dir, target),
4991 else => {
4992 const generic_name = target_util.libCGenericName(target);
4993 // Some architectures are handled by the same set of headers.
4994 const arch_name = if (target.abi.isMusl())
4995 musl.archNameHeaders(target.cpu.arch)
4996 else if (target.cpu.arch.isThumb())
4997 // ARM headers are valid for Thumb too.
4998 switch (target.cpu.arch) {
4999 .thumb => "arm",
5000 .thumbeb => "armeb",
5001 else => unreachable,
5002 }
5003 else
5004 @tagName(target.cpu.arch);
5005 const os_name = @tagName(target.os.tag);
5006 // Musl's headers are ABI-agnostic and so they all have the "musl" ABI name.
5007 const abi_name = if (target.abi.isMusl()) "musl" else @tagName(target.abi);
5008 const s = std.fs.path.sep_str;
5009 const arch_include_dir = try std.fmt.allocPrint(
5010 arena,
5011 "{s}" ++ s ++ "libc" ++ s ++ "include" ++ s ++ "{s}-{s}-{s}",
5012 .{ zig_lib_dir, arch_name, os_name, abi_name },
5013 );
5014 const generic_include_dir = try std.fmt.allocPrint(
5015 arena,
5016 "{s}" ++ s ++ "libc" ++ s ++ "include" ++ s ++ "generic-{s}",
5017 .{ zig_lib_dir, generic_name },
5018 );
5019 const generic_arch_name = target_util.osArchName(target);
5020 const arch_os_include_dir = try std.fmt.allocPrint(
5021 arena,
5022 "{s}" ++ s ++ "libc" ++ s ++ "include" ++ s ++ "{s}-{s}-any",
5023 .{ zig_lib_dir, generic_arch_name, os_name },
5024 );
5025 const generic_os_include_dir = try std.fmt.allocPrint(
5026 arena,
5027 "{s}" ++ s ++ "libc" ++ s ++ "include" ++ s ++ "any-{s}-any",
5028 .{ zig_lib_dir, os_name },
5029 );
4967 if (target.isDarwin())
4968 return getZigShippedLibCIncludeDirsDarwin(arena, zig_lib_dir, target);
4969
4970 const generic_name = target_util.libCGenericName(target);
4971 // Some architectures are handled by the same set of headers.
4972 const arch_name = if (target.abi.isMusl())
4973 musl.archNameHeaders(target.cpu.arch)
4974 else if (target.cpu.arch.isThumb())
4975 // ARM headers are valid for Thumb too.
4976 switch (target.cpu.arch) {
4977 .thumb => "arm",
4978 .thumbeb => "armeb",
4979 else => unreachable,
4980 }
4981 else
4982 @tagName(target.cpu.arch);
4983 const os_name = @tagName(target.os.tag);
4984 // Musl's headers are ABI-agnostic and so they all have the "musl" ABI name.
4985 const abi_name = if (target.abi.isMusl()) "musl" else @tagName(target.abi);
4986 const s = std.fs.path.sep_str;
4987 const arch_include_dir = try std.fmt.allocPrint(
4988 arena,
4989 "{s}" ++ s ++ "libc" ++ s ++ "include" ++ s ++ "{s}-{s}-{s}",
4990 .{ zig_lib_dir, arch_name, os_name, abi_name },
4991 );
4992 const generic_include_dir = try std.fmt.allocPrint(
4993 arena,
4994 "{s}" ++ s ++ "libc" ++ s ++ "include" ++ s ++ "generic-{s}",
4995 .{ zig_lib_dir, generic_name },
4996 );
4997 const generic_arch_name = target_util.osArchName(target);
4998 const arch_os_include_dir = try std.fmt.allocPrint(
4999 arena,
5000 "{s}" ++ s ++ "libc" ++ s ++ "include" ++ s ++ "{s}-{s}-any",
5001 .{ zig_lib_dir, generic_arch_name, os_name },
5002 );
5003 const generic_os_include_dir = try std.fmt.allocPrint(
5004 arena,
5005 "{s}" ++ s ++ "libc" ++ s ++ "include" ++ s ++ "any-{s}-any",
5006 .{ zig_lib_dir, os_name },
5007 );
50305008
5031 const list = try arena.alloc([]const u8, 4);
5032 list[0] = arch_include_dir;
5033 list[1] = generic_include_dir;
5034 list[2] = arch_os_include_dir;
5035 list[3] = generic_os_include_dir;
5009 const list = try arena.alloc([]const u8, 4);
5010 list[0] = arch_include_dir;
5011 list[1] = generic_include_dir;
5012 list[2] = arch_os_include_dir;
5013 list[3] = generic_os_include_dir;
50365014
5037 return LibCDirs{
5038 .libc_include_dir_list = list,
5039 .libc_installation = null,
5040 };
5041 },
5042 }
5015 return LibCDirs{
5016 .libc_include_dir_list = list,
5017 .libc_installation = null,
5018 };
50435019}
50445020
50455021pub fn get_libc_crt_file(comp: *Compilation, arena: Allocator, basename: []const u8) ![]const u8 {
src/libc_installation.zig+15-1
......@@ -33,6 +33,7 @@ pub const LibCInstallation = struct {
3333 LibCKernel32LibNotFound,
3434 UnsupportedArchitecture,
3535 WindowsSdkNotFound,
36 DarwinSdkNotFound,
3637 ZigIsTheCCompiler,
3738 };
3839
......@@ -171,6 +172,7 @@ pub const LibCInstallation = struct {
171172
172173 pub const FindNativeOptions = struct {
173174 allocator: Allocator,
175 target: std.Target,
174176
175177 /// If enabled, will print human-friendly errors to stderr.
176178 verbose: bool = false,
......@@ -181,7 +183,19 @@ pub const LibCInstallation = struct {
181183 var self: LibCInstallation = .{};
182184
183185 if (is_darwin) {
184 @panic("Darwin is handled separately via std.zig.system.darwin module");
186 if (!std.zig.system.darwin.isDarwinSDKInstalled(args.allocator))
187 return error.DarwinSdkNotFound;
188 const sdk = std.zig.system.darwin.getDarwinSDK(args.allocator, args.target) orelse
189 return error.DarwinSdkNotFound;
190 defer args.allocator.free(sdk.path);
191
192 self.include_dir = try fs.path.join(args.allocator, &.{
193 sdk.path, "usr/include",
194 });
195 self.sys_include_dir = try fs.path.join(args.allocator, &.{
196 sdk.path, "usr/include",
197 });
198 return self;
185199 } else if (is_windows) {
186200 var sdk: ZigWindowsSDK = ZigWindowsSDK.find(args.allocator) catch |err| switch (err) {
187201 error.NotFound => return error.WindowsSdkNotFound,
src/link.zig+1-3
......@@ -231,6 +231,7 @@ pub const Options = struct {
231231
232232 version: ?std.SemanticVersion,
233233 compatibility_version: ?std.SemanticVersion,
234 darwin_sdk_version: ?std.SemanticVersion = null,
234235 libc_installation: ?*const LibCInstallation,
235236
236237 dwarf_format: ?std.dwarf.Format,
......@@ -241,9 +242,6 @@ pub const Options = struct {
241242 /// (Zig compiler development) Enable dumping of linker's state as JSON.
242243 enable_link_snapshots: bool = false,
243244
244 /// (Darwin) Path and version of the native SDK if detected.
245 native_darwin_sdk: ?std.zig.system.darwin.DarwinSDK = null,
246
247245 /// (Darwin) Install name for the dylib
248246 install_name: ?[]const u8 = null,
249247
src/link/MachO/load_commands.zig+4-5
......@@ -278,11 +278,10 @@ pub fn writeBuildVersionLC(options: *const link.Options, lc_writer: anytype) !vo
278278 const platform_version = @as(u32, @intCast(ver.major << 16 | ver.minor << 8));
279279 break :blk platform_version;
280280 };
281 const sdk_version = if (options.native_darwin_sdk) |sdk| blk: {
282 const ver = sdk.version;
283 const sdk_version = @as(u32, @intCast(ver.major << 16 | ver.minor << 8));
284 break :blk sdk_version;
285 } else platform_version;
281 const sdk_version: u32 = if (options.darwin_sdk_version) |ver|
282 @intCast(ver.major << 16 | ver.minor << 8)
283 else
284 platform_version;
286285 const is_simulator_abi = options.target.abi == .simulator;
287286 try lc_writer.writeStruct(macho.build_version_command{
288287 .cmdsize = cmdsize,
src/main.zig+2-2
......@@ -891,7 +891,6 @@ fn buildOutputType(
891891 var minor_subsystem_version: ?u32 = null;
892892 var wasi_exec_model: ?std.builtin.WasiExecModel = null;
893893 var enable_link_snapshots: bool = false;
894 var native_darwin_sdk: ?std.zig.system.darwin.DarwinSDK = null;
895894 var install_name: ?[]const u8 = null;
896895 var hash_style: link.HashStyle = .both;
897896 var entitlements: ?[]const u8 = null;
......@@ -3367,7 +3366,6 @@ fn buildOutputType(
33673366 .wasi_exec_model = wasi_exec_model,
33683367 .debug_compile_errors = debug_compile_errors,
33693368 .enable_link_snapshots = enable_link_snapshots,
3370 .native_darwin_sdk = native_darwin_sdk,
33713369 .install_name = install_name,
33723370 .entitlements = entitlements,
33733371 .pagezero_size = pagezero_size,
......@@ -4243,10 +4241,12 @@ pub fn cmdLibC(gpa: Allocator, args: []const []const u8) !void {
42434241 if (!cross_target.isNative()) {
42444242 fatal("unable to detect libc for non-native target", .{});
42454243 }
4244 const target_info = try detectNativeTargetInfo(cross_target);
42464245
42474246 var libc = LibCInstallation.findNative(.{
42484247 .allocator = gpa,
42494248 .verbose = true,
4249 .target = target_info.target,
42504250 }) catch |err| {
42514251 fatal("unable to detect native libc: {s}", .{@errorName(err)});
42524252 };