build runner: untangle dependency loop checking from making

This commit is contained in:
Andrew Kelley 2023-02-13 13:28:18 -07:00
parent c6a895f667
commit 0b744d7d67
2 changed files with 21 additions and 7 deletions

View File

@ -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();
}

View File

@ -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,
};
}