From 69103a3b821d8b8955eac59489b0dabb6f4735ff Mon Sep 17 00:00:00 2001
From: Manlio Perillo <manlio.perillo@gmail.com>
Date: Sun, 30 Apr 2023 17:47:16 +0200
Subject: [PATCH] build: add the Exercise.addExecutable method

Currently addExecutable is called 3 times, unnecessarily making the code
more complex.

The method takes as argument the path to the exercises directory.

Additionally, use the new std.Build.ExecutableOptions.link_libc field.
The new field was added in ziglang/zig@adc9b77d5f on 2023-04-13.

Update the required Zig compiler version.
Note that I added the **current** zig version to the changelog, since
the reason for the change is known only to the person updating the
version.
---
 README.md      |  6 ++++--
 build.zig      | 36 ++++++++++++++++--------------------
 src/compat.zig |  2 +-
 3 files changed, 21 insertions(+), 23 deletions(-)

diff --git a/README.md b/README.md
index 548303a..dff3f2d 100644
--- a/README.md
+++ b/README.md
@@ -40,7 +40,7 @@ Verify the installation and build number of `zig` like so:
 
 ```
 $ zig version
-0.11.0-dev.2560+xxxxxxxxx
+0.11.0-dev.2704+xxxxxxxxx
 ```
 
 Clone this repository with Git:
@@ -77,7 +77,9 @@ need to also update the other.
 
 ### Version Changes
 
-Version-0.11.0-dev.2560+602029bb2
+Version-0.11.0-dev.2704+83970b6d9
+* *2023-04-30* zig 0.11.0-dev.2704 - use of the new `std.Build.ExecutableOptions.link_libc` field
+* *2023-04-12* zig 0.11.0-dev.2560 - changes in `std.Build` - remove run() and install()
 * *2023-04-07* zig 0.11.0-dev.2401 - fixes of the new build system - see [#212](https://github.com/ratfactor/ziglings/pull/212)
 * *2023-02-21* zig 0.11.0-dev.2157 - changes in `build system` - new: parallel processing of the build steps
 * *2023-02-21* zig 0.11.0-dev.1711 - changes in `for loops` - new: Multi-Object For-Loops + Struct-of-Arrays
diff --git a/build.zig b/build.zig
index efeab39..b9c59d6 100644
--- a/build.zig
+++ b/build.zig
@@ -5,6 +5,7 @@ const ipc = @import("src/ipc.zig");
 const tests = @import("test/tests.zig");
 
 const Build = compat.Build;
+const CompileStep = compat.build.CompileStep;
 const Step = compat.build.Step;
 const Child = std.process.Child;
 
@@ -60,6 +61,18 @@ pub const Exercise = struct {
     pub fn number(self: Exercise) usize {
         return std.fmt.parseInt(usize, self.key(), 10) catch unreachable;
     }
+
+    /// Returns the CompileStep for this exercise.
+    pub fn addExecutable(self: Exercise, b: *Build, work_path: []const u8) *CompileStep {
+        const file_path = join(b.allocator, &.{ work_path, self.main_file }) catch
+            @panic("OOM");
+
+        return b.addExecutable(.{
+            .name = self.baseName(),
+            .root_source_file = .{ .path = file_path },
+            .link_libc = self.link_libc,
+        });
+    }
 };
 
 pub fn build(b: *Build) !void {
@@ -121,14 +134,8 @@ pub fn build(b: *Build) !void {
         }
 
         const ex = exercises[n - 1];
-        const base_name = ex.baseName();
-        const file_path = join(b.allocator, &.{ work_path, ex.main_file }) catch
-            @panic("OOM");
 
-        const build_step = b.addExecutable(.{ .name = base_name, .root_source_file = .{ .path = file_path } });
-        if (ex.link_libc) {
-            build_step.linkLibC();
-        }
+        const build_step = ex.addExecutable(b, work_path);
         b.installArtifact(build_step);
 
         const run_step = b.addRunArtifact(build_step);
@@ -178,14 +185,7 @@ pub fn build(b: *Build) !void {
         b.default_step = test_step;
 
         for (exercises) |ex| {
-            const base_name = ex.baseName();
-            const file_path = join(b.allocator, &.{ healed_path, ex.main_file }) catch
-                @panic("OOM");
-
-            const build_step = b.addExecutable(.{ .name = base_name, .root_source_file = .{ .path = file_path } });
-            if (ex.link_libc) {
-                build_step.linkLibC();
-            }
+            const build_step = ex.addExecutable(b, healed_path);
             b.installArtifact(build_step);
 
             const run_step = b.addRunArtifact(build_step);
@@ -207,11 +207,7 @@ pub fn build(b: *Build) !void {
     // error with old Zig compilers.
     var prev_step = &header_step.step;
     for (exercises) |ex| {
-        const base_name = ex.baseName();
-        const file_path = join(b.allocator, &.{ "exercises", ex.main_file }) catch
-            @panic("OOM");
-
-        const build_step = b.addExecutable(.{ .name = base_name, .root_source_file = .{ .path = file_path } });
+        const build_step = ex.addExecutable(b, "exercises");
         b.installArtifact(build_step);
 
         const verify_stepn = ZiglingStep.create(b, ex, work_path);
diff --git a/src/compat.zig b/src/compat.zig
index cd7f3e5..42ecb6b 100644
--- a/src/compat.zig
+++ b/src/compat.zig
@@ -15,7 +15,7 @@ const print = if (@hasDecl(debug, "print")) debug.print else debug.warn;
 // When changing this version, be sure to also update README.md in two places:
 //     1) Getting Started
 //     2) Version Changes
-const needed_version_str = "0.11.0-dev.2560";
+const needed_version_str = "0.11.0-dev.2704";
 
 fn isCompatible() bool {
     if (!@hasDecl(builtin, "zig_version") or !@hasDecl(std, "SemanticVersion")) {