commit b490412cd28e4bc76de9dfe39ac1d99435a86814 (tree)
parent 523cfabcdff65c9547299b3a4f721d2052c163ee
Author: Andrew Kelley <andrew@ziglang.org>
Date: Fri, 27 Mar 2026 05:08:24 -0700
build runner: fail, not warn when insufficient memory
Users can proceed by telling the build system how much memory to assume
the system has. I have improved the failure message to communicate this.
Partially reverts 87f8f47ba508b684d03c13b850cac3fb72efac26
Even if we wanted to unrevert this reverted commit, it's not sufficient
to merely downgrade the failure to a warning, because the main
scheduling logic will fail to schedule steps that have a max_rss
exceeding the detected system value, causing some steps to never get
executed, eventually tripping an assert. Such a change would need to
also override the max_rss value to be equal to the greatest value across
all steps.
closes #31510
Diffstat:
1 file changed, 10 insertions(+), 5 deletions(-)
diff --git a/lib/compiler/build_runner.zig b/lib/compiler/build_runner.zig
@@ -532,7 +532,7 @@ pub fn main(init: process.Init.Minimal) !void {
}
prepare(arena, builder, targets.items, &run, graph.random_seed) catch |err| switch (err) {
- error.DependencyLoopDetected => {
+ error.DependencyLoopDetected, error.InsufficientMemory => {
// Perhaps in the future there could be an Advanced Options flag
// such as --debug-build-runner-leaks which would make this code
// return instead of calling exit.
@@ -696,8 +696,8 @@ fn prepare(
for (0..step_names.len) |i| {
const step_name = step_names[step_names.len - i - 1];
const s = b.top_level_steps.get(step_name) orelse {
- std.debug.print("no step named '{s}'\n access the help menu with 'zig build -h'\n", .{step_name});
- process.exit(1);
+ std.log.info("access the help menu with \"zig build -h\"", .{});
+ fatal("no step named '{s}'", .{step_name});
};
step_stack.putAssumeCapacity(&s.step, {});
}
@@ -716,8 +716,10 @@ fn prepare(
{
// Check that we have enough memory to complete the build.
var any_problems = false;
+ var max_needed: usize = 0;
for (step_stack.keys()) |s| {
if (s.max_rss == 0) continue;
+ max_needed = @max(max_needed, s.max_rss);
if (s.max_rss > run.available_rss) {
if (run.skip_oom_steps) {
s.state = .skipped_oom;
@@ -725,7 +727,7 @@ fn prepare(
dependant.pending_deps -= 1;
}
} else {
- std.debug.print("{s}{s}: this step declares an upper bound of {d} bytes of memory, exceeding the available {d} bytes of memory\n", .{
+ std.log.err("{s}{s}: this step declares an upper bound of {d} bytes of memory, exceeding the available {d} bytes of memory", .{
s.owner.dep_prefix, s.name, s.max_rss, run.available_rss,
});
any_problems = true;
@@ -734,8 +736,11 @@ fn prepare(
}
if (any_problems) {
if (run.max_rss_is_default) {
- std.debug.print("note: use --maxrss to override the default", .{});
+ std.log.info("use --maxrss {d} to proceed, risking system memory exhaustion", .{
+ max_needed,
+ });
}
+ return error.InsufficientMemory;
}
}
}