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 {...@@ -1554,10 +1554,10 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
1554 .use_lld = use_lld,1554 .use_lld = use_lld,
1555 .use_llvm = use_llvm,1555 .use_llvm = use_llvm,
1556 .use_lib_llvm = use_lib_llvm,1556 .use_lib_llvm = use_lib_llvm,
1557 .libc_provider = libc_dirs.provider,
1558 .link_libc = link_libc,1557 .link_libc = link_libc,
1559 .link_libcpp = link_libcpp,1558 .link_libcpp = link_libcpp,
1560 .link_libunwind = link_libunwind,1559 .link_libunwind = link_libunwind,
1560 .darwinSdkLayout = libc_dirs.darwinSdkLayout,
1561 .objects = options.link_objects,1561 .objects = options.link_objects,
1562 .frameworks = options.frameworks,1562 .frameworks = options.frameworks,
1563 .framework_dirs = options.framework_dirs,1563 .framework_dirs = options.framework_dirs,
...@@ -5287,6 +5287,7 @@ fn detectWin32ResourceIncludeDirs(arena: Allocator, options: InitOptions) !LibCD...@@ -5287,6 +5287,7 @@ fn detectWin32ResourceIncludeDirs(arena: Allocator, options: InitOptions) !LibCD
5287 .libc_installation = null,5287 .libc_installation = null,
5288 .libc_framework_dir_list = &.{},5288 .libc_framework_dir_list = &.{},
5289 .sysroot = null,5289 .sysroot = null,
5290 .darwinSdkLayout = .none,
5290 },5291 },
5291 }5292 }
5292 }5293 }
...@@ -5655,7 +5656,7 @@ const LibCDirs = struct {...@@ -5655,7 +5656,7 @@ const LibCDirs = struct {
5655 libc_installation: ?*const LibCInstallation,5656 libc_installation: ?*const LibCInstallation,
5656 libc_framework_dir_list: []const []const u8,5657 libc_framework_dir_list: []const []const u8,
5657 sysroot: ?[]const u8,5658 sysroot: ?[]const u8,
5658 provider: link.LibCProvider,5659 darwinSdkLayout: link.DarwinSdkLayout,
5659};5660};
56605661
5661fn getZigShippedLibCIncludeDirsDarwin(arena: Allocator, zig_lib_dir: []const u8) !LibCDirs {5662fn getZigShippedLibCIncludeDirsDarwin(arena: Allocator, zig_lib_dir: []const u8) !LibCDirs {
...@@ -5671,7 +5672,7 @@ fn getZigShippedLibCIncludeDirsDarwin(arena: Allocator, zig_lib_dir: []const u8)...@@ -5671,7 +5672,7 @@ fn getZigShippedLibCIncludeDirsDarwin(arena: Allocator, zig_lib_dir: []const u8)
5671 .libc_installation = null,5672 .libc_installation = null,
5672 .libc_framework_dir_list = &.{},5673 .libc_framework_dir_list = &.{},
5673 .sysroot = null,5674 .sysroot = null,
5674 .provider = .vendored,5675 .darwinSdkLayout = .vendored,
5675 };5676 };
5676}5677}
56775678
...@@ -5689,7 +5690,7 @@ pub fn detectLibCIncludeDirs(...@@ -5689,7 +5690,7 @@ pub fn detectLibCIncludeDirs(
5689 .libc_installation = null,5690 .libc_installation = null,
5690 .libc_framework_dir_list = &.{},5691 .libc_framework_dir_list = &.{},
5691 .sysroot = null,5692 .sysroot = null,
5692 .provider = .none,5693 .darwinSdkLayout = .none,
5693 };5694 };
5694 }5695 }
56955696
...@@ -5747,7 +5748,7 @@ pub fn detectLibCIncludeDirs(...@@ -5747,7 +5748,7 @@ pub fn detectLibCIncludeDirs(
5747 .libc_installation = null,5748 .libc_installation = null,
5748 .libc_framework_dir_list = &.{},5749 .libc_framework_dir_list = &.{},
5749 .sysroot = null,5750 .sysroot = null,
5750 .provider = .none,5751 .darwinSdkLayout = .none,
5751 };5752 };
5752}5753}
57535754
...@@ -5802,7 +5803,7 @@ fn detectLibCFromLibCInstallation(arena: Allocator, target: Target, lci: *const...@@ -5802,7 +5803,7 @@ fn detectLibCFromLibCInstallation(arena: Allocator, target: Target, lci: *const
5802 .libc_installation = lci,5803 .libc_installation = lci,
5803 .libc_framework_dir_list = framework_list.items,5804 .libc_framework_dir_list = framework_list.items,
5804 .sysroot = sysroot,5805 .sysroot = sysroot,
5805 .provider = if (sysroot == null) .installation else .sysroot,5806 .darwinSdkLayout = if (sysroot == null) .none else .sdk,
5806 };5807 };
5807}5808}
58085809
...@@ -5864,7 +5865,7 @@ fn detectLibCFromBuilding(...@@ -5864,7 +5865,7 @@ fn detectLibCFromBuilding(
5864 .libc_installation = null,5865 .libc_installation = null,
5865 .libc_framework_dir_list = &.{},5866 .libc_framework_dir_list = &.{},
5866 .sysroot = null,5867 .sysroot = null,
5867 .provider = .vendored,5868 .darwinSdkLayout = .vendored,
5868 };5869 };
5869}5870}
58705871
src/link.zig+7-4
...@@ -134,10 +134,10 @@ pub const Options = struct {...@@ -134,10 +134,10 @@ pub const Options = struct {
134 /// Otherwise (depending on `use_lld`) this link code directly outputs and updates the final binary.134 /// Otherwise (depending on `use_lld`) this link code directly outputs and updates the final binary.
135 use_llvm: bool,135 use_llvm: bool,
136 use_lib_llvm: bool,136 use_lib_llvm: bool,
137 libc_provider: LibCProvider,
138 link_libc: bool,137 link_libc: bool,
139 link_libcpp: bool,138 link_libcpp: bool,
140 link_libunwind: bool,139 link_libunwind: bool,
140 darwinSdkLayout: DarwinSdkLayout,
141 function_sections: bool,141 function_sections: bool,
142 no_builtin: bool,142 no_builtin: bool,
143 eh_frame_hdr: bool,143 eh_frame_hdr: bool,
...@@ -283,10 +283,13 @@ pub const HashStyle = enum { sysv, gnu, both };...@@ -283,10 +283,13 @@ pub const HashStyle = enum { sysv, gnu, both };
283283
284pub const CompressDebugSections = enum { none, zlib };284pub 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.
287 none,289 none,
288 installation,290 /// macOS SDK layout: TOP { /usr/include, /usr/lib, /System/Library/Frameworks }.
289 sysroot,291 sdk,
292 /// Shipped libc layout: TOP { /lib/libc/include, /lib/libc/darwin, <NONE> }.
290 vendored,293 vendored,
291};294};
292295
src/link/MachO.zig+3-4
...@@ -558,7 +558,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No...@@ -558,7 +558,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No
558 });558 });
559 {559 {
560 const platform = Platform.fromTarget(self.base.options.target);560 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);
562 if (platform.isBuildVersionCompatible()) {562 if (platform.isBuildVersionCompatible()) {
563 try load_commands.writeBuildVersionLC(platform, sdk_version, lc_writer);563 try load_commands.writeBuildVersionLC(platform, sdk_version, lc_writer);
564 } else if (platform.isVersionMinCompatible()) {564 } else if (platform.isVersionMinCompatible()) {
...@@ -652,10 +652,9 @@ pub fn resolveLibSystem(...@@ -652,10 +652,9 @@ pub fn resolveLibSystem(
652 "libSystem",652 "libSystem",
653 )) break :success;653 )) break :success;
654654
655 switch (self.base.options.libc_provider) {655 switch (self.base.options.darwinSdkLayout) {
656 .none => unreachable,656 .none => unreachable,
657 .installation => unreachable,657 .sdk => {
658 .sysroot => {
659 const dir = try fs.path.join(tmp_arena, &[_][]const u8{ self.base.options.sysroot.?, "usr", "lib" });658 const dir = try fs.path.join(tmp_arena, &[_][]const u8{ self.base.options.sysroot.?, "usr", "lib" });
660 if (try accessLibPath(tmp_arena, &test_path, &checked_paths, dir, "libSystem")) break :success;659 if (try accessLibPath(tmp_arena, &test_path, &checked_paths, dir, "libSystem")) break :success;
661 },660 },
src/link/MachO/load_commands.zig+23-16
...@@ -467,31 +467,27 @@ pub inline fn appleVersionToSemanticVersion(version: u32) std.SemanticVersion {...@@ -467,31 +467,27 @@ pub inline fn appleVersionToSemanticVersion(version: u32) std.SemanticVersion {
467 };467 };
468}468}
469469
470fn readSdkVersionString(arena: Allocator, dir: []const u8) ![]const u8 {470pub fn inferSdkVersion(gpa: Allocator, comp: *const Compilation) ?std.SemanticVersion {
471 const sdk_path = try std.fs.path.join(arena, &.{ dir, "SDKSettings.json" });471 var arena_allocator = std.heap.ArenaAllocator.init(gpa);
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);
480 defer arena_allocator.deinit();472 defer arena_allocator.deinit();
481 const arena = arena_allocator.allocator();473 const arena = arena_allocator.allocator();
474
482 const options = comp.bin_file.options;475 const options = comp.bin_file.options;
483476
484 const sdk_dir = switch (options.libc_provider) {477 const sdk_dir = switch (options.darwinSdkLayout) {
485 .none => unreachable,478 .none => unreachable,
486 .installation => unreachable,479 .sdk => options.sysroot.?,
487 .sysroot => options.sysroot.?,
488 .vendored => std.fs.path.join(arena, &.{ comp.zig_lib_directory.path.?, "libc", "darwin" }) catch return null,480 .vendored => std.fs.path.join(arena, &.{ comp.zig_lib_directory.path.?, "libc", "darwin" }) catch return null,
489 };481 };
490482
491 // prefer meta information if available483 if (readSdkVersionFromSettings(arena, sdk_dir)) |ver| {
492 if (readSdkVersionString(arena, sdk_dir)) |ver| {
493 return parseSdkVersion(ver);484 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
496 // infer from pathname492 // infer from pathname
497 const stem = std.fs.path.stem(sdk_dir);493 const stem = std.fs.path.stem(sdk_dir);
...@@ -505,6 +501,17 @@ pub fn inferSdkVersion(comp: *const Compilation) ?std.SemanticVersion {...@@ -505,6 +501,17 @@ pub fn inferSdkVersion(comp: *const Compilation) ?std.SemanticVersion {
505 return parseSdkVersion(stem[start..end]);501 return parseSdkVersion(stem[start..end]);
506}502}
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
508// Versions reported by Apple aren't exactly semantically valid as they usually omit515// Versions reported by Apple aren't exactly semantically valid as they usually omit
509// the patch component, so we parse SDK value by hand.516// the patch component, so we parse SDK value by hand.
510fn parseSdkVersion(raw: []const u8) ?std.SemanticVersion {517fn parseSdkVersion(raw: []const u8) ?std.SemanticVersion {
src/link/MachO/zld.zig+2-2
...@@ -241,7 +241,7 @@ pub fn linkWithZld(...@@ -241,7 +241,7 @@ pub fn linkWithZld(
241 try argv.append(@tagName(platform.os_tag));241 try argv.append(@tagName(platform.os_tag));
242 try argv.append(try std.fmt.allocPrint(arena, "{}", .{platform.version}));242 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);
245 if (sdk_version) |ver| {245 if (sdk_version) |ver| {
246 try argv.append(try std.fmt.allocPrint(arena, "{d}.{d}", .{ ver.major, ver.minor }));246 try argv.append(try std.fmt.allocPrint(arena, "{d}.{d}", .{ ver.major, ver.minor }));
247 } else {247 } else {
...@@ -588,7 +588,7 @@ pub fn linkWithZld(...@@ -588,7 +588,7 @@ pub fn linkWithZld(
588 });588 });
589 {589 {
590 const platform = Platform.fromTarget(macho_file.base.options.target);590 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);
592 if (platform.isBuildVersionCompatible()) {592 if (platform.isBuildVersionCompatible()) {
593 try load_commands.writeBuildVersionLC(platform, sdk_version, lc_writer);593 try load_commands.writeBuildVersionLC(platform, sdk_version, lc_writer);
594 } else {594 } else {