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();...@@ -2,6 +2,7 @@ const Compile = @This();
22
3const std = @import("std");3const std = @import("std");
4const Allocator = std.mem.Allocator;4const Allocator = std.mem.Allocator;
5const mem = std.mem;
5const Configuration = std.Build.Configuration;6const Configuration = std.Build.Configuration;
6const Dir = std.Io.Dir;7const Dir = std.Io.Dir;
7const Path = std.Build.Cache.Path;8const Path = std.Build.Cache.Path;
...@@ -9,7 +10,6 @@ const Module = std.Build.Configuration.Module;...@@ -9,7 +10,6 @@ const Module = std.Build.Configuration.Module;
9const Io = std.Io;10const Io = std.Io;
10const Sha256 = std.crypto.hash.sha2.Sha256;11const Sha256 = std.crypto.hash.sha2.Sha256;
11const assert = std.debug.assert;12const assert = std.debug.assert;
12const mem = std.mem;
13const allocPrint = std.fmt.allocPrint;13const allocPrint = std.fmt.allocPrint;
1414
15const Step = @import("../Step.zig");15const Step = @import("../Step.zig");
...@@ -51,7 +51,7 @@ pub fn make(...@@ -51,7 +51,7 @@ pub fn make(
51 (graph.incremental == true) and (maker.watch or maker.web_server != null),51 (graph.incremental == true) and (maker.watch or maker.web_server != null),
52 ) catch |err| switch (err) {52 ) catch |err| switch (err) {
53 error.NeedCompileErrorCheck => {53 error.NeedCompileErrorCheck => {
54 try checkCompileErrors(compile, maker);54 try checkCompileErrors(maker, compile_index);
55 return;55 return;
56 },56 },
57 else => |e| return e,57 else => |e| return e,
...@@ -518,7 +518,7 @@ fn lowerZigArgs(...@@ -518,7 +518,7 @@ fn lowerZigArgs(
518 const import_cli_name = cli_named_modules.names.keys()[import_index];518 const import_cli_name = cli_named_modules.names.keys()[import_index];
519 zig_args.appendAssumeCapacity("--dep");519 zig_args.appendAssumeCapacity("--dep");
520 const name_slice = name.slice(conf);520 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)) {
522 zig_args.appendAssumeCapacity(import_cli_name);522 zig_args.appendAssumeCapacity(import_cli_name);
523 } else {523 } else {
524 zig_args.appendAssumeCapacity(try allocPrint(arena, "{s}={s}", .{524 zig_args.appendAssumeCapacity(try allocPrint(arena, "{s}={s}", .{
...@@ -898,8 +898,8 @@ fn lowerZigArgs(...@@ -898,8 +898,8 @@ fn lowerZigArgs(
898898
899 // Write the args to zig-cache/args/<SHA256 hash of args> to avoid conflicts with899 // Write the args to zig-cache/args/<SHA256 hash of args> to avoid conflicts with
900 // other zig build commands running in parallel.900 // other zig build commands running in parallel.
901 const partially_quoted = try std.mem.join(arena, "\" \"", escaped_args.items);901 const partially_quoted = try mem.join(arena, "\" \"", escaped_args.items);
902 const args = try std.mem.concat(arena, u8, &[_][]const u8{ "\"", partially_quoted, "\"" });902 const args = try mem.concat(arena, u8, &[_][]const u8{ "\"", partially_quoted, "\"" });
903903
904 var args_hash: [Sha256.digest_length]u8 = undefined;904 var args_hash: [Sha256.digest_length]u8 = undefined;
905 Sha256.hash(args, &args_hash, .{});905 Sha256.hash(args, &args_hash, .{});
...@@ -943,24 +943,30 @@ fn lowerZigArgs(...@@ -943,24 +943,30 @@ fn lowerZigArgs(
943 }943 }
944}944}
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 {
947 const gpa = maker.graph.gpa;952 const gpa = maker.graph.gpa;
953 const step = maker.stepByIndex(step_index);
948954
949 compile.step.result_error_msgs.clearRetainingCapacity();955 step.result_error_msgs.clearRetainingCapacity();
950 compile.step.result_stderr = "";956 step.result_stderr = "";
951957
952 compile.step.result_error_bundle.deinit(gpa);958 step.result_error_bundle.deinit(gpa);
953 compile.step.result_error_bundle = std.zig.ErrorBundle.empty;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| {
956 gpa.free(cmd);962 gpa.free(cmd);
957 compile.step.result_failed_command = null;963 step.result_failed_command = null;
958 }964 }
959965
960 const zig_args = &compile.zig_args;966 const zig_args = &compile.zig_args;
961 zig_args.clearRetainingCapacity();967 zig_args.clearRetainingCapacity();
962 try lowerZigArgs(compile, maker, progress_node, zig_args, true);968 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);
964 return maybe_output_bin_path.?;970 return maybe_output_bin_path.?;
965}971}
966972
...@@ -973,35 +979,43 @@ fn addFlag(gpa: Allocator, args: *std.ArrayList([]const u8), comptime name: []co...@@ -973,35 +979,43 @@ fn addFlag(gpa: Allocator, args: *std.ArrayList([]const u8), comptime name: []co
973 try args.append(gpa, if (cond) "-f" ++ name else "-fno-" ++ name);979 try args.append(gpa, if (cond) "-f" ++ name else "-fno-" ++ name);
974}980}
975981
976fn checkCompileErrors(compile: *Compile, maker: *Maker) !void {982fn checkCompileErrors(
977 if (true) @panic("TODO checkCompileErrors");983 maker: *Maker,
978 // Clear this field so that it does not get printed by the build runner.984 step_index: Configuration.Step.Index,
979 const actual_eb = compile.step.result_error_bundle;985) Step.ExtendedMakeError!void {
980 compile.step.result_error_bundle = .empty;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
984 const actual_errors = ae: {997 const actual_errors = ae: {
985 var aw: std.Io.Writer.Allocating = .init(arena);998 var aw: std.Io.Writer.Allocating = .init(arena);
986 defer aw.deinit();999 defer aw.deinit();
987 try actual_eb.renderToWriter(.{1000 actual_eb.renderToWriter(.{
988 .include_reference_trace = false,1001 .include_reference_trace = false,
989 .include_source_line = false,1002 .include_source_line = false,
990 }, &aw.writer);1003 }, &aw.writer) catch |err| switch (err) {
1004 error.WriteFailed => return error.OutOfMemory,
1005 };
991 break :ae try aw.toOwnedSlice();1006 break :ae try aw.toOwnedSlice();
992 };1007 };
9931008
994 // Render the expected lines into a string that we can compare verbatim.1009 // Render the expected lines into a string that we can compare verbatim.
995 var expected_generated: std.ArrayList(u8) = .empty;1010 var expected_generated: std.ArrayList(u8) = .empty;
996 const expect_errors = compile.expect_errors.?;
997
998 var actual_line_it = mem.splitScalar(u8, actual_errors, '\n');1011 var actual_line_it = mem.splitScalar(u8, actual_errors, '\n');
9991012
1000 // TODO merge this with the testing.expectEqualStrings logic, and also CheckFile1013 switch (conf_comp.expect_errors.u) {
1001 switch (expect_errors) {1014 .none => unreachable,
1002 .starts_with => |expect_starts_with| {1015 .starts_with => |expect_starts_with_string| {
1003 if (std.mem.startsWith(u8, actual_errors, expect_starts_with)) return;1016 const expect_starts_with = expect_starts_with_string.slice(conf);
1004 return compile.step.fail(maker,1017 if (mem.startsWith(u8, actual_errors, expect_starts_with)) return;
1018 return step.fail(maker,
1005 \\1019 \\
1006 \\========= should start with: ============1020 \\========= should start with: ============
1007 \\{s}1021 \\{s}
...@@ -1010,13 +1024,14 @@ fn checkCompileErrors(compile: *Compile, maker: *Maker) !void {...@@ -1010,13 +1024,14 @@ fn checkCompileErrors(compile: *Compile, maker: *Maker) !void {
1010 \\=========================================1024 \\=========================================
1011 , .{ expect_starts_with, actual_errors });1025 , .{ expect_starts_with, actual_errors });
1012 },1026 },
1013 .contains => |expect_line| {1027 .contains => |expect_line_string| {
1028 const expect_line = expect_line_string.slice(conf);
1014 while (actual_line_it.next()) |actual_line| {1029 while (actual_line_it.next()) |actual_line| {
1015 if (!matchCompileError(actual_line, expect_line)) continue;1030 if (!matchCompileError(actual_line, expect_line)) continue;
1016 return;1031 return;
1017 }1032 }
10181033
1019 return compile.step.fail(maker,1034 return step.fail(maker,
1020 \\1035 \\
1021 \\========= should contain: ===============1036 \\========= should contain: ===============
1022 \\{s}1037 \\{s}
...@@ -1025,12 +1040,13 @@ fn checkCompileErrors(compile: *Compile, maker: *Maker) !void {...@@ -1025,12 +1040,13 @@ fn checkCompileErrors(compile: *Compile, maker: *Maker) !void {
1025 \\=========================================1040 \\=========================================
1026 , .{ expect_line, actual_errors });1041 , .{ expect_line, actual_errors });
1027 },1042 },
1028 .stderr_contains => |expect_line| {1043 .stderr_contains => |expect_line_string| {
1029 const actual_stderr: []const u8 = if (compile.step.result_error_msgs.items.len > 0)1044 const expect_line = expect_line_string.slice(conf);
1030 compile.step.result_error_msgs.items[0]1045 const actual_stderr: []const u8 = if (step.result_error_msgs.items.len > 0)
1046 step.result_error_msgs.items[0]
1031 else1047 else
1032 &.{};1048 &.{};
1033 compile.step.result_error_msgs.clearRetainingCapacity();1049 step.result_error_msgs.clearRetainingCapacity();
10341050
1035 var stderr_line_it = mem.splitScalar(u8, actual_stderr, '\n');1051 var stderr_line_it = mem.splitScalar(u8, actual_stderr, '\n');
10361052
...@@ -1039,7 +1055,7 @@ fn checkCompileErrors(compile: *Compile, maker: *Maker) !void {...@@ -1039,7 +1055,7 @@ fn checkCompileErrors(compile: *Compile, maker: *Maker) !void {
1039 return;1055 return;
1040 }1056 }
10411057
1042 return compile.step.fail(maker,1058 return step.fail(maker,
1043 \\1059 \\
1044 \\========= should contain: ===============1060 \\========= should contain: ===============
1045 \\{s}1061 \\{s}
...@@ -1049,7 +1065,8 @@ fn checkCompileErrors(compile: *Compile, maker: *Maker) !void {...@@ -1049,7 +1065,8 @@ fn checkCompileErrors(compile: *Compile, maker: *Maker) !void {
1049 , .{ expect_line, actual_stderr });1065 , .{ expect_line, actual_stderr });
1050 },1066 },
1051 .exact => |expect_lines| {1067 .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);
1053 const actual_line = actual_line_it.next() orelse {1070 const actual_line = actual_line_it.next() orelse {
1054 try expected_generated.appendSlice(arena, expect_line);1071 try expected_generated.appendSlice(arena, expect_line);
1055 try expected_generated.append(arena, '\n');1072 try expected_generated.append(arena, '\n');
...@@ -1066,7 +1083,7 @@ fn checkCompileErrors(compile: *Compile, maker: *Maker) !void {...@@ -1066,7 +1083,7 @@ fn checkCompileErrors(compile: *Compile, maker: *Maker) !void {
10661083
1067 if (mem.eql(u8, expected_generated.items, actual_errors)) return;1084 if (mem.eql(u8, expected_generated.items, actual_errors)) return;
10681085
1069 return compile.step.fail(maker,1086 return step.fail(maker,
1070 \\1087 \\
1071 \\========= expected: =====================1088 \\========= expected: =====================
1072 \\{s}1089 \\{s}