From 0ec0cc0f9592fe9ba716a1567b887ba52e4b75dc Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Tue, 6 Aug 2024 16:04:41 -0700 Subject: [PATCH] build: build proper metallib for iOS builds --- build.zig | 31 ++++++++++--------------------- src/build/MetallibStep.zig | 32 ++++++++++++++++++++++++++++++-- 2 files changed, 40 insertions(+), 23 deletions(-) diff --git a/build.zig b/build.zig index 9cac8d810..afc97f57f 100644 --- a/build.zig +++ b/build.zig @@ -1267,29 +1267,18 @@ fn addDeps( /// Generate Metal shader library fn addMetallib( b: *std.Build, - step_: ?*std.Build.Step.Compile, + step: *std.Build.Step.Compile, ) !void { - // Our static state between runs. We memoize so we only compile - // the Metal shaders once. - const MetalState = struct { - var generated: ?std.Build.LazyPath = null; - }; + const metal_step = MetallibStep.create(b, .{ + .name = "Ghostty", + .target = step.root_module.resolved_target.?, + .sources = &.{b.path("src/renderer/shaders/cell.metal")}, + }); - const output = MetalState.generated orelse metal: { - const step = MetallibStep.create(b, .{ - .name = "Ghostty", - .sources = &.{b.path("src/renderer/shaders/cell.metal")}, - }); - - break :metal step.output; - }; - - if (step_) |step| { - output.addStepDependencies(&step.step); - step.root_module.addAnonymousImport("ghostty_metallib", .{ - .root_source_file = output, - }); - } + metal_step.output.addStepDependencies(&step.step); + step.root_module.addAnonymousImport("ghostty_metallib", .{ + .root_source_file = metal_step.output, + }); } /// Generate help files diff --git a/src/build/MetallibStep.zig b/src/build/MetallibStep.zig index 8d78d0ceb..e576b9c3a 100644 --- a/src/build/MetallibStep.zig +++ b/src/build/MetallibStep.zig @@ -11,6 +11,9 @@ pub const Options = struct { /// The name of the xcframework to create. name: []const u8, + /// The OS being targeted + target: std.Build.ResolvedTarget, + /// The Metal source files. sources: []const LazyPath, }; @@ -21,20 +24,45 @@ output: LazyPath, pub fn create(b: *std.Build, opts: Options) *MetallibStep { const self = b.allocator.create(MetallibStep) catch @panic("OOM"); + const sdk = switch (opts.target.result.os.tag) { + .macos => "macosx", + .ios => "iphoneos", + else => @panic("unsupported metallib OS"), + }; + + const min_version = if (opts.target.query.os_version_min) |v| + b.fmt("{}", .{v.semver}) + else switch (opts.target.result.os.tag) { + .macos => "10.14", + .ios => "11.0", + else => unreachable, + }; + const run_ir = RunStep.create( b, b.fmt("metal {s}", .{opts.name}), ); - run_ir.addArgs(&.{ "xcrun", "-sdk", "macosx", "metal", "-o" }); + run_ir.addArgs(&.{ "xcrun", "-sdk", sdk, "metal", "-o" }); const output_ir = run_ir.addOutputFileArg(b.fmt("{s}.ir", .{opts.name})); run_ir.addArgs(&.{"-c"}); for (opts.sources) |source| run_ir.addFileArg(source); + switch (opts.target.result.os.tag) { + .ios => run_ir.addArgs(&.{b.fmt( + "-mios-version-min={s}", + .{min_version}, + )}), + .macos => run_ir.addArgs(&.{b.fmt( + "-mmacos-version-min={s}", + .{min_version}, + )}), + else => {}, + } const run_lib = RunStep.create( b, b.fmt("metallib {s}", .{opts.name}), ); - run_lib.addArgs(&.{ "xcrun", "-sdk", "macosx", "metallib", "-o" }); + run_lib.addArgs(&.{ "xcrun", "-sdk", sdk, "metallib", "-o" }); const output_lib = run_lib.addOutputFileArg(b.fmt("{s}.metallib", .{opts.name})); run_lib.addFileArg(output_ir); run_lib.step.dependOn(&run_ir.step);