From 0b744d7d670d00fa865ebd17847cbdc1a909ba70 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Mon, 13 Feb 2023 13:28:18 -0700 Subject: [PATCH] build runner: untangle dependency loop checking from making --- lib/build_runner.zig | 23 ++++++++++++++++++----- lib/std/Build/Step.zig | 5 +++-- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/lib/build_runner.zig b/lib/build_runner.zig index f9a2bbd40a..cc5c9325ae 100644 --- a/lib/build_runner.zig +++ b/lib/build_runner.zig @@ -274,20 +274,27 @@ fn make(b: *std.Build, step_names: []const []const u8) !void { } } + for (wanted_steps.items) |s| { + checkForDependencyLoop(b, s) catch |err| switch (err) { + error.DependencyLoopDetected => return error.UncleanExit, + else => |e| return e, + }; + } + for (wanted_steps.items) |s| { try makeOneStep(b, s); } } -fn makeOneStep(b: *std.Build, s: *std.Build.Step) anyerror!void { - if (s.loop_flag) { +fn checkForDependencyLoop(b: *std.Build, s: *std.Build.Step) !void { + if (s.loop_tag == .started) { std.debug.print("dependency loop detected:\n {s}\n", .{s.name}); return error.DependencyLoopDetected; } - s.loop_flag = true; + s.loop_tag = .started; for (s.dependencies.items) |dep| { - makeOneStep(b, dep) catch |err| { + checkForDependencyLoop(b, dep) catch |err| { if (err == error.DependencyLoopDetected) { std.debug.print(" {s}\n", .{s.name}); } @@ -295,7 +302,13 @@ fn makeOneStep(b: *std.Build, s: *std.Build.Step) anyerror!void { }; } - s.loop_flag = false; + s.loop_tag = .done; +} + +fn makeOneStep(b: *std.Build, s: *std.Build.Step) anyerror!void { + for (s.dependencies.items) |dep| { + try makeOneStep(b, dep); + } try s.make(); } diff --git a/lib/std/Build/Step.zig b/lib/std/Build/Step.zig index 82c39ac2cc..16b1640e70 100644 --- a/lib/std/Build/Step.zig +++ b/lib/std/Build/Step.zig @@ -2,7 +2,8 @@ id: Id, name: []const u8, makeFn: *const fn (self: *Step) anyerror!void, dependencies: std.ArrayList(*Step), -loop_flag: bool, +/// Used only during a pre-check for dependency loops. +loop_tag: enum { unstarted, started, done }, done_flag: bool, pub const Id = enum { @@ -60,7 +61,7 @@ pub fn init( .name = allocator.dupe(u8, name) catch @panic("OOM"), .makeFn = makeFn, .dependencies = std.ArrayList(*Step).init(allocator), - .loop_flag = false, + .loop_tag = .unstarted, .done_flag = false, }; }