authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-05-19 17:17:10-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-05-25 18:54:36-07:00
log3a259e2f0f56220ffa3019b009429e9adc4bc6d0
tree6035a7234e106eb867a23db3db524d931e224f56
parentec65f129d8cfdba6c15f0ea5cda5acea5c8d3ada

Maker.Step.Compile: implement checkCompileErrors


1 files changed, 54 insertions(+), 37 deletions(-)

lib/compiler/Maker/Step/Compile.zig+54-37
......@@ -2,6 +2,7 @@ const Compile = @This();
22
33const std = @import("std");
44const Allocator = std.mem.Allocator;
5const mem = std.mem;
56const Configuration = std.Build.Configuration;
67const Dir = std.Io.Dir;
78const Path = std.Build.Cache.Path;
......@@ -9,7 +10,6 @@ const Module = std.Build.Configuration.Module;
910const Io = std.Io;
1011const Sha256 = std.crypto.hash.sha2.Sha256;
1112const assert = std.debug.assert;
12const mem = std.mem;
1313const allocPrint = std.fmt.allocPrint;
1414
1515const Step = @import("../Step.zig");
......@@ -51,7 +51,7 @@ pub fn make(
5151 (graph.incremental == true) and (maker.watch or maker.web_server != null),
5252 ) catch |err| switch (err) {
5353 error.NeedCompileErrorCheck => {
54 try checkCompileErrors(compile, maker);
54 try checkCompileErrors(maker, compile_index);
5555 return;
5656 },
5757 else => |e| return e,
......@@ -518,7 +518,7 @@ fn lowerZigArgs(
518518 const import_cli_name = cli_named_modules.names.keys()[import_index];
519519 zig_args.appendAssumeCapacity("--dep");
520520 const name_slice = name.slice(conf);
521 if (std.mem.eql(u8, import_cli_name, name_slice)) {
521 if (mem.eql(u8, import_cli_name, name_slice)) {
522522 zig_args.appendAssumeCapacity(import_cli_name);
523523 } else {
524524 zig_args.appendAssumeCapacity(try allocPrint(arena, "{s}={s}", .{
......@@ -898,8 +898,8 @@ fn lowerZigArgs(
898898
899899 // Write the args to zig-cache/args/<SHA256 hash of args> to avoid conflicts with
900900 // other zig build commands running in parallel.
901 const partially_quoted = try std.mem.join(arena, "\" \"", escaped_args.items);
902 const args = try std.mem.concat(arena, u8, &[_][]const u8{ "\"", partially_quoted, "\"" });
901 const partially_quoted = try mem.join(arena, "\" \"", escaped_args.items);
902 const args = try mem.concat(arena, u8, &[_][]const u8{ "\"", partially_quoted, "\"" });
903903
904904 var args_hash: [Sha256.digest_length]u8 = undefined;
905905 Sha256.hash(args, &args_hash, .{});
......@@ -943,24 +943,30 @@ fn lowerZigArgs(
943943 }
944944}
945945
946pub fn rebuildInFuzzMode(compile: *Compile, maker: *Maker, progress_node: std.Progress.Node) !Path {
946pub fn rebuildInFuzzMode(
947 compile: *Compile,
948 maker: *Maker,
949 step_index: Configuration.Step.Index,
950 progress_node: std.Progress.Node,
951) !Path {
947952 const gpa = maker.graph.gpa;
953 const step = maker.stepByIndex(step_index);
948954
949 compile.step.result_error_msgs.clearRetainingCapacity();
950 compile.step.result_stderr = "";
955 step.result_error_msgs.clearRetainingCapacity();
956 step.result_stderr = "";
951957
952 compile.step.result_error_bundle.deinit(gpa);
953 compile.step.result_error_bundle = std.zig.ErrorBundle.empty;
958 step.result_error_bundle.deinit(gpa);
959 step.result_error_bundle = std.zig.ErrorBundle.empty;
954960
955 if (compile.step.result_failed_command) |cmd| {
961 if (step.result_failed_command) |cmd| {
956962 gpa.free(cmd);
957 compile.step.result_failed_command = null;
963 step.result_failed_command = null;
958964 }
959965
960966 const zig_args = &compile.zig_args;
961967 zig_args.clearRetainingCapacity();
962968 try lowerZigArgs(compile, maker, progress_node, zig_args, true);
963 const maybe_output_bin_path = try compile.step.evalZigProcess(zig_args.items, progress_node, false, maker);
969 const maybe_output_bin_path = try step.evalZigProcess(zig_args.items, progress_node, false, maker);
964970 return maybe_output_bin_path.?;
965971}
966972
......@@ -973,35 +979,43 @@ fn addFlag(gpa: Allocator, args: *std.ArrayList([]const u8), comptime name: []co
973979 try args.append(gpa, if (cond) "-f" ++ name else "-fno-" ++ name);
974980}
975981
976fn checkCompileErrors(compile: *Compile, maker: *Maker) !void {
977 if (true) @panic("TODO checkCompileErrors");
978 // Clear this field so that it does not get printed by the build runner.
979 const actual_eb = compile.step.result_error_bundle;
980 compile.step.result_error_bundle = .empty;
982fn checkCompileErrors(
983 maker: *Maker,
984 step_index: Configuration.Step.Index,
985) Step.ExtendedMakeError!void {
986 const step = maker.stepByIndex(step_index);
987 const graph = maker.graph;
988 const arena = graph.arena; // TODO don't leak into the process arena
989 const conf = &maker.scanned_config.configuration;
990 const conf_step = step_index.ptr(conf);
991 const conf_comp = conf_step.extended.get(conf.extra).compile;
981992
982 const arena = compile.step.owner.allocator;
993 // Clear this field so that it does not get printed by the build runner.
994 const actual_eb = step.result_error_bundle;
995 step.result_error_bundle = .empty;
983996
984997 const actual_errors = ae: {
985998 var aw: std.Io.Writer.Allocating = .init(arena);
986999 defer aw.deinit();
987 try actual_eb.renderToWriter(.{
1000 actual_eb.renderToWriter(.{
9881001 .include_reference_trace = false,
9891002 .include_source_line = false,
990 }, &aw.writer);
1003 }, &aw.writer) catch |err| switch (err) {
1004 error.WriteFailed => return error.OutOfMemory,
1005 };
9911006 break :ae try aw.toOwnedSlice();
9921007 };
9931008
9941009 // Render the expected lines into a string that we can compare verbatim.
9951010 var expected_generated: std.ArrayList(u8) = .empty;
996 const expect_errors = compile.expect_errors.?;
997
9981011 var actual_line_it = mem.splitScalar(u8, actual_errors, '\n');
9991012
1000 // TODO merge this with the testing.expectEqualStrings logic, and also CheckFile
1001 switch (expect_errors) {
1002 .starts_with => |expect_starts_with| {
1003 if (std.mem.startsWith(u8, actual_errors, expect_starts_with)) return;
1004 return compile.step.fail(maker,
1013 switch (conf_comp.expect_errors.u) {
1014 .none => unreachable,
1015 .starts_with => |expect_starts_with_string| {
1016 const expect_starts_with = expect_starts_with_string.slice(conf);
1017 if (mem.startsWith(u8, actual_errors, expect_starts_with)) return;
1018 return step.fail(maker,
10051019 \\
10061020 \\========= should start with: ============
10071021 \\{s}
......@@ -1010,13 +1024,14 @@ fn checkCompileErrors(compile: *Compile, maker: *Maker) !void {
10101024 \\=========================================
10111025 , .{ expect_starts_with, actual_errors });
10121026 },
1013 .contains => |expect_line| {
1027 .contains => |expect_line_string| {
1028 const expect_line = expect_line_string.slice(conf);
10141029 while (actual_line_it.next()) |actual_line| {
10151030 if (!matchCompileError(actual_line, expect_line)) continue;
10161031 return;
10171032 }
10181033
1019 return compile.step.fail(maker,
1034 return step.fail(maker,
10201035 \\
10211036 \\========= should contain: ===============
10221037 \\{s}
......@@ -1025,12 +1040,13 @@ fn checkCompileErrors(compile: *Compile, maker: *Maker) !void {
10251040 \\=========================================
10261041 , .{ expect_line, actual_errors });
10271042 },
1028 .stderr_contains => |expect_line| {
1029 const actual_stderr: []const u8 = if (compile.step.result_error_msgs.items.len > 0)
1030 compile.step.result_error_msgs.items[0]
1043 .stderr_contains => |expect_line_string| {
1044 const expect_line = expect_line_string.slice(conf);
1045 const actual_stderr: []const u8 = if (step.result_error_msgs.items.len > 0)
1046 step.result_error_msgs.items[0]
10311047 else
10321048 &.{};
1033 compile.step.result_error_msgs.clearRetainingCapacity();
1049 step.result_error_msgs.clearRetainingCapacity();
10341050
10351051 var stderr_line_it = mem.splitScalar(u8, actual_stderr, '\n');
10361052
......@@ -1039,7 +1055,7 @@ fn checkCompileErrors(compile: *Compile, maker: *Maker) !void {
10391055 return;
10401056 }
10411057
1042 return compile.step.fail(maker,
1058 return step.fail(maker,
10431059 \\
10441060 \\========= should contain: ===============
10451061 \\{s}
......@@ -1049,7 +1065,8 @@ fn checkCompileErrors(compile: *Compile, maker: *Maker) !void {
10491065 , .{ expect_line, actual_stderr });
10501066 },
10511067 .exact => |expect_lines| {
1052 for (expect_lines) |expect_line| {
1068 for (expect_lines.slice) |expect_line_string| {
1069 const expect_line = expect_line_string.slice(conf);
10531070 const actual_line = actual_line_it.next() orelse {
10541071 try expected_generated.appendSlice(arena, expect_line);
10551072 try expected_generated.append(arena, '\n');
......@@ -1066,7 +1083,7 @@ fn checkCompileErrors(compile: *Compile, maker: *Maker) !void {
10661083
10671084 if (mem.eql(u8, expected_generated.items, actual_errors)) return;
10681085
1069 return compile.step.fail(maker,
1086 return step.fail(maker,
10701087 \\
10711088 \\========= expected: =====================
10721089 \\{s}