Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ship versioned libc headers on macOS #10215

Merged
merged 7 commits into from
Nov 26, 2021
Merged

Ship versioned libc headers on macOS #10215

merged 7 commits into from
Nov 26, 2021

Conversation

kubkon
Copy link
Member

@kubkon kubkon commented Nov 24, 2021

Fixes #10200

Previously, we would ship a singular set of libc headers per macOS CPU architecture. This PR rectifies it by now shipping a separate set of headers per macOS version AND CPU architecture. The headers are deduplicated among themselves following a 3 layer approach such that:

  • layer 1: x86_64-macos.10 x86_64-macos.11 x86_64-macos.12 aarch64-macos.11 aarch64-macos.12
  • layer 2: any-macos.10 any-macos.11 any-macos.12
  • layer 3: any-macos-any

where each subsequent layer contains common headers from the previous layer. More on this can be found in the discussion in ziglang/fetch-them-macos-headers#15.

Changes required to make this work include:

  • treating macOS target separately in Compilation.detectLibCIncludeDirs (dab6414)
  • temporarily tweaking std.Target.Os.defaultVersionRange to also accept std.Target.Cpu.Arch enum as there is currently a mismatch between the minimum version of macOS supported by x86_64 and aarch64 (the former is 10.15, while the latter is 11.6) (baf4609)
  • do not rely on headers shipped with Zig if we are building natively AND we have detected an SDK using xcrun --sdk macosx --show-sdk-path - turns out that it is possible to have SDK 11.1 on macOS 10.15, or SDK 12.0 on macOS 11.6. I'm guessing that Apple offers devs on the older OSes to target newer / latest OS too.
  • version libSystem.B.tbd shipped with Zig to match the versions that Zig currently supports

@kubkon kubkon requested a review from andrewrk November 24, 2021 20:24
@kubkon
Copy link
Member Author

kubkon commented Nov 24, 2021

cc @slimsag

@andrewrk
Copy link
Member

Looks good so far! There's one more place you'll need to edit in Compilation.zig for the generated builtin.zig source.

`fetch-them-macos-headers` gitrev
7036517cc6a9aa154e7aef4c4593b5c4a5143ed4
This is mainly because arm64 macOS doesn't support all
versions supported by x86_64 macOS. This is just a temporary
thing until both architectures support the same set of OSes.
This means that I am purposefully regressing linking iOS and related
which will require manual specification of the sysroot path, etc.
This is handled before by detecting and adding SDK path which
is a centralised point for the native libc installation on darwin.
@kubkon kubkon force-pushed the macos-versions branch 2 times, most recently from 9db4d61 to f8eb840 Compare November 25, 2021 15:58
We will mimick the same solution as with the headers:
* `libSystem.10.tbd`
* `libSystem.11.tbd`
* `libSystem.12.tbd`

and so on...
@kubkon
Copy link
Member Author

kubkon commented Nov 25, 2021

Looks good so far! There's one more place you'll need to edit in Compilation.zig for the generated builtin.zig source.

Hmm, are you sure anything needs updating in Compilation.zig? I don't see any use of defaultVersionRange in the generated builtin.zig source there. It seems to be using a direct constructor with already inferred version ranges for the OS.

@kubkon kubkon marked this pull request as ready for review November 25, 2021 16:42
@kubkon
Copy link
Member Author

kubkon commented Nov 25, 2021

Ready for review! I've fixed one of the oversights I made when adding better iOS, iPadOS, etc. support to Zig. Namely, since all of these represent cross-compilation targets from macOS, if you decide to cross-compile to any such target, you will need to manually specify relevant sysroot and syslib / framework paths on the command line and in your build.zig file. This behaviour is now consistent with any other cross-compilation target in Zig I believe. The auto-inferred SDK paths are only used if we're compiling something natively (from host to host). So, to build for iPhone simulator on the M1 for example, you will need to spell out something like:

$ zig build-exe test.zig -target aarch64-ios-simulator --sysroot $(xcrun --sdk iphonesimulator --show-sdk-path) -L/usr/lib -F/System/Library/Frameworks

But, if you're building the same test.zig natively, this suffices:

$ zig build-exe test.zig

@kubkon
Copy link
Member Author

kubkon commented Nov 25, 2021

Finally, you are now free to target any of the supported macOS versions for cross-compilation using version ranges. For instance, in order to target Catalina from Monterey, all you need to do is:

$ zig cc hello.c -target x86_64-macos.10

Similarly, if we want to target M1 Monterey from a Catalina-based Intel MBP, we can do:

$ zig cc hello.c -target aarch64-macos.12

Tl;dr versioning is currently based on major macOS revisions - 10 for Catalina, 11 for BigSur, 12 for Monterey. If this is confusing, or if Apple decides to use minor versioning again between different OS cuts (10.14 vs 10.15), we can add that in too.

};

const sysroot = blk: {
if (options.sysroot) |sysroot| {
break :blk sysroot;
} else if (darwin_can_use_system_sdk) {
} else if (darwin_use_system_sdk) {
break :blk try std.zig.system.darwin.getSDKPath(arena, options.target);
Copy link
Sponsor Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that this change might fix an issue I've been meaning to file for a while now, #10217, specifically when specifying a cross-compilation target. WDYT?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I hope that's the case too actually. Would you mind checking after this gets merged, or building zig directly from this branch?

Copy link
Sponsor Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will do!

Copy link
Sponsor Contributor

@slimsag slimsag left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks quite good to me!

@andrewrk
Copy link
Member

CI failure:

error(link): undefined reference to symbol '___ulock_wait2'
error(link):   first referenced in '/workspace/zig-cache/o/f13b7e43e90bbe6475a7f932d7504a84/test.o'
thread 51767 panic: attempt to unwrap error: UndefinedSymbolReference
/workspace/src/main.zig:216:9: 0x30c4488 in main.mainArgs (zig1)
        return buildOutputType(gpa, arena, args, .zig_test);
        ^
/workspace/lib/std/heap.zig:150:9: 0x30be120 in std.heap.CAllocator.resize (zig1)
        return error.OutOfMemory;
        ^
/workspace/lib/std/heap.zig:150:9: 0x30be120 in std.heap.CAllocator.resize (zig1)
        return error.OutOfMemory;
        ^
/workspace/lib/std/heap.zig:150:9: 0x30be120 in std.heap.CAllocator.resize (zig1)
        return error.OutOfMemory;
        ^
/workspace/lib/std/heap.zig:150:9: 0x30be120 in std.heap.CAllocator.resize (zig1)
        return error.OutOfMemory;
        ^
/workspace/lib/std/heap.zig:150:9: 0x30be120 in std.heap.CAllocator.resize (zig1)
        return error.OutOfMemory;
        ^
/workspace/lib/std/heap.zig:150:9: 0x30be120 in std.heap.CAllocator.resize (zig1)
        return error.OutOfMemory;
        ^
/workspace/lib/std/heap.zig:150:9: 0x30be120 in std.heap.CAllocator.resize (zig1)
        return error.OutOfMemory;
        ^
/workspace/lib/std/heap.zig:150:9: 0x30be120 in std.heap.CAllocator.resize (zig1)
        return error.OutOfMemory;
        ^
/workspace/lib/std/heap.zig:150:9: 0x30be120 in std.heap.CAllocator.resize (zig1)
        return error.OutOfMemory;
        ^
/workspace/lib/std/heap.zig:150:9: 0x30be120 in std.heap.CAllocator.resize (zig1)
        return error.OutOfMemory;
        ^
/workspace/lib/std/heap.zig:150:9: 0x30be120 in std.heap.CAllocator.resize (zig1)
        return error.OutOfMemory;
        ^
/workspace/lib/std/heap.zig:150:9: 0x30be120 in std.heap.CAllocator.resize (zig1)
        return error.OutOfMemory;
        ^
/workspace/lib/std/heap.zig:150:9: 0x30be120 in std.heap.CAllocator.resize (zig1)
        return error.OutOfMemory;
        ^
/workspace/lib/std/heap.zig:150:9: 0x30be120 in std.heap.CAllocator.resize (zig1)
        return error.OutOfMemory;
        ^
/workspace/lib/std/heap.zig:150:9: 0x30be120 in std.heap.CAllocator.resize (zig1)
        return error.OutOfMemory;
        ^
/workspace/lib/std/heap.zig:150:9: 0x30be120 in std.heap.CAllocator.resize (zig1)
        return error.OutOfMemory;
        ^
/workspace/lib/std/heap.zig:150:9: 0x30be120 in std.heap.CAllocator.resize (zig1)
        return error.OutOfMemory;
        ^
/workspace/lib/std/heap.zig:150:9: 0x30be120 in std.heap.CAllocator.resize (zig1)
        return error.OutOfMemory;
        ^
/workspace/lib/std/heap.zig:150:9: 0x30be120 in std.heap.CAllocator.resize (zig1)
        return error.OutOfMemory;
        ^
/workspace/lib/std/heap.zig:150:9: 0x30be120 in std.heap.CAllocator.resize (zig1)
        return error.OutOfMemory;
        ^
/workspace/lib/std/heap.zig:150:9: 0x30be120 in std.heap.CAllocator.resize (zig1)
        return error.OutOfMemory;
        ^
/workspace/lib/std/heap.zig:150:9: 0x30be120 in std.heap.CAllocator.resize (zig1)
        return error.OutOfMemory;
        ^
/workspace/lib/std/heap.zig:150:9: 0x30be120 in std.heap.CAllocator.resize (zig1)
        return error.OutOfMemory;
        ^
/workspace/lib/std/heap.zig:150:9: 0x30be120 in std.heap.CAllocator.resize (zig1)
        return error.OutOfMemory;
        ^
/workspace/lib/std/heap.zig:150:9: 0x30be120 in std.heap.CAllocator.resize (zig1)
        return error.OutOfMemory;
        ^
/workspace/src/link/MachO.zig:890:13: 0x32a8643 in link.MachO.flushModule (zig1)
            return error.UndefinedSymbolReference;
            ^
/workspace/src/link/MachO.zig:401:5: 0x328b287 in link.MachO.flush (zig1)
    try self.flushModule(comp);
    ^
/workspace/src/link.zig:541:23: 0x3253083 in link.File.flush (zig1)
            .macho => return @fieldParentPtr(MachO, "base", base).flush(comp),
                      ^
/workspace/src/Compilation.zig:1877:5: 0x324b651 in Compilation.update (zig1)
    try self.bin_file.flush(self);
    ^
/workspace/src/main.zig:2689:5: 0x31d90ed in main.updateModule (zig1)
    try comp.update();
    ^
/workspace/src/main.zig:2372:21: 0x30f147a in main.buildOutputType (zig1)
        else => |e| return e,
                    ^
???:?:?: 0x30c5c22 in ??? (???)
/workspace/src/stage1.zig:48:43: 0x30c3d12 in main (zig1)
        stage2.mainArgs(gpa, arena, args) catch unreachable;
                                          ^
???:?:?: 0x8379fe8 in ??? (???)
The following command terminated unexpectedly:
/workspace/_debug/staging/bin/zig test /workspace/lib/std/std.zig --test-name-prefix std-x86_64-macos-gnu-Debug--multi  --cache-dir /workspace/zig-cache --global-cache-dir /root/.cache/zig --name test -target x86_64-macos-gnu -mcpu x86_64 -I /workspace/test --zig-lib-dir /workspace/lib 

@kubkon
Copy link
Member Author

kubkon commented Nov 25, 2021

CI failure:

error(link): undefined reference to symbol '___ulock_wait2'
error(link):   first referenced in '/workspace/zig-cache/o/f13b7e43e90bbe6475a7f932d7504a84/test.o'
thread 51767 panic: attempt to unwrap error: UndefinedSymbolReference
/workspace/src/main.zig:216:9: 0x30c4488 in main.mainArgs (zig1)
        return buildOutputType(gpa, arena, args, .zig_test);
        ^
/workspace/lib/std/heap.zig:150:9: 0x30be120 in std.heap.CAllocator.resize (zig1)
        return error.OutOfMemory;
        ^
/workspace/lib/std/heap.zig:150:9: 0x30be120 in std.heap.CAllocator.resize (zig1)
        return error.OutOfMemory;
        ^
/workspace/lib/std/heap.zig:150:9: 0x30be120 in std.heap.CAllocator.resize (zig1)
        return error.OutOfMemory;
        ^
/workspace/lib/std/heap.zig:150:9: 0x30be120 in std.heap.CAllocator.resize (zig1)
        return error.OutOfMemory;
        ^
/workspace/lib/std/heap.zig:150:9: 0x30be120 in std.heap.CAllocator.resize (zig1)
        return error.OutOfMemory;
        ^
/workspace/lib/std/heap.zig:150:9: 0x30be120 in std.heap.CAllocator.resize (zig1)
        return error.OutOfMemory;
        ^
/workspace/lib/std/heap.zig:150:9: 0x30be120 in std.heap.CAllocator.resize (zig1)
        return error.OutOfMemory;
        ^
/workspace/lib/std/heap.zig:150:9: 0x30be120 in std.heap.CAllocator.resize (zig1)
        return error.OutOfMemory;
        ^
/workspace/lib/std/heap.zig:150:9: 0x30be120 in std.heap.CAllocator.resize (zig1)
        return error.OutOfMemory;
        ^
/workspace/lib/std/heap.zig:150:9: 0x30be120 in std.heap.CAllocator.resize (zig1)
        return error.OutOfMemory;
        ^
/workspace/lib/std/heap.zig:150:9: 0x30be120 in std.heap.CAllocator.resize (zig1)
        return error.OutOfMemory;
        ^
/workspace/lib/std/heap.zig:150:9: 0x30be120 in std.heap.CAllocator.resize (zig1)
        return error.OutOfMemory;
        ^
/workspace/lib/std/heap.zig:150:9: 0x30be120 in std.heap.CAllocator.resize (zig1)
        return error.OutOfMemory;
        ^
/workspace/lib/std/heap.zig:150:9: 0x30be120 in std.heap.CAllocator.resize (zig1)
        return error.OutOfMemory;
        ^
/workspace/lib/std/heap.zig:150:9: 0x30be120 in std.heap.CAllocator.resize (zig1)
        return error.OutOfMemory;
        ^
/workspace/lib/std/heap.zig:150:9: 0x30be120 in std.heap.CAllocator.resize (zig1)
        return error.OutOfMemory;
        ^
/workspace/lib/std/heap.zig:150:9: 0x30be120 in std.heap.CAllocator.resize (zig1)
        return error.OutOfMemory;
        ^
/workspace/lib/std/heap.zig:150:9: 0x30be120 in std.heap.CAllocator.resize (zig1)
        return error.OutOfMemory;
        ^
/workspace/lib/std/heap.zig:150:9: 0x30be120 in std.heap.CAllocator.resize (zig1)
        return error.OutOfMemory;
        ^
/workspace/lib/std/heap.zig:150:9: 0x30be120 in std.heap.CAllocator.resize (zig1)
        return error.OutOfMemory;
        ^
/workspace/lib/std/heap.zig:150:9: 0x30be120 in std.heap.CAllocator.resize (zig1)
        return error.OutOfMemory;
        ^
/workspace/lib/std/heap.zig:150:9: 0x30be120 in std.heap.CAllocator.resize (zig1)
        return error.OutOfMemory;
        ^
/workspace/lib/std/heap.zig:150:9: 0x30be120 in std.heap.CAllocator.resize (zig1)
        return error.OutOfMemory;
        ^
/workspace/lib/std/heap.zig:150:9: 0x30be120 in std.heap.CAllocator.resize (zig1)
        return error.OutOfMemory;
        ^
/workspace/lib/std/heap.zig:150:9: 0x30be120 in std.heap.CAllocator.resize (zig1)
        return error.OutOfMemory;
        ^
/workspace/src/link/MachO.zig:890:13: 0x32a8643 in link.MachO.flushModule (zig1)
            return error.UndefinedSymbolReference;
            ^
/workspace/src/link/MachO.zig:401:5: 0x328b287 in link.MachO.flush (zig1)
    try self.flushModule(comp);
    ^
/workspace/src/link.zig:541:23: 0x3253083 in link.File.flush (zig1)
            .macho => return @fieldParentPtr(MachO, "base", base).flush(comp),
                      ^
/workspace/src/Compilation.zig:1877:5: 0x324b651 in Compilation.update (zig1)
    try self.bin_file.flush(self);
    ^
/workspace/src/main.zig:2689:5: 0x31d90ed in main.updateModule (zig1)
    try comp.update();
    ^
/workspace/src/main.zig:2372:21: 0x30f147a in main.buildOutputType (zig1)
        else => |e| return e,
                    ^
???:?:?: 0x30c5c22 in ??? (???)
/workspace/src/stage1.zig:48:43: 0x30c3d12 in main (zig1)
        stage2.mainArgs(gpa, arena, args) catch unreachable;
                                          ^
???:?:?: 0x8379fe8 in ??? (???)
The following command terminated unexpectedly:
/workspace/_debug/staging/bin/zig test /workspace/lib/std/std.zig --test-name-prefix std-x86_64-macos-gnu-Debug--multi  --cache-dir /workspace/zig-cache --global-cache-dir /root/.cache/zig --name test -target x86_64-macos-gnu -mcpu x86_64 -I /workspace/test --zig-lib-dir /workspace/lib 

A bug in libstd, fixed in a041401.

Copy link
Member

@andrewrk andrewrk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is a really big improvement for targeting macOS!

For those who aren't paying super close attention (and for myself when I type up release notes in a couple weeks):

Master branch, before this PR

  • macOS C headers & .tbd files total installation size: 6.1 MiB
    • tarball size: 534 KB
  • supported triples:
    • x86_64-macos.11 (Big Sur)
    • aarch64-macos.11 (Big Sur)

After this PR is merged

  • macOS C headers & .tbd files total installation size: 13.1 MiB
    • tarball size: 581 KB
  • supported triples:
    • x86_64-macos.10 (Catalina)
    • x86_64-macos.11 (Big Sur)
    • x86_64-macos.12 (Monterey)
    • aarch64-macos.11 (Big Sur)
    • aarch64-macos.12 (Monterey)

@kubkon kubkon merged commit 2006add into master Nov 26, 2021
@kubkon kubkon deleted the macos-versions branch November 26, 2021 00:08
slimsag added a commit to hexops/mach that referenced this pull request Nov 27, 2021
…eting

The latest Zig master supports specifying a specific macOS version for libc, via
the target triple (ziglang/zig#10215):

* x86_64-macos.10 (Catalina)
* x86_64-macos.11 (Big Sur)
* x86_64-macos.12 (Monterey)
* aarch64-macos.11 (Big Sur)
* aarch64-macos.12 (Monterey)

Mach's `system_sdk.zig` can now download the relevant XCode framework stubs
for Big Sur (11) and Monterey (12). We do not support Catalina (10) currently.
By default, Zig targets the N-3 version (e.g. `x86_64-macos` defaults to `x86_64-macos.10`).

Targeting the older version (`<arch>-macos.11`) is useful for compatability, it
guarantees the produced binary will run on macOS 11+. Targeting the newer version
can be useful if you wish to use newer APIs not available in previous versions.

Fixes #102

Signed-off-by: Stephen Gutekanst <stephen@hexops.com>
slimsag added a commit to hexops/mach that referenced this pull request Nov 27, 2021
…eting

The latest Zig master supports specifying a specific macOS version for libc, via
the target triple (ziglang/zig#10215):

* x86_64-macos.10 (Catalina)
* x86_64-macos.11 (Big Sur)
* x86_64-macos.12 (Monterey)
* aarch64-macos.11 (Big Sur)
* aarch64-macos.12 (Monterey)

Mach's `system_sdk.zig` can now download the relevant XCode framework stubs
for Big Sur (11) and Monterey (12). Although we don't have an SDK for Catalina (10)
currently, we use the Big Sur (11) SDK in that case and it generally works fine.
By default, Zig targets the N-3 version (e.g. `x86_64-macos` defaults to `x86_64-macos.10`).

Targeting the minimum supported version is useful for compatability, it guarantees the produced
binary will run on any later macOS version. Targeting the newer version can be useful if you
wish to use newer APIs not available in previous versions.

Fixes #102

Signed-off-by: Stephen Gutekanst <stephen@hexops.com>
slimsag added a commit to hexops/mach that referenced this pull request Nov 27, 2021
…eting

The latest Zig master supports specifying a specific macOS version for libc, via
the target triple (ziglang/zig#10215):

* x86_64-macos.10 (Catalina)
* x86_64-macos.11 (Big Sur)
* x86_64-macos.12 (Monterey)
* aarch64-macos.11 (Big Sur)
* aarch64-macos.12 (Monterey)

Mach's `system_sdk.zig` can now download the relevant XCode framework stubs
for Big Sur (11) and Monterey (12). Although we don't have an SDK for Catalina (10)
currently, we use the Big Sur (11) SDK in that case and it generally works fine.
By default, Zig targets the N-3 version (e.g. `x86_64-macos` defaults to `x86_64-macos.10`).

Targeting the minimum supported version is useful for compatability, it guarantees the produced
binary will run on any later macOS version. Targeting the newer version can be useful if you
wish to use newer APIs not available in previous versions.

Fixes #102

Signed-off-by: Stephen Gutekanst <stephen@hexops.com>
slimsag added a commit to slimsag/mach-glfw that referenced this pull request Dec 7, 2021
…eting

The latest Zig master supports specifying a specific macOS version for libc, via
the target triple (ziglang/zig#10215):

* x86_64-macos.10 (Catalina)
* x86_64-macos.11 (Big Sur)
* x86_64-macos.12 (Monterey)
* aarch64-macos.11 (Big Sur)
* aarch64-macos.12 (Monterey)

Mach's `system_sdk.zig` can now download the relevant XCode framework stubs
for Big Sur (11) and Monterey (12). Although we don't have an SDK for Catalina (10)
currently, we use the Big Sur (11) SDK in that case and it generally works fine.
By default, Zig targets the N-3 version (e.g. `x86_64-macos` defaults to `x86_64-macos.10`).

Targeting the minimum supported version is useful for compatability, it guarantees the produced
binary will run on any later macOS version. Targeting the newer version can be useful if you
wish to use newer APIs not available in previous versions.

Fixes hexops/mach#102

Signed-off-by: Stephen Gutekanst <stephen@hexops.com>
slimsag added a commit to slimsag/mach-glfw that referenced this pull request Aug 26, 2022
…eting

The latest Zig master supports specifying a specific macOS version for libc, via
the target triple (ziglang/zig#10215):

* x86_64-macos.10 (Catalina)
* x86_64-macos.11 (Big Sur)
* x86_64-macos.12 (Monterey)
* aarch64-macos.11 (Big Sur)
* aarch64-macos.12 (Monterey)

Mach's `system_sdk.zig` can now download the relevant XCode framework stubs
for Big Sur (11) and Monterey (12). Although we don't have an SDK for Catalina (10)
currently, we use the Big Sur (11) SDK in that case and it generally works fine.
By default, Zig targets the N-3 version (e.g. `x86_64-macos` defaults to `x86_64-macos.10`).

Targeting the minimum supported version is useful for compatability, it guarantees the produced
binary will run on any later macOS version. Targeting the newer version can be useful if you
wish to use newer APIs not available in previous versions.

Fixes hexops/mach#102

Signed-off-by: Stephen Gutekanst <stephen@hexops.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

aarch64-macos-gnu, any-macos-any headers need to be updated for macOS 12.0 Monterey
3 participants