build: use apple sdk from xcode
This commit is contained in:
parent
fe5ac41953
commit
95b4ddcdb1
4 changed files with 69 additions and 23 deletions
5
.github/workflows/test.yml
vendored
5
.github/workflows/test.yml
vendored
|
@ -2,10 +2,7 @@ on: [push, pull_request]
|
|||
name: Test
|
||||
jobs:
|
||||
build:
|
||||
runs-on: macos-12
|
||||
env:
|
||||
# Needed for macos SDK
|
||||
AGREE: "true"
|
||||
runs-on: namespace-profile-ghostty-macos
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
|
17
README.md
17
README.md
|
@ -73,23 +73,22 @@ const NSOperatingSystemVersion = extern struct {
|
|||
|
||||
## Usage
|
||||
|
||||
**Warning:** This project follows the nightly releases of Zig and may
|
||||
not work with released versions of Zig until Zig stabilizes. I also
|
||||
am **not promising API stability** right now.
|
||||
|
||||
Use your favorite Zig package manager or vendor this repository, then add the package.
|
||||
For example in your build.zig:
|
||||
Add this repository to your `build.zig.zon` file. Then:
|
||||
|
||||
```zig
|
||||
const objc = @import("vendor/zig-objc/build.zig");
|
||||
|
||||
pub fn build(b: *std.build.Builder) !void {
|
||||
// ... other stuff
|
||||
|
||||
exe.addPackage(objc.pkg);
|
||||
exe.root_module.addImport("obcj", b.dependency("zig_objc", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
}).module("objc"));
|
||||
}
|
||||
```
|
||||
|
||||
**`zig-objc` only works with released versions of Zig.** We don't support
|
||||
nightly versions because the Zig compiler is still changing too much.
|
||||
|
||||
## Documentation
|
||||
|
||||
Read the source code, it is well commented. If something isn't clear, please
|
||||
|
|
63
build.zig
63
build.zig
|
@ -1,16 +1,20 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn build(b: *std.Build) void {
|
||||
pub fn build(b: *std.Build) !void {
|
||||
const optimize = b.standardOptimizeOption(.{});
|
||||
const target = b.standardTargetOptions(.{});
|
||||
const add_paths = b.option(bool, "add-paths", "add macos SDK paths from dependency") orelse false;
|
||||
const add_paths = b.option(
|
||||
bool,
|
||||
"add-paths",
|
||||
"add apple SDK paths from Xcode installation",
|
||||
) orelse true;
|
||||
|
||||
const objc = b.addModule("objc", .{
|
||||
.root_source_file = b.path("src/main.zig"),
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
});
|
||||
if (add_paths) @import("macos_sdk").addPathsModule(objc);
|
||||
if (add_paths) try addAppleSDK(b, objc);
|
||||
objc.linkSystemLibrary("objc", .{});
|
||||
objc.linkFramework("Foundation", .{});
|
||||
|
||||
|
@ -22,10 +26,61 @@ pub fn build(b: *std.Build) void {
|
|||
});
|
||||
tests.linkSystemLibrary("objc");
|
||||
tests.linkFramework("Foundation");
|
||||
@import("macos_sdk").addPaths(tests);
|
||||
try addAppleSDK(b, &tests.root_module);
|
||||
b.installArtifact(tests);
|
||||
|
||||
const test_step = b.step("test", "Run tests");
|
||||
const tests_run = b.addRunArtifact(tests);
|
||||
test_step.dependOn(&tests_run.step);
|
||||
}
|
||||
|
||||
/// Add the SDK framework, include, and library paths to the given module.
|
||||
/// The module target is used to determine the SDK to use so it must have
|
||||
/// a resolved target.
|
||||
///
|
||||
/// The Apple SDK is determined based on the build target and found using
|
||||
/// xcrun, so it requires a valid Xcode installation.
|
||||
pub fn addAppleSDK(b: *std.Build, m: *std.Build.Module) !void {
|
||||
// The cache. This always uses b.allocator and never frees memory
|
||||
// (which is idiomatic for a Zig build exe).
|
||||
const Cache = struct {
|
||||
const Key = struct {
|
||||
arch: std.Target.Cpu.Arch,
|
||||
os: std.Target.Os.Tag,
|
||||
abi: std.Target.Abi,
|
||||
};
|
||||
|
||||
var map: std.AutoHashMapUnmanaged(Key, ?[]const u8) = .{};
|
||||
};
|
||||
|
||||
const target = m.resolved_target.?.result;
|
||||
const gop = try Cache.map.getOrPut(b.allocator, .{
|
||||
.arch = target.cpu.arch,
|
||||
.os = target.os.tag,
|
||||
.abi = target.abi,
|
||||
});
|
||||
|
||||
// This executes `xcrun` to get the SDK path. We don't want to execute
|
||||
// this multiple times so we cache the value.
|
||||
if (!gop.found_existing) {
|
||||
gop.value_ptr.* = std.zig.system.darwin.getSdk(
|
||||
b.allocator,
|
||||
m.resolved_target.?.result,
|
||||
);
|
||||
}
|
||||
|
||||
// The active SDK we want to use
|
||||
const path = gop.value_ptr.* orelse return switch (target.os.tag) {
|
||||
// Return a more descriptive error. Before we just returned the
|
||||
// generic error but this was confusing a lot of community members.
|
||||
// It costs us nothing in the build script to return something better.
|
||||
.macos => error.XcodeMacOSSDKNotFound,
|
||||
.ios => error.XcodeiOSSDKNotFound,
|
||||
.tvos => error.XcodeTVOSSDKNotFound,
|
||||
.watchos => error.XcodeWatchOSSDKNotFound,
|
||||
else => error.XcodeAppleSDKNotFound,
|
||||
};
|
||||
m.addSystemFrameworkPath(.{ .cwd_relative = b.pathJoin(&.{ path, "/System/Library/Frameworks" }) });
|
||||
m.addSystemIncludePath(.{ .cwd_relative = b.pathJoin(&.{ path, "/usr/include" }) });
|
||||
m.addLibraryPath(.{ .cwd_relative = b.pathJoin(&.{ path, "/usr/lib" }) });
|
||||
}
|
||||
|
|
|
@ -8,10 +8,5 @@
|
|||
"README.md",
|
||||
"LICENSE",
|
||||
},
|
||||
.dependencies = .{
|
||||
.macos_sdk = .{
|
||||
.url = "https://github.com/mitchellh/zig-build-macos-sdk/archive/a4ea24f105902111633c6ae9f888b676ac5e36df.tar.gz",
|
||||
.hash = "12209cc9ee372456eda52b71cf9ae77dcc707fa42c9f9d68996b5bf7495b53229c2e",
|
||||
},
|
||||
},
|
||||
.dependencies = .{},
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue