authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-02-13 13:28:18-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-03-15 10:48:12-07:00
log0b744d7d670d00fa865ebd17847cbdc1a909ba70
treed43cbc658d26a9f2fe919651598af137ff859fbe
parentc6a895f6671d30e2db77ae4f4e0c2d9e40624787

build runner: untangle dependency loop checking from making


2 files changed, 21 insertions(+), 7 deletions(-)

lib/build_runner.zig+18-5
...@@ -274,20 +274,27 @@ fn make(b: *std.Build, step_names: []const []const u8) !void {...@@ -274,20 +274,27 @@ fn make(b: *std.Build, step_names: []const []const u8) !void {
274 }274 }
275 }275 }
276276
277 for (wanted_steps.items) |s| {
278 checkForDependencyLoop(b, s) catch |err| switch (err) {
279 error.DependencyLoopDetected => return error.UncleanExit,
280 else => |e| return e,
281 };
282 }
283
277 for (wanted_steps.items) |s| {284 for (wanted_steps.items) |s| {
278 try makeOneStep(b, s);285 try makeOneStep(b, s);
279 }286 }
280}287}
281288
282fn makeOneStep(b: *std.Build, s: *std.Build.Step) anyerror!void {289fn checkForDependencyLoop(b: *std.Build, s: *std.Build.Step) !void {
283 if (s.loop_flag) {290 if (s.loop_tag == .started) {
284 std.debug.print("dependency loop detected:\n {s}\n", .{s.name});291 std.debug.print("dependency loop detected:\n {s}\n", .{s.name});
285 return error.DependencyLoopDetected;292 return error.DependencyLoopDetected;
286 }293 }
287 s.loop_flag = true;294 s.loop_tag = .started;
288295
289 for (s.dependencies.items) |dep| {296 for (s.dependencies.items) |dep| {
290 makeOneStep(b, dep) catch |err| {297 checkForDependencyLoop(b, dep) catch |err| {
291 if (err == error.DependencyLoopDetected) {298 if (err == error.DependencyLoopDetected) {
292 std.debug.print(" {s}\n", .{s.name});299 std.debug.print(" {s}\n", .{s.name});
293 }300 }
...@@ -295,7 +302,13 @@ fn makeOneStep(b: *std.Build, s: *std.Build.Step) anyerror!void {...@@ -295,7 +302,13 @@ fn makeOneStep(b: *std.Build, s: *std.Build.Step) anyerror!void {
295 };302 };
296 }303 }
297304
298 s.loop_flag = false;305 s.loop_tag = .done;
306}
307
308fn makeOneStep(b: *std.Build, s: *std.Build.Step) anyerror!void {
309 for (s.dependencies.items) |dep| {
310 try makeOneStep(b, dep);
311 }
299312
300 try s.make();313 try s.make();
301}314}
lib/std/Build/Step.zig+3-2
...@@ -2,7 +2,8 @@ id: Id,...@@ -2,7 +2,8 @@ id: Id,
2name: []const u8,2name: []const u8,
3makeFn: *const fn (self: *Step) anyerror!void,3makeFn: *const fn (self: *Step) anyerror!void,
4dependencies: std.ArrayList(*Step),4dependencies: std.ArrayList(*Step),
5loop_flag: bool,5/// Used only during a pre-check for dependency loops.
6loop_tag: enum { unstarted, started, done },
6done_flag: bool,7done_flag: bool,
78
8pub const Id = enum {9pub const Id = enum {
...@@ -60,7 +61,7 @@ pub fn init(...@@ -60,7 +61,7 @@ pub fn init(
60 .name = allocator.dupe(u8, name) catch @panic("OOM"),61 .name = allocator.dupe(u8, name) catch @panic("OOM"),
61 .makeFn = makeFn,62 .makeFn = makeFn,
62 .dependencies = std.ArrayList(*Step).init(allocator),63 .dependencies = std.ArrayList(*Step).init(allocator),
63 .loop_flag = false,64 .loop_tag = .unstarted,
64 .done_flag = false,65 .done_flag = false,
65 };66 };
66}67}