Skip to content

Commit 4bd2b62

Browse files
committed
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.
1 parent 24478be commit 4bd2b62

File tree

2 files changed

+75
-48
lines changed

2 files changed

+75
-48
lines changed

build.zig

Lines changed: 10 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
11
const std = @import("std");
22
const builtin = @import("builtin");
3-
const Builder = std.build.Builder;
4-
const Step = std.build.Step;
3+
const compat = @import("src/compat.zig");
4+
5+
const Build = compat.Build;
6+
const Step = compat.build.Step;
7+
58
const assert = std.debug.assert;
69
const print = std.debug.print;
710

8-
// When changing this version, be sure to also update README.md in two places:
9-
// 1) Getting Started
10-
// 2) Version Changes
11-
const needed_version = std.SemanticVersion.parse("0.11.0-dev.2157") catch unreachable;
12-
1311
const Exercise = struct {
1412
/// main_file must have the format key_name.zig.
1513
/// The key will be used as a shorthand to build
@@ -493,44 +491,8 @@ const exercises = [_]Exercise{
493491
},
494492
};
495493

496-
/// Check the zig version to make sure it can compile the examples properly.
497-
/// This will compile with Zig 0.6.0 and later.
498-
fn checkVersion() bool {
499-
if (!@hasDecl(builtin, "zig_version")) {
500-
return false;
501-
}
502-
503-
const version = builtin.zig_version;
504-
const order = version.order(needed_version);
505-
return order != .lt;
506-
}
507-
508-
pub fn build(b: *Builder) !void {
509-
// Use a comptime branch for the version check.
510-
// If this fails, code after this block is not compiled.
511-
// It is parsed though, so versions of zig from before 0.6.0
512-
// cannot do the version check and will just fail to compile.
513-
// We could fix this by moving the ziglings code to a separate file,
514-
// but 0.5.0 was a long time ago, it is unlikely that anyone who
515-
// attempts these exercises is still using it.
516-
if (comptime !checkVersion()) {
517-
// very old versions of Zig used warn instead of print.
518-
const stderrPrintFn = if (@hasDecl(std.debug, "print")) std.debug.print else std.debug.warn;
519-
stderrPrintFn(
520-
\\ERROR: Sorry, it looks like your version of zig is too old. :-(
521-
\\
522-
\\Ziglings requires development build
523-
\\
524-
\\ {}
525-
\\
526-
\\or higher. Please download a development ("master") build from
527-
\\
528-
\\ https://ziglang.org/download/
529-
\\
530-
\\
531-
, .{needed_version});
532-
std.os.exit(0);
533-
}
494+
pub fn build(b: *Build) !void {
495+
if (!compat.is_compatible) compat.die();
534496

535497
use_color_escapes = false;
536498
if (std.io.getStdErr().supportsAnsiEscapeCodes()) {
@@ -629,10 +591,10 @@ var reset_text: []const u8 = "";
629591
const ZiglingStep = struct {
630592
step: Step,
631593
exercise: Exercise,
632-
builder: *Builder,
594+
builder: *Build,
633595
use_healed: bool,
634596

635-
pub fn create(builder: *Builder, exercise: Exercise, use_healed: bool) *@This() {
597+
pub fn create(builder: *Build, exercise: Exercise, use_healed: bool) *@This() {
636598
const self = builder.allocator.create(@This()) catch unreachable;
637599
self.* = .{
638600
.step = Step.init(Step.Options{ .id = .custom, .name = exercise.main_file, .owner = builder, .makeFn = make }),
@@ -813,7 +775,7 @@ const PrintStep = struct {
813775
message: []const u8,
814776
file: std.fs.File,
815777

816-
pub fn create(owner: *std.Build, message: []const u8, file: std.fs.File) *PrintStep {
778+
pub fn create(owner: *Build, message: []const u8, file: std.fs.File) *PrintStep {
817779
const self = owner.allocator.create(PrintStep) catch @panic("OOM");
818780
self.* = .{
819781
.step = Step.init(.{

src/compat.zig

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/// Compatibility support for very old versions of Zig and recent versions before
2+
/// commit efa25e7d5 (Merge pull request #14498 from ziglang/zig-build-api).
3+
///
4+
/// Versions of Zig from before 0.6.0 cannot do the version check and will just
5+
/// fail to compile, but 0.5.0 was a long time ago, it is unlikely that anyone
6+
/// who attempts these exercises is still using it.
7+
const std = @import("std");
8+
const builtin = @import("builtin");
9+
10+
const debug = std.debug;
11+
12+
// Very old versions of Zig used warn instead of print.
13+
const print = if (@hasDecl(debug, "print")) debug.print else debug.warn;
14+
15+
// When changing this version, be sure to also update README.md in two places:
16+
// 1) Getting Started
17+
// 2) Version Changes
18+
const needed_version_str = "0.11.0-dev.2157";
19+
20+
fn isCompatible() bool {
21+
if (!@hasDecl(builtin, "zig_version") or !@hasDecl(std, "SemanticVersion")) {
22+
return false;
23+
}
24+
25+
const needed_version = std.SemanticVersion.parse(needed_version_str) catch unreachable;
26+
const version = builtin.zig_version;
27+
const order = version.order(needed_version);
28+
29+
return order != .lt;
30+
}
31+
32+
pub fn die() noreturn {
33+
const error_message =
34+
\\ERROR: Sorry, it looks like your version of zig is too old. :-(
35+
\\
36+
\\Ziglings requires development build
37+
\\
38+
\\ {s}
39+
\\
40+
\\or higher. Please download a development ("master") build from
41+
\\
42+
\\ https://ziglang.org/download/
43+
\\
44+
\\
45+
;
46+
47+
print(error_message, .{needed_version_str});
48+
49+
// Use exit code 2, to differentiate from a normal Zig compiler error.
50+
std.os.exit(2);
51+
}
52+
53+
// A separate function is required because very old versions of Zig doesn't
54+
// support labeled block expressions.
55+
pub const is_compatible: bool = isCompatible();
56+
57+
/// This is the type to be used only for the build function definition, since
58+
/// the type must be compatible with the build runner.
59+
///
60+
/// Don't use std.Build.Builder, since it is deprecated and may be removed in
61+
/// future.
62+
pub const Build = if (is_compatible) std.Build else std.build.Builder;
63+
64+
/// This is the type to be used for accessing the build namespace.
65+
pub const build = if (is_compatible) std.Build else std.build;

0 commit comments

Comments
 (0)