zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit 745b38fde2b7e3e8369874aee3709fe18eb39a11 (tree)
parent 3750469dcac7711374002835f569bcdf1df75f4d
Author: Motiejus Jakštys <motiejus@jakstys.lt>
Date:   Tue, 10 Feb 2026 14:26:56 +0000

`zig build` does more and in parallel

Diffstat:
MREADME.md | 10+++-------
Mbuild.zig | 102+++++++++++++++++++++++++++++++++++++++++++++++++++----------------------------
2 files changed, 69 insertions(+), 43 deletions(-)

diff --git a/README.md b/README.md @@ -1,14 +1,10 @@ -zig0 aspires to be an interpreter of zig 0.14.0 C backend. +zig0 aspires to be an interpreter of zig 0.15.1 written in C. # Testing -Where the following $CC are supported: `zig`, `clang`, `gcc` and `tcc`. Then: +Quick test: - zig build test -Dcc=$CC - -Static analysis: - - zig build fmt lint + zig build # Debugging tips diff --git a/build.zig b/build.zig @@ -36,51 +36,20 @@ const cflags = &[_][]const u8{ //"-D_FORTIFY_SOURCE=2", // consider when optimization flags are enabled }; +const compilers = &[_][]const u8{ "zig", "clang", "gcc", "tcc" }; + pub fn build(b: *std.Build) !void { const target = b.standardTargetOptions(.{}); const optimize = b.standardOptimizeOption(.{}); const cc = b.option([]const u8, "cc", "C compiler") orelse "zig"; + const no_exec = b.option(bool, "no-exec", "Compile test binary without running it") orelse false; const test_step = b.step("test", "Run unit tests"); - const test_mod = b.createModule(.{ - .root_source_file = b.path("test_all.zig"), - .optimize = optimize, - .target = target, - }); - test_mod.addIncludePath(b.path(".")); - - // TODO(zig 0.16+): remove this if block entirely; keep only the addLibrary branch. - // Also delete addCObjectsDirectly. - // Zig 0.15's ELF archive parser fails on archives containing odd-sized objects - // (off-by-one after 2-byte alignment). This is fixed on zig master/0.16. - if (comptime builtin.zig_version.order(.{ .major = 0, .minor = 16, .patch = 0 }) == .lt) { - addCObjectsDirectly(b, test_mod, cc, optimize); - } else { - const lib_mod = b.createModule(.{ - .optimize = optimize, - .target = target, - .link_libc = true, - }); - const lib = b.addLibrary(.{ - .name = "tokenizer", - .root_module = lib_mod, - }); - addCSources(b, lib.root_module, cc, optimize); - test_mod.linkLibrary(lib); - } - - const no_exec = b.option(bool, "no-exec", "Compile test binary without running it") orelse false; - const test_exe = b.addTest(.{ .root_module = test_mod }); - if (no_exec) { - const install = b.addInstallArtifact(test_exe, .{}); - test_step.dependOn(&install.step); - } else { - test_step.dependOn(&b.addRunArtifact(test_exe).step); - } + addTestStep(b, test_step, target, optimize, cc, no_exec); const fmt_step = b.step("fmt", "clang-format"); - const clang_format = b.addSystemCommand(&.{ "clang-format", "-Werror", "-i" }); + const clang_format = b.addSystemCommand(&.{ "clang-format", "-i" }); for (all_c_files ++ headers) |f| clang_format.addFileArg(b.path(f)); fmt_step.dependOn(&clang_format.step); @@ -95,6 +64,7 @@ pub fn build(b: *std.Build) !void { "-Werror", }); for (all_c_files) |cfile| clang_analyze.addFileArg(b.path(cfile)); + clang_analyze.expectExitCode(0); lint_step.dependOn(&clang_analyze.step); const gcc_analyze = b.addSystemCommand(&.{ @@ -105,6 +75,7 @@ pub fn build(b: *std.Build) !void { "/dev/null", }); for (all_c_files) |cfile| gcc_analyze.addFileArg(b.path(cfile)); + gcc_analyze.expectExitCode(0); lint_step.dependOn(&gcc_analyze.step); const cppcheck = b.addSystemCommand(&.{ @@ -120,7 +91,66 @@ pub fn build(b: *std.Build) !void { "--suppress=knownConditionTrueFalse", // TODO remove after plumbing is done }); for (all_c_files) |cfile| cppcheck.addFileArg(b.path(cfile)); + cppcheck.expectExitCode(0); lint_step.dependOn(&cppcheck.step); + + const all_step = b.step("all", "Run fmt check, lint, and tests with all compilers"); + all_step.dependOn(lint_step); + + const fmt_check = b.addSystemCommand(&.{ "clang-format", "--dry-run", "-Werror" }); + for (all_c_files ++ headers) |f| fmt_check.addFileArg(b.path(f)); + fmt_check.expectExitCode(0); + all_step.dependOn(&fmt_check.step); + + for (compilers) |compiler| { + addTestStep(b, all_step, target, optimize, compiler, false); + } + + b.default_step = all_step; +} + +fn addTestStep( + b: *std.Build, + step: *std.Build.Step, + target: std.Build.ResolvedTarget, + optimize: std.builtin.OptimizeMode, + cc: []const u8, + no_exec: bool, +) void { + const test_mod = b.createModule(.{ + .root_source_file = b.path("test_all.zig"), + .optimize = optimize, + .target = target, + }); + test_mod.addIncludePath(b.path(".")); + + // TODO(zig 0.16+): remove this if block entirely; keep only the addLibrary branch. + // Also delete addCObjectsDirectly. + // Zig 0.15's ELF archive parser fails on archives containing odd-sized objects + // (off-by-one after 2-byte alignment). This is fixed on zig master/0.16. + if (comptime builtin.zig_version.order(.{ .major = 0, .minor = 16, .patch = 0 }) == .lt) { + addCObjectsDirectly(b, test_mod, cc, optimize); + } else { + const lib_mod = b.createModule(.{ + .optimize = optimize, + .target = target, + .link_libc = true, + }); + const lib = b.addLibrary(.{ + .name = b.fmt("zig0-{s}", .{cc}), + .root_module = lib_mod, + }); + addCSources(b, lib.root_module, cc, optimize); + test_mod.linkLibrary(lib); + } + + const test_exe = b.addTest(.{ .root_module = test_mod }); + if (no_exec) { + const install = b.addInstallArtifact(test_exe, .{}); + step.dependOn(&install.step); + } else { + step.dependOn(&b.addRunArtifact(test_exe).step); + } } fn addCSources(