Browse Source

build: restore support for Zig 0.6.0

The version check for Zig 0.6.0 was incorrect since commit
971ab7f (Use a zig build script to run ziglings).

Move compatibility support to a separate file, in order to simplify
build.zig.

In case of incompatible version, exit with code 3 instead of 0, in order
to detect the case of failure in a test (to be implemented).

Remove the use of comptime when checking compatibility at the start of
the build function, since it is not necessary.

Closes #210.
Manlio Perillo 2 years ago
parent
commit
45713ec8ab
2 changed files with 75 additions and 48 deletions
  1. 10 48
      build.zig
  2. 65 0
      src/compat.zig

+ 10 - 48
build.zig

@@ -1,15 +1,13 @@
 const std = @import("std");
 const std = @import("std");
 const builtin = @import("builtin");
 const builtin = @import("builtin");
-const Builder = std.build.Builder;
-const Step = std.build.Step;
+const compat = @import("src/compat.zig");
+
+const Build = compat.Build;
+const Step = compat.build.Step;
+
 const assert = std.debug.assert;
 const assert = std.debug.assert;
 const print = std.debug.print;
 const print = std.debug.print;
 
 
-// When changing this version, be sure to also update README.md in two places:
-//     1) Getting Started
-//     2) Version Changes
-const needed_version = std.SemanticVersion.parse("0.11.0-dev.2157") catch unreachable;
-
 const Exercise = struct {
 const Exercise = struct {
     /// main_file must have the format key_name.zig.
     /// main_file must have the format key_name.zig.
     /// The key will be used as a shorthand to build
     /// The key will be used as a shorthand to build
@@ -493,44 +491,8 @@ const exercises = [_]Exercise{
     },
     },
 };
 };
 
 
-/// Check the zig version to make sure it can compile the examples properly.
-/// This will compile with Zig 0.6.0 and later.
-fn checkVersion() bool {
-    if (!@hasDecl(builtin, "zig_version")) {
-        return false;
-    }
-
-    const version = builtin.zig_version;
-    const order = version.order(needed_version);
-    return order != .lt;
-}
-
-pub fn build(b: *Builder) !void {
-    // Use a comptime branch for the version check.
-    // If this fails, code after this block is not compiled.
-    // It is parsed though, so versions of zig from before 0.6.0
-    // cannot do the version check and will just fail to compile.
-    // We could fix this by moving the ziglings code to a separate file,
-    // but 0.5.0 was a long time ago, it is unlikely that anyone who
-    // attempts these exercises is still using it.
-    if (comptime !checkVersion()) {
-        // very old versions of Zig used warn instead of print.
-        const stderrPrintFn = if (@hasDecl(std.debug, "print")) std.debug.print else std.debug.warn;
-        stderrPrintFn(
-            \\ERROR: Sorry, it looks like your version of zig is too old. :-(
-            \\
-            \\Ziglings requires development build
-            \\
-            \\    {}
-            \\
-            \\or higher. Please download a development ("master") build from
-            \\
-            \\    https://ziglang.org/download/
-            \\
-            \\
-        , .{needed_version});
-        std.os.exit(0);
-    }
+pub fn build(b: *Build) !void {
+    if (!compat.is_compatible) compat.die();
 
 
     use_color_escapes = false;
     use_color_escapes = false;
     if (std.io.getStdErr().supportsAnsiEscapeCodes()) {
     if (std.io.getStdErr().supportsAnsiEscapeCodes()) {
@@ -629,10 +591,10 @@ var reset_text: []const u8 = "";
 const ZiglingStep = struct {
 const ZiglingStep = struct {
     step: Step,
     step: Step,
     exercise: Exercise,
     exercise: Exercise,
-    builder: *Builder,
+    builder: *Build,
     use_healed: bool,
     use_healed: bool,
 
 
-    pub fn create(builder: *Builder, exercise: Exercise, use_healed: bool) *@This() {
+    pub fn create(builder: *Build, exercise: Exercise, use_healed: bool) *@This() {
         const self = builder.allocator.create(@This()) catch unreachable;
         const self = builder.allocator.create(@This()) catch unreachable;
         self.* = .{
         self.* = .{
             .step = Step.init(Step.Options{ .id = .custom, .name = exercise.main_file, .owner = builder, .makeFn = make }),
             .step = Step.init(Step.Options{ .id = .custom, .name = exercise.main_file, .owner = builder, .makeFn = make }),
@@ -813,7 +775,7 @@ const PrintStep = struct {
     message: []const u8,
     message: []const u8,
     file: std.fs.File,
     file: std.fs.File,
 
 
-    pub fn create(owner: *std.Build, message: []const u8, file: std.fs.File) *PrintStep {
+    pub fn create(owner: *Build, message: []const u8, file: std.fs.File) *PrintStep {
         const self = owner.allocator.create(PrintStep) catch @panic("OOM");
         const self = owner.allocator.create(PrintStep) catch @panic("OOM");
         self.* = .{
         self.* = .{
             .step = Step.init(.{
             .step = Step.init(.{

+ 65 - 0
src/compat.zig

@@ -0,0 +1,65 @@
+/// Compatibility support for very old versions of Zig and recent versions before
+/// commit efa25e7d5 (Merge pull request #14498 from ziglang/zig-build-api).
+///
+/// Versions of Zig from before 0.6.0 cannot do the version check and will just
+/// fail to compile, but 0.5.0 was a long time ago, it is unlikely that anyone
+/// who attempts these exercises is still using it.
+const std = @import("std");
+const builtin = @import("builtin");
+
+const debug = std.debug;
+
+// Very old versions of Zig used warn instead of print.
+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.2157";
+
+fn isCompatible() bool {
+    if (!@hasDecl(builtin, "zig_version") or !@hasDecl(std, "SemanticVersion")) {
+        return false;
+    }
+
+    const needed_version = std.SemanticVersion.parse(needed_version_str) catch unreachable;
+    const version = builtin.zig_version;
+    const order = version.order(needed_version);
+
+    return order != .lt;
+}
+
+pub fn die() noreturn {
+    const error_message =
+        \\ERROR: Sorry, it looks like your version of zig is too old. :-(
+        \\
+        \\Ziglings requires development build
+        \\
+        \\    {s}
+        \\
+        \\or higher. Please download a development ("master") build from
+        \\
+        \\    https://ziglang.org/download/
+        \\
+        \\
+    ;
+
+    print(error_message, .{needed_version_str});
+
+    // Use exit code 2, to differentiate from a normal Zig compiler error.
+    std.os.exit(2);
+}
+
+// A separate function is required because very old versions of Zig doesn't
+// support labeled block expressions.
+pub const is_compatible: bool = isCompatible();
+
+/// This is the type to be used only for the build function definition, since
+/// the type must be compatible with the build runner.
+///
+/// Don't use std.Build.Builder, since it is deprecated and may be removed in
+/// future.
+pub const Build = if (is_compatible) std.Build else std.build.Builder;
+
+/// This is the type to be used for accessing the build namespace.
+pub const build = if (is_compatible) std.Build else std.build;