From 559ec4de3d78457b43c7f7eea0856bb70fff9f4f Mon Sep 17 00:00:00 2001
From: Christofer Nolander <christofer@nolander.me>
Date: Tue, 17 Oct 2023 08:47:39 +0200
Subject: [PATCH] enable parallel release builds

---
 build.zig  | 101 ++++++++++++++++++++++++++++++++++++++---------------
 justfile   |   2 +-
 release.sh |  21 +++++------
 3 files changed, 81 insertions(+), 43 deletions(-)

diff --git a/build.zig b/build.zig
index ec1be27..f9045b0 100644
--- a/build.zig
+++ b/build.zig
@@ -4,40 +4,83 @@ pub fn build(b: *std.Build) !void {
     const target = b.standardTargetOptions(.{});
     const optimize = b.standardOptimizeOption(.{});
 
+    // Executable
+    {
+        const exe = try addExecutable(b, .{ .target = target, .optimize = optimize });
+        b.installArtifact(exe);
+
+        const run_cmd = b.addRunArtifact(exe);
+        run_cmd.step.dependOn(b.getInstallStep());
+
+        if (b.args) |args| {
+            run_cmd.addArgs(args);
+        }
+
+        const run_step = b.step("run", "Run the app");
+        run_step.dependOn(&run_cmd.step);
+    }
+
+    // Tests
+    {
+        const unit_tests = b.addTest(.{
+            .name = "unit-tests",
+            .root_source_file = .{ .path = "src/main.zig" },
+            .target = target,
+            .optimize = optimize,
+        });
+        try attachModules(unit_tests);
+
+        if (b.option(bool, "install-tests", "Install the unit tests in the `bin` folder") orelse false) {
+            b.installArtifact(unit_tests);
+        }
+
+        const run_unit_tests = b.addRunArtifact(unit_tests);
+        const test_step = b.step("test", "Run unit tests");
+        test_step.dependOn(&run_unit_tests.step);
+    }
+
+    // Release
+    {
+        const target_triples = [_][]const u8{
+            "x86_64-linux-musl",
+            "aarch64-linux-musl",
+            "x86_64-macos",
+            "aarch64-macos",
+            "x86_64-windows",
+            "aarch64-windows",
+        };
+        const release_step = b.step("release", "Produce executables for targeted platforms");
+
+        for (&target_triples) |triple| {
+            const release_target = try std.zig.CrossTarget.parse(.{
+                .arch_os_abi = triple,
+                .cpu_features = "baseline",
+            });
+
+            const exe = try addExecutable(b, .{ .target = release_target, .optimize = optimize });
+            const install = b.addInstallArtifact(exe, .{
+                .dest_dir = .{ .override = .{
+                    .custom = b.pathJoin(&.{ triple, "bin" }),
+                } },
+            });
+
+            release_step.dependOn(&install.step);
+        }
+    }
+}
+
+fn addExecutable(b: *std.Build, options: struct {
+    target: std.zig.CrossTarget,
+    optimize: std.builtin.OptimizeMode,
+}) !*std.Build.CompileStep {
     const exe = b.addExecutable(.{
         .name = "glsl_analyzer",
         .root_source_file = .{ .path = "src/main.zig" },
-        .target = target,
-        .optimize = optimize,
+        .target = options.target,
+        .optimize = options.optimize,
     });
     try attachModules(exe);
-    b.installArtifact(exe);
-
-    const run_cmd = b.addRunArtifact(exe);
-    run_cmd.step.dependOn(b.getInstallStep());
-
-    if (b.args) |args| {
-        run_cmd.addArgs(args);
-    }
-
-    const run_step = b.step("run", "Run the app");
-    run_step.dependOn(&run_cmd.step);
-
-    const unit_tests = b.addTest(.{
-        .name = "unit-tests",
-        .root_source_file = .{ .path = "src/main.zig" },
-        .target = target,
-        .optimize = optimize,
-    });
-    try attachModules(unit_tests);
-
-    if (b.option(bool, "install-tests", "Install the unit tests in the `bin` folder") orelse false) {
-        b.installArtifact(unit_tests);
-    }
-
-    const run_unit_tests = b.addRunArtifact(unit_tests);
-    const test_step = b.step("test", "Run unit tests");
-    test_step.dependOn(&run_unit_tests.step);
+    return exe;
 }
 
 fn attachModules(step: *std.Build.CompileStep) !void {
diff --git a/justfile b/justfile
index 412f816..0743ca0 100644
--- a/justfile
+++ b/justfile
@@ -41,4 +41,4 @@ generate-spec:
     cd spec && just
 
 release:
-    ./release.sh
+    zig build release {{flags}}
diff --git a/release.sh b/release.sh
index e017a87..24c4e5f 100755
--- a/release.sh
+++ b/release.sh
@@ -2,20 +2,15 @@
 
 set -e
 
-targets=(
-    x86_64-linux-musl
-    aarch64-linux-musl
-    x86_64-macos
-    aarch64-macos
-    x86_64-windows
-    aarch64-windows
-)
+rm -rf "zig-out/release"
+rm -rf "zig-out/archives"
+
+zig build release -Doptimize=ReleaseSafe --prefix "zig-out/release" --verbose
 
 mkdir -p "zig-out/archives"
 
-for target in ${targets[@]}; do
-    echo "building $target..."
-    mkdir -p "zig-out/$target"
-    zig build -Dtarget=$target -Doptimize=ReleaseSafe --prefix "zig-out/$target"
-    (cd "zig-out/$target/" && zip -r "../archives/$target.zip" *)
+for target_path in zig-out/release/*; do
+    target=$(basename "$target_path")
+    echo "archiving $target..."
+    (cd "zig-out/release/$target/" && zip -r "../../archives/$target.zip" *)
 done