| ... | @@ -50,6 +50,7 @@ memory_blocked_steps: std.ArrayList(Configuration.Step.Index), | ... | @@ -50,6 +50,7 @@ memory_blocked_steps: std.ArrayList(Configuration.Step.Index), |
| 50 | /// Allocated into `gpa`. | 50 | /// Allocated into `gpa`. |
| 51 | step_stack: std.AutoArrayHashMapUnmanaged(Configuration.Step.Index, void), | 51 | step_stack: std.AutoArrayHashMapUnmanaged(Configuration.Step.Index, void), |
| 52 | pkg_config: PkgConfig, | 52 | pkg_config: PkgConfig, |
| | 53 | debug_maker_leaks: bool, |
| 53 | | 54 | |
| 54 | error_style: ErrorStyle, | 55 | error_style: ErrorStyle, |
| 55 | multiline_errors: MultilineErrors, | 56 | multiline_errors: MultilineErrors, |
| ... | @@ -73,6 +74,7 @@ pub fn main(init: process.Init.Minimal) !void { | ... | @@ -73,6 +74,7 @@ pub fn main(init: process.Init.Minimal) !void { |
| 73 | var arena_instance: std.heap.ArenaAllocator = .init(std.heap.page_allocator); | 74 | var arena_instance: std.heap.ArenaAllocator = .init(std.heap.page_allocator); |
| 74 | defer arena_instance.deinit(); | 75 | defer arena_instance.deinit(); |
| 75 | const arena = arena_instance.allocator(); | 76 | const arena = arena_instance.allocator(); |
| | 77 | defer log.info("used {Bi} of arena", .{arena_instance.queryCapacity()}); |
| 76 | | 78 | |
| 77 | const args = try init.args.toSlice(arena); | 79 | const args = try init.args.toSlice(arena); |
| 78 | | 80 | |
| ... | @@ -150,7 +152,8 @@ pub fn main(init: process.Init.Minimal) !void { | ... | @@ -150,7 +152,8 @@ pub fn main(init: process.Init.Minimal) !void { |
| 150 | var fuzz: ?Fuzz.Mode = null; | 152 | var fuzz: ?Fuzz.Mode = null; |
| 151 | var debounce_interval_ms: u16 = 50; | 153 | var debounce_interval_ms: u16 = 50; |
| 152 | var webui_listen: ?Io.net.IpAddress = null; | 154 | var webui_listen: ?Io.net.IpAddress = null; |
| 153 | var debug_pkg_config: bool = false; | 155 | var debug_pkg_config = false; |
| | 156 | var debug_maker_leaks = false; |
| 154 | var run_args: ?[]const []const u8 = null; | 157 | var run_args: ?[]const []const u8 = null; |
| 155 | | 158 | |
| 156 | if (std.zig.EnvVar.ZIG_BUILD_ERROR_STYLE.get(&graph.environ_map)) |str| { | 159 | if (std.zig.EnvVar.ZIG_BUILD_ERROR_STYLE.get(&graph.environ_map)) |str| { |
| ... | @@ -297,6 +300,8 @@ pub fn main(init: process.Init.Minimal) !void { | ... | @@ -297,6 +300,8 @@ pub fn main(init: process.Init.Minimal) !void { |
| 297 | } else if (mem.cutPrefix(u8, arg, "--debug-rt=")) |rest| { | 300 | } else if (mem.cutPrefix(u8, arg, "--debug-rt=")) |rest| { |
| 298 | graph.debug_compiler_runtime_libs = std.meta.stringToEnum(std.builtin.OptimizeMode, rest) orelse | 301 | graph.debug_compiler_runtime_libs = std.meta.stringToEnum(std.builtin.OptimizeMode, rest) orelse |
| 299 | fatal("unrecognized optimization mode: {s}", .{rest}); | 302 | fatal("unrecognized optimization mode: {s}", .{rest}); |
| | 303 | } else if (mem.eql(u8, arg, "--debug-maker-leaks")) { |
| | 304 | debug_maker_leaks = true; |
| 300 | } else if (mem.eql(u8, arg, "--libc-runtimes") or mem.eql(u8, arg, "--glibc-runtimes")) { | 305 | } else if (mem.eql(u8, arg, "--libc-runtimes") or mem.eql(u8, arg, "--glibc-runtimes")) { |
| 301 | // --glibc-runtimes was the old name of the flag; kept for compatibility for now. | 306 | // --glibc-runtimes was the old name of the flag; kept for compatibility for now. |
| 302 | graph.libc_runtimes_dir = nextArgOrFatal(args, &arg_idx); | 307 | graph.libc_runtimes_dir = nextArgOrFatal(args, &arg_idx); |
| ... | @@ -538,6 +543,7 @@ pub fn main(init: process.Init.Minimal) !void { | ... | @@ -538,6 +543,7 @@ pub fn main(init: process.Init.Minimal) !void { |
| 538 | .memory_blocked_steps = .empty, | 543 | .memory_blocked_steps = .empty, |
| 539 | .step_stack = .empty, | 544 | .step_stack = .empty, |
| 540 | .pkg_config = .{ .debug = debug_pkg_config }, | 545 | .pkg_config = .{ .debug = debug_pkg_config }, |
| | 546 | .debug_maker_leaks = debug_maker_leaks, |
| 541 | | 547 | |
| 542 | .error_style = error_style, | 548 | .error_style = error_style, |
| 543 | .multiline_errors = multiline_errors, | 549 | .multiline_errors = multiline_errors, |
| ... | @@ -603,10 +609,10 @@ pub fn main(init: process.Init.Minimal) !void { | ... | @@ -603,10 +609,10 @@ pub fn main(init: process.Init.Minimal) !void { |
| 603 | web_server.finishBuild(.{ .fuzz = fuzz != null }); | 609 | web_server.finishBuild(.{ .fuzz = fuzz != null }); |
| 604 | } | 610 | } |
| 605 | | 611 | |
| 606 | if (maker.web_server) |*ws| { | 612 | if (maker.web_server) |*web_server| { |
| 607 | const c = &scanned_config.configuration; | 613 | const c = &scanned_config.configuration; |
| 608 | assert(!watch); // fatal error after CLI parsing | 614 | assert(!watch); // fatal error after CLI parsing |
| 609 | while (true) switch (try ws.wait()) { | 615 | while (true) switch (try web_server.wait()) { |
| 610 | .rebuild => { | 616 | .rebuild => { |
| 611 | for (maker.step_stack.keys()) |step_index| { | 617 | for (maker.step_stack.keys()) |step_index| { |
| 612 | const step = maker.stepByIndex(step_index); | 618 | const step = maker.stepByIndex(step_index); |
| ... | @@ -620,6 +626,8 @@ pub fn main(init: process.Init.Minimal) !void { | ... | @@ -620,6 +626,8 @@ pub fn main(init: process.Init.Minimal) !void { |
| 620 | }; | 626 | }; |
| 621 | } | 627 | } |
| 622 | | 628 | |
| | 629 | if (!maker.watch) return; |
| | 630 | |
| 623 | // Comptime-known guard to prevent including the logic below when `!Watch.have_impl`. | 631 | // Comptime-known guard to prevent including the logic below when `!Watch.have_impl`. |
| 624 | if (!Watch.have_impl) unreachable; | 632 | if (!Watch.have_impl) unreachable; |
| 625 | | 633 | |
| ... | @@ -996,21 +1004,29 @@ fn makeStepNames( | ... | @@ -996,21 +1004,29 @@ fn makeStepNames( |
| 996 | | 1004 | |
| 997 | if (maker.watch or maker.web_server != null) return; | 1005 | if (maker.watch or maker.web_server != null) return; |
| 998 | | 1006 | |
| 999 | // Perhaps in the future there could be an Advanced Options flag such as | | |
| 1000 | // --debug-build-runner-leaks which would make this code return instead of | | |
| 1001 | // calling exit. | | |
| 1002 | | | |
| 1003 | const code: u8 = code: { | 1007 | const code: u8 = code: { |
| 1004 | if (failure_count == 0) break :code 0; // success | 1008 | if (failure_count == 0) break :code 0; // success |
| 1005 | if (maker.error_style.verboseContext()) break :code 1; // failure; print build command | 1009 | if (maker.error_style.verboseContext()) break :code 1; // failure; print build command |
| 1006 | break :code 2; // failure; do not print build command | 1010 | break :code 2; // failure; do not print build command |
| 1007 | }; | 1011 | }; |
| 1008 | if (code == 0) removePoisonedConfiguration(io, maker.scanned_config); | 1012 | if (code == 0) { |
| | 1013 | removePoisonedConfiguration(io, maker.scanned_config); |
| | 1014 | if (builtin.mode == .Debug and maker.debug_maker_leaks) return deinit(maker); |
| | 1015 | } |
| 1009 | cleanup_task.await(io); // There is a defer above but an exit below. | 1016 | cleanup_task.await(io); // There is a defer above but an exit below. |
| 1010 | _ = io.lockStderr(&.{}, graph.stderr_mode) catch {}; | 1017 | _ = io.lockStderr(&.{}, graph.stderr_mode) catch {}; |
| 1011 | process.exit(code); | 1018 | process.exit(code); |
| 1012 | } | 1019 | } |
| 1013 | | 1020 | |
| | 1021 | fn deinit(maker: *Maker) void { |
| | 1022 | const gpa = maker.gpa; |
| | 1023 | for (maker.steps) |*step| { |
| | 1024 | step.clearFailedCommand(gpa); |
| | 1025 | step.clearErrorBundle(gpa); |
| | 1026 | step.inputs.deinit(gpa); |
| | 1027 | } |
| | 1028 | } |
| | 1029 | |
| 1014 | fn stepReady( | 1030 | fn stepReady( |
| 1015 | maker: *Maker, | 1031 | maker: *Maker, |
| 1016 | group: *Io.Group, | 1032 | group: *Io.Group, |
| ... | @@ -1457,6 +1473,7 @@ fn constructGraphAndCheckForDependencyLoop( | ... | @@ -1457,6 +1473,7 @@ fn constructGraphAndCheckForDependencyLoop( |
| 1457 | ) error{ DependencyLoopDetected, OutOfMemory }!void { | 1473 | ) error{ DependencyLoopDetected, OutOfMemory }!void { |
| 1458 | const c = &maker.scanned_config.configuration; | 1474 | const c = &maker.scanned_config.configuration; |
| 1459 | const gpa = maker.gpa; | 1475 | const gpa = maker.gpa; |
| | 1476 | const arena = maker.graph.arena; |
| 1460 | const make_step = maker.stepByIndex(step_index); | 1477 | const make_step = maker.stepByIndex(step_index); |
| 1461 | switch (make_step.state) { | 1478 | switch (make_step.state) { |
| 1462 | .precheck_started => { | 1479 | .precheck_started => { |
| ... | @@ -1480,7 +1497,7 @@ fn constructGraphAndCheckForDependencyLoop( | ... | @@ -1480,7 +1497,7 @@ fn constructGraphAndCheckForDependencyLoop( |
| 1480 | for (deps) |dep| { | 1497 | for (deps) |dep| { |
| 1481 | const dep_step = maker.stepByIndex(dep); | 1498 | const dep_step = maker.stepByIndex(dep); |
| 1482 | try step_stack.put(gpa, dep, {}); | 1499 | try step_stack.put(gpa, dep, {}); |
| 1483 | try dep_step.dependants.append(gpa, step_index); | 1500 | try dep_step.dependants.append(arena, step_index); |
| 1484 | constructGraphAndCheckForDependencyLoop(maker, dep, step_stack, rand) catch |err| switch (err) { | 1501 | constructGraphAndCheckForDependencyLoop(maker, dep, step_stack, rand) catch |err| switch (err) { |
| 1485 | error.DependencyLoopDetected => { | 1502 | error.DependencyLoopDetected => { |
| 1486 | log.info("needed by: {s}", .{step_index.ptr(c).name.slice(c)}); | 1503 | log.info("needed by: {s}", .{step_index.ptr(c).name.slice(c)}); |