From a388a8e5a7193831a349f6d00e04bd15211a931f Mon Sep 17 00:00:00 2001 From: mlugg Date: Tue, 26 Aug 2025 16:28:42 +0100 Subject: std.Build: separate errors from failed commands Recording the command in a separate field will give the build runner more freedom to choose how and when the command should be printed. --- lib/std/Build.zig | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) (limited to 'lib/std/Build.zig') diff --git a/lib/std/Build.zig b/lib/std/Build.zig index 5a5bce5127..c13b137ff6 100644 --- a/lib/std/Build.zig +++ b/lib/std/Build.zig @@ -1594,20 +1594,6 @@ pub fn validateUserInputDidItFail(b: *Build) bool { return b.invalid_user_input; } -fn allocPrintCmd(gpa: Allocator, opt_cwd: ?[]const u8, argv: []const []const u8) error{OutOfMemory}![]u8 { - var buf: ArrayList(u8) = .empty; - if (opt_cwd) |cwd| try buf.print(gpa, "cd {s} && ", .{cwd}); - for (argv) |arg| { - try buf.print(gpa, "{s} ", .{arg}); - } - return buf.toOwnedSlice(gpa); -} - -fn printCmd(ally: Allocator, cwd: ?[]const u8, argv: []const []const u8) void { - const text = allocPrintCmd(ally, cwd, argv) catch @panic("OOM"); - std.debug.print("{s}\n", .{text}); -} - /// This creates the install step and adds it to the dependencies of the /// top-level install step, using all the default options. /// See `addInstallArtifact` for a more flexible function. @@ -1857,14 +1843,14 @@ pub fn runAllowFail( pub fn run(b: *Build, argv: []const []const u8) []u8 { if (!process.can_spawn) { std.debug.print("unable to spawn the following command: cannot spawn child process\n{s}\n", .{ - try allocPrintCmd(b.allocator, null, argv), + try Step.allocPrintCmd(b.allocator, null, argv), }); process.exit(1); } var code: u8 = undefined; return b.runAllowFail(argv, &code, .Inherit) catch |err| { - const printed_cmd = allocPrintCmd(b.allocator, null, argv) catch @panic("OOM"); + const printed_cmd = Step.allocPrintCmd(b.allocator, null, argv) catch @panic("OOM"); std.debug.print("unable to spawn the following command: {s}\n{s}\n", .{ @errorName(err), printed_cmd, }); -- cgit v1.2.3 From d0b92a80224e1ed44434ed8546fa2ff497cc5312 Mon Sep 17 00:00:00 2001 From: mlugg Date: Sat, 13 Sep 2025 16:16:11 +0100 Subject: std.Build: do not expect server protocol for tests using immature backends For instance, when running a Zig test using the self-hosted aarch64 backend, this logic was previously expecting `std.zig.Server` to be used, but the default test runner intentionally does not do this because the backend is too immature to handle it. On 'master', this is causing sporadic failures; on this branch, they became consistent failures. --- lib/compiler/test_runner.zig | 8 +++++--- lib/std/Build.zig | 33 +++++++++++++++++++++++++++++++-- 2 files changed, 36 insertions(+), 5 deletions(-) (limited to 'lib/std/Build.zig') diff --git a/lib/compiler/test_runner.zig b/lib/compiler/test_runner.zig index adb3e9e90a..673ea2cb2d 100644 --- a/lib/compiler/test_runner.zig +++ b/lib/compiler/test_runner.zig @@ -17,7 +17,9 @@ var fba_buffer: [8192]u8 = undefined; var stdin_buffer: [4096]u8 = undefined; var stdout_buffer: [4096]u8 = undefined; -const crippled = switch (builtin.zig_backend) { +/// Keep in sync with logic in `std.Build.addRunArtifact` which decides whether +/// the test runner will communicate with the build runner via `std.zig.Server`. +const need_simple = switch (builtin.zig_backend) { .stage2_aarch64, .stage2_powerpc, .stage2_riscv64, @@ -33,7 +35,7 @@ pub fn main() void { return; } - if (crippled) { + if (need_simple) { return mainSimple() catch @panic("test failure\n"); } @@ -380,7 +382,7 @@ pub fn fuzz( // Some compiler backends are not capable of handling fuzz testing yet but // we still want CI test coverage enabled. - if (crippled) return; + if (need_simple) return; // Smoke test to ensure the test did not use conditional compilation to // contradict itself by making it not actually be a fuzz test when the test diff --git a/lib/std/Build.zig b/lib/std/Build.zig index c13b137ff6..9fd906e333 100644 --- a/lib/std/Build.zig +++ b/lib/std/Build.zig @@ -956,8 +956,37 @@ pub fn addRunArtifact(b: *Build, exe: *Step.Compile) *Step.Run { run_step.addArtifactArg(exe); } - const test_server_mode = if (exe.test_runner) |r| r.mode == .server else true; - if (test_server_mode) run_step.enableTestRunnerMode(); + const test_server_mode: bool = s: { + if (exe.test_runner) |r| break :s r.mode == .server; + if (exe.use_llvm == false) { + // The default test runner does not use the server protocol if the selected backend + // is too immature to support it. Keep this logic in sync with `need_simple` in the + // default test runner implementation. + switch (exe.rootModuleTarget().cpu.arch) { + // stage2_aarch64 + .aarch64, + .aarch64_be, + // stage2_powerpc + .powerpc, + .powerpcle, + .powerpc64, + .powerpc64le, + // stage2_riscv64 + .riscv64, + => break :s false, + + else => {}, + } + } + break :s true; + }; + if (test_server_mode) { + run_step.enableTestRunnerMode(); + } else if (exe.test_runner == null) { + // If a test runner does not use the `std.zig.Server` protocol, it can instead + // communicate failure via its exit code. + run_step.expectExitCode(0); + } } else { run_step.addArtifactArg(exe); } -- cgit v1.2.3