| ... | ... | @@ -2,7 +2,7 @@ const std = @import("std"); |
| 2 | 2 | const fatal = std.process.fatal; |
| 3 | 3 | const Allocator = std.mem.Allocator; |
| 4 | 4 | |
| 5 | | const usage = "usage: incr-check <zig binary path> <input file> [-fno-emit-bin] [--zig-lib-dir lib]"; |
| 5 | const usage = "usage: incr-check <zig binary path> <input file> [-fno-emit-bin] [--zig-lib-dir lib] [--debug-zcu]"; |
| 6 | 6 | |
| 7 | 7 | pub fn main() !void { |
| 8 | 8 | var arena_instance = std.heap.ArenaAllocator.init(std.heap.page_allocator); |
| ... | ... | @@ -13,6 +13,7 @@ pub fn main() !void { |
| 13 | 13 | var opt_input_file_name: ?[]const u8 = null; |
| 14 | 14 | var opt_lib_dir: ?[]const u8 = null; |
| 15 | 15 | var no_bin = false; |
| 16 | var debug_zcu = false; |
| 16 | 17 | |
| 17 | 18 | var arg_it = try std.process.argsWithAllocator(arena); |
| 18 | 19 | _ = arg_it.skip(); |
| ... | ... | @@ -20,6 +21,8 @@ pub fn main() !void { |
| 20 | 21 | if (arg.len > 0 and arg[0] == '-') { |
| 21 | 22 | if (std.mem.eql(u8, arg, "-fno-emit-bin")) { |
| 22 | 23 | no_bin = true; |
| 24 | } else if (std.mem.eql(u8, arg, "--debug-zcu")) { |
| 25 | debug_zcu = true; |
| 23 | 26 | } else if (std.mem.eql(u8, arg, "--zig-lib-dir")) { |
| 24 | 27 | opt_lib_dir = arg_it.next() orelse fatal("expected arg after '--zig-lib-dir'\n{s}", .{usage}); |
| 25 | 28 | } else { |
| ... | ... | @@ -48,6 +51,13 @@ pub fn main() !void { |
| 48 | 51 | const tmp_dir_path = "tmp_" ++ std.fmt.hex(rand_int); |
| 49 | 52 | const tmp_dir = try std.fs.cwd().makeOpenPath(tmp_dir_path, .{}); |
| 50 | 53 | |
| 54 | if (opt_lib_dir) |lib_dir| { |
| 55 | if (!std.fs.path.isAbsolute(lib_dir)) { |
| 56 | // The cwd of the subprocess is within the tmp dir, so prepend `..` to the path. |
| 57 | opt_lib_dir = try std.fs.path.join(arena, &.{ "..", lib_dir }); |
| 58 | } |
| 59 | } |
| 60 | |
| 51 | 61 | const child_prog_node = prog_node.start("zig build-exe", 0); |
| 52 | 62 | defer child_prog_node.end(); |
| 53 | 63 | |
| ... | ... | @@ -74,6 +84,9 @@ pub fn main() !void { |
| 74 | 84 | } else { |
| 75 | 85 | try child_args.appendSlice(arena, &.{ "-fno-llvm", "-fno-lld" }); |
| 76 | 86 | } |
| 87 | if (debug_zcu) { |
| 88 | try child_args.appendSlice(arena, &.{ "--debug-log", "zcu" }); |
| 89 | } |
| 77 | 90 | |
| 78 | 91 | var child = std.process.Child.init(child_args.items, arena); |
| 79 | 92 | child.stdin_behavior = .Pipe; |
| ... | ... | @@ -89,6 +102,7 @@ pub fn main() !void { |
| 89 | 102 | .tmp_dir = tmp_dir, |
| 90 | 103 | .tmp_dir_path = tmp_dir_path, |
| 91 | 104 | .child = &child, |
| 105 | .allow_stderr = debug_zcu, |
| 92 | 106 | }; |
| 93 | 107 | |
| 94 | 108 | try child.spawn(); |
| ... | ... | @@ -102,6 +116,11 @@ pub fn main() !void { |
| 102 | 116 | for (case.updates) |update| { |
| 103 | 117 | var update_node = prog_node.start(update.name, 0); |
| 104 | 118 | defer update_node.end(); |
| 119 | |
| 120 | if (debug_zcu) { |
| 121 | std.log.info("=== START UPDATE '{s}' ===", .{update.name}); |
| 122 | } |
| 123 | |
| 105 | 124 | eval.write(update); |
| 106 | 125 | try eval.requestUpdate(); |
| 107 | 126 | try eval.check(&poller, update); |
| ... | ... | @@ -118,6 +137,7 @@ const Eval = struct { |
| 118 | 137 | tmp_dir: std.fs.Dir, |
| 119 | 138 | tmp_dir_path: []const u8, |
| 120 | 139 | child: *std.process.Child, |
| 140 | allow_stderr: bool, |
| 121 | 141 | |
| 122 | 142 | const StreamEnum = enum { stdout, stderr }; |
| 123 | 143 | const Poller = std.io.Poller(StreamEnum); |
| ... | ... | @@ -173,7 +193,11 @@ const Eval = struct { |
| 173 | 193 | }; |
| 174 | 194 | if (stderr.readableLength() > 0) { |
| 175 | 195 | const stderr_data = try stderr.toOwnedSlice(); |
| 176 | | fatal("error_bundle included unexpected stderr:\n{s}", .{stderr_data}); |
| 196 | if (eval.allow_stderr) { |
| 197 | std.log.info("error_bundle included stderr:\n{s}", .{stderr_data}); |
| 198 | } else { |
| 199 | fatal("error_bundle included unexpected stderr:\n{s}", .{stderr_data}); |
| 200 | } |
| 177 | 201 | } |
| 178 | 202 | if (result_error_bundle.errorMessageCount() == 0) { |
| 179 | 203 | // Empty bundle indicates successful update in a `-fno-emit-bin` build. |
| ... | ... | @@ -197,7 +221,11 @@ const Eval = struct { |
| 197 | 221 | const result_binary = try arena.dupe(u8, body[@sizeOf(EbpHdr)..]); |
| 198 | 222 | if (stderr.readableLength() > 0) { |
| 199 | 223 | const stderr_data = try stderr.toOwnedSlice(); |
| 200 | | fatal("emit_bin_path included unexpected stderr:\n{s}", .{stderr_data}); |
| 224 | if (eval.allow_stderr) { |
| 225 | std.log.info("emit_bin_path included stderr:\n{s}", .{stderr_data}); |
| 226 | } else { |
| 227 | fatal("emit_bin_path included unexpected stderr:\n{s}", .{stderr_data}); |
| 228 | } |
| 201 | 229 | } |
| 202 | 230 | try eval.checkSuccessOutcome(update, result_binary); |
| 203 | 231 | // This message indicates the end of the update. |
| ... | ... | @@ -213,7 +241,11 @@ const Eval = struct { |
| 213 | 241 | |
| 214 | 242 | if (stderr.readableLength() > 0) { |
| 215 | 243 | const stderr_data = try stderr.toOwnedSlice(); |
| 216 | | fatal("update '{s}' failed:\n{s}", .{ update.name, stderr_data }); |
| 244 | if (eval.allow_stderr) { |
| 245 | std.log.info("update '{s}' included stderr:\n{s}", .{ update.name, stderr_data }); |
| 246 | } else { |
| 247 | fatal("update '{s}' failed:\n{s}", .{ update.name, stderr_data }); |
| 248 | } |
| 217 | 249 | } |
| 218 | 250 | |
| 219 | 251 | waitChild(eval.child); |