authorgravatar for michael.dusan@gmail.comMichael Dusan <michael.dusan@gmail.com> 2023-09-22 14:10:24-04:00
committergravatar for michael.dusan@gmail.comMichael Dusan <michael.dusan@gmail.com> 2023-09-25 15:53:05-04:00
log9357973912798d3f64938762ea8993ff3a083ac0
tree96904629a22bb99a16b427857569696d8612c276
parent50f2d7958226efaa9cd441998877c125cd01533b
signaturelock-open Commit is signed but in an unrecognized format.

kubkon review changes: 1

general: - rename `DarwinSdkLayout` → `DarwinSdkLayout` - drop `DarwinSdkLayout.installation` (not needed for darwin) - document struct inferSdkVersion: - use explicit allocator - avoid trying to infer SDK ver from vendored path

5 files changed, 43 insertions(+), 33 deletions(-)

src/Compilation.zig+8-7
......@@ -1554,10 +1554,10 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
15541554 .use_lld = use_lld,
15551555 .use_llvm = use_llvm,
15561556 .use_lib_llvm = use_lib_llvm,
1557 .libc_provider = libc_dirs.provider,
15581557 .link_libc = link_libc,
15591558 .link_libcpp = link_libcpp,
15601559 .link_libunwind = link_libunwind,
1560 .darwinSdkLayout = libc_dirs.darwinSdkLayout,
15611561 .objects = options.link_objects,
15621562 .frameworks = options.frameworks,
15631563 .framework_dirs = options.framework_dirs,
......@@ -5287,6 +5287,7 @@ fn detectWin32ResourceIncludeDirs(arena: Allocator, options: InitOptions) !LibCD
52875287 .libc_installation = null,
52885288 .libc_framework_dir_list = &.{},
52895289 .sysroot = null,
5290 .darwinSdkLayout = .none,
52905291 },
52915292 }
52925293 }
......@@ -5655,7 +5656,7 @@ const LibCDirs = struct {
56555656 libc_installation: ?*const LibCInstallation,
56565657 libc_framework_dir_list: []const []const u8,
56575658 sysroot: ?[]const u8,
5658 provider: link.LibCProvider,
5659 darwinSdkLayout: link.DarwinSdkLayout,
56595660};
56605661
56615662fn getZigShippedLibCIncludeDirsDarwin(arena: Allocator, zig_lib_dir: []const u8) !LibCDirs {
......@@ -5671,7 +5672,7 @@ fn getZigShippedLibCIncludeDirsDarwin(arena: Allocator, zig_lib_dir: []const u8)
56715672 .libc_installation = null,
56725673 .libc_framework_dir_list = &.{},
56735674 .sysroot = null,
5674 .provider = .vendored,
5675 .darwinSdkLayout = .vendored,
56755676 };
56765677}
56775678
......@@ -5689,7 +5690,7 @@ pub fn detectLibCIncludeDirs(
56895690 .libc_installation = null,
56905691 .libc_framework_dir_list = &.{},
56915692 .sysroot = null,
5692 .provider = .none,
5693 .darwinSdkLayout = .none,
56935694 };
56945695 }
56955696
......@@ -5747,7 +5748,7 @@ pub fn detectLibCIncludeDirs(
57475748 .libc_installation = null,
57485749 .libc_framework_dir_list = &.{},
57495750 .sysroot = null,
5750 .provider = .none,
5751 .darwinSdkLayout = .none,
57515752 };
57525753}
57535754
......@@ -5802,7 +5803,7 @@ fn detectLibCFromLibCInstallation(arena: Allocator, target: Target, lci: *const
58025803 .libc_installation = lci,
58035804 .libc_framework_dir_list = framework_list.items,
58045805 .sysroot = sysroot,
5805 .provider = if (sysroot == null) .installation else .sysroot,
5806 .darwinSdkLayout = if (sysroot == null) .none else .sdk,
58065807 };
58075808}
58085809
......@@ -5864,7 +5865,7 @@ fn detectLibCFromBuilding(
58645865 .libc_installation = null,
58655866 .libc_framework_dir_list = &.{},
58665867 .sysroot = null,
5867 .provider = .vendored,
5868 .darwinSdkLayout = .vendored,
58685869 };
58695870}
58705871
src/link.zig+7-4
......@@ -134,10 +134,10 @@ pub const Options = struct {
134134 /// Otherwise (depending on `use_lld`) this link code directly outputs and updates the final binary.
135135 use_llvm: bool,
136136 use_lib_llvm: bool,
137 libc_provider: LibCProvider,
138137 link_libc: bool,
139138 link_libcpp: bool,
140139 link_libunwind: bool,
140 darwinSdkLayout: DarwinSdkLayout,
141141 function_sections: bool,
142142 no_builtin: bool,
143143 eh_frame_hdr: bool,
......@@ -283,10 +283,13 @@ pub const HashStyle = enum { sysv, gnu, both };
283283
284284pub const CompressDebugSections = enum { none, zlib };
285285
286pub const LibCProvider = enum {
286/// The filesystem layout of darwin SDK elements.
287pub const DarwinSdkLayout = enum {
288 /// Does not apply to the target.
287289 none,
288 installation,
289 sysroot,
290 /// macOS SDK layout: TOP { /usr/include, /usr/lib, /System/Library/Frameworks }.
291 sdk,
292 /// Shipped libc layout: TOP { /lib/libc/include, /lib/libc/darwin, <NONE> }.
290293 vendored,
291294};
292295
src/link/MachO.zig+3-4
......@@ -558,7 +558,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No
558558 });
559559 {
560560 const platform = Platform.fromTarget(self.base.options.target);
561 const sdk_version: ?std.SemanticVersion = load_commands.inferSdkVersion(comp);
561 const sdk_version: ?std.SemanticVersion = load_commands.inferSdkVersion(arena, comp);
562562 if (platform.isBuildVersionCompatible()) {
563563 try load_commands.writeBuildVersionLC(platform, sdk_version, lc_writer);
564564 } else if (platform.isVersionMinCompatible()) {
......@@ -652,10 +652,9 @@ pub fn resolveLibSystem(
652652 "libSystem",
653653 )) break :success;
654654
655 switch (self.base.options.libc_provider) {
655 switch (self.base.options.darwinSdkLayout) {
656656 .none => unreachable,
657 .installation => unreachable,
658 .sysroot => {
657 .sdk => {
659658 const dir = try fs.path.join(tmp_arena, &[_][]const u8{ self.base.options.sysroot.?, "usr", "lib" });
660659 if (try accessLibPath(tmp_arena, &test_path, &checked_paths, dir, "libSystem")) break :success;
661660 },
src/link/MachO/load_commands.zig+23-16
......@@ -467,31 +467,27 @@ pub inline fn appleVersionToSemanticVersion(version: u32) std.SemanticVersion {
467467 };
468468}
469469
470fn readSdkVersionString(arena: Allocator, dir: []const u8) ![]const u8 {
471 const sdk_path = try std.fs.path.join(arena, &.{ dir, "SDKSettings.json" });
472 const contents = try std.fs.cwd().readFileAlloc(arena, sdk_path, std.math.maxInt(u16));
473 const parsed = try std.json.parseFromSlice(std.json.Value, arena, contents, .{});
474 if (parsed.value.object.get("MinimalDisplayName")) |ver| return ver.string;
475 return error.SdkVersionFailure;
476}
477
478pub fn inferSdkVersion(comp: *const Compilation) ?std.SemanticVersion {
479 var arena_allocator = std.heap.ArenaAllocator.init(comp.gpa);
470pub fn inferSdkVersion(gpa: Allocator, comp: *const Compilation) ?std.SemanticVersion {
471 var arena_allocator = std.heap.ArenaAllocator.init(gpa);
480472 defer arena_allocator.deinit();
481473 const arena = arena_allocator.allocator();
474
482475 const options = comp.bin_file.options;
483476
484 const sdk_dir = switch (options.libc_provider) {
477 const sdk_dir = switch (options.darwinSdkLayout) {
485478 .none => unreachable,
486 .installation => unreachable,
487 .sysroot => options.sysroot.?,
479 .sdk => options.sysroot.?,
488480 .vendored => std.fs.path.join(arena, &.{ comp.zig_lib_directory.path.?, "libc", "darwin" }) catch return null,
489481 };
490482
491 // prefer meta information if available
492 if (readSdkVersionString(arena, sdk_dir)) |ver| {
483 if (readSdkVersionFromSettings(arena, sdk_dir)) |ver| {
493484 return parseSdkVersion(ver);
494 } else |_| {}
485 } else |_| {
486 if (options.darwinSdkLayout == .vendored) {
487 // vendored layout does not have versioned pathname
488 return null;
489 }
490 }
495491
496492 // infer from pathname
497493 const stem = std.fs.path.stem(sdk_dir);
......@@ -505,6 +501,17 @@ pub fn inferSdkVersion(comp: *const Compilation) ?std.SemanticVersion {
505501 return parseSdkVersion(stem[start..end]);
506502}
507503
504// Official Apple SDKs ship with a `SDKSettings.json` located at the top of SDK fs layout.
505// Use property `MinimalDisplayName` to determine version.
506// The file/property is also available with vendored libc.
507fn readSdkVersionFromSettings(arena: Allocator, dir: []const u8) ![]const u8 {
508 const sdk_path = try std.fs.path.join(arena, &.{ dir, "SDKSettings.json" });
509 const contents = try std.fs.cwd().readFileAlloc(arena, sdk_path, std.math.maxInt(u16));
510 const parsed = try std.json.parseFromSlice(std.json.Value, arena, contents, .{});
511 if (parsed.value.object.get("MinimalDisplayName")) |ver| return ver.string;
512 return error.SdkVersionFailure;
513}
514
508515// Versions reported by Apple aren't exactly semantically valid as they usually omit
509516// the patch component, so we parse SDK value by hand.
510517fn parseSdkVersion(raw: []const u8) ?std.SemanticVersion {
src/link/MachO/zld.zig+2-2
......@@ -241,7 +241,7 @@ pub fn linkWithZld(
241241 try argv.append(@tagName(platform.os_tag));
242242 try argv.append(try std.fmt.allocPrint(arena, "{}", .{platform.version}));
243243
244 const sdk_version: ?std.SemanticVersion = load_commands.inferSdkVersion(comp);
244 const sdk_version: ?std.SemanticVersion = load_commands.inferSdkVersion(arena, comp);
245245 if (sdk_version) |ver| {
246246 try argv.append(try std.fmt.allocPrint(arena, "{d}.{d}", .{ ver.major, ver.minor }));
247247 } else {
......@@ -588,7 +588,7 @@ pub fn linkWithZld(
588588 });
589589 {
590590 const platform = Platform.fromTarget(macho_file.base.options.target);
591 const sdk_version: ?std.SemanticVersion = load_commands.inferSdkVersion(comp);
591 const sdk_version: ?std.SemanticVersion = load_commands.inferSdkVersion(arena, comp);
592592 if (platform.isBuildVersionCompatible()) {
593593 try load_commands.writeBuildVersionLC(platform, sdk_version, lc_writer);
594594 } else {