From 0cc492a272ef9c03a34b57a26bf570b242615ddf Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Tue, 9 Jul 2024 21:08:20 -0700 Subject: [PATCH] make more build steps integrate with the watch system --- lib/std/Build.zig | 2 +- lib/std/Build/Step.zig | 15 +++++++++------ lib/std/Build/Step/CheckFile.zig | 1 + lib/std/Build/Step/CheckObject.zig | 1 + lib/std/Build/Step/ConfigHeader.zig | 2 ++ lib/std/Build/Step/InstallFile.zig | 4 +--- lib/std/Build/Step/ObjCopy.zig | 1 + lib/std/Build/Step/Options.zig | 3 +++ lib/std/Build/Step/RemoveDir.zig | 20 +++++++++++++------- test/tests.zig | 6 +++--- 10 files changed, 35 insertions(+), 20 deletions(-) diff --git a/lib/std/Build.zig b/lib/std/Build.zig index 30aa5b72db..72108adaf5 100644 --- a/lib/std/Build.zig +++ b/lib/std/Build.zig @@ -1052,7 +1052,7 @@ pub fn addWriteFiles(b: *Build) *Step.WriteFile { return Step.WriteFile.create(b); } -pub fn addRemoveDirTree(b: *Build, dir_path: []const u8) *Step.RemoveDir { +pub fn addRemoveDirTree(b: *Build, dir_path: LazyPath) *Step.RemoveDir { return Step.RemoveDir.create(b, dir_path); } diff --git a/lib/std/Build/Step.zig b/lib/std/Build/Step.zig index 4b958be284..91d3924611 100644 --- a/lib/std/Build/Step.zig +++ b/lib/std/Build/Step.zig @@ -598,14 +598,17 @@ pub fn writeManifest(s: *Step, man: *Build.Cache.Manifest) !void { } } -fn oom(err: anytype) noreturn { - switch (err) { - error.OutOfMemory => @panic("out of memory"), - } +/// For steps that have a single input that never changes when re-running `make`. +pub fn singleUnchangingWatchInput(step: *Step, lazy_path: Build.LazyPath) Allocator.Error!void { + if (!step.inputs.populated()) try step.addWatchInput(lazy_path); } -pub fn addWatchInput(step: *Step, lazy_path: Build.LazyPath) void { - errdefer |err| oom(err); +pub fn clearWatchInputs(step: *Step) void { + const gpa = step.owner.allocator; + step.inputs.clear(gpa); +} + +pub fn addWatchInput(step: *Step, lazy_path: Build.LazyPath) Allocator.Error!void { switch (lazy_path) { .src_path => |src_path| try addWatchInputFromBuilder(step, src_path.owner, src_path.sub_path), .dependency => |d| try addWatchInputFromBuilder(step, d.dependency.builder, d.sub_path), diff --git a/lib/std/Build/Step/CheckFile.zig b/lib/std/Build/Step/CheckFile.zig index b7ce2ded61..c7a2046c1f 100644 --- a/lib/std/Build/Step/CheckFile.zig +++ b/lib/std/Build/Step/CheckFile.zig @@ -50,6 +50,7 @@ fn make(step: *Step, prog_node: std.Progress.Node) !void { _ = prog_node; const b = step.owner; const check_file: *CheckFile = @fieldParentPtr("step", step); + try step.singleUnchangingWatchInput(check_file.source); const src_path = check_file.source.getPath2(b, step); const contents = fs.cwd().readFileAlloc(b.allocator, src_path, check_file.max_bytes) catch |err| { diff --git a/lib/std/Build/Step/CheckObject.zig b/lib/std/Build/Step/CheckObject.zig index f25708c55b..93ee57e3b4 100644 --- a/lib/std/Build/Step/CheckObject.zig +++ b/lib/std/Build/Step/CheckObject.zig @@ -555,6 +555,7 @@ fn make(step: *Step, prog_node: std.Progress.Node) !void { const b = step.owner; const gpa = b.allocator; const check_object: *CheckObject = @fieldParentPtr("step", step); + try step.singleUnchangingWatchInput(check_object.source); const src_path = check_object.source.getPath2(b, step); const contents = fs.cwd().readFileAllocOptions( diff --git a/lib/std/Build/Step/ConfigHeader.zig b/lib/std/Build/Step/ConfigHeader.zig index 6390a88da7..fd655125cf 100644 --- a/lib/std/Build/Step/ConfigHeader.zig +++ b/lib/std/Build/Step/ConfigHeader.zig @@ -168,6 +168,8 @@ fn make(step: *Step, prog_node: std.Progress.Node) !void { _ = prog_node; const b = step.owner; const config_header: *ConfigHeader = @fieldParentPtr("step", step); + if (config_header.style.getPath()) |lp| try step.singleUnchangingWatchInput(lp); + const gpa = b.allocator; const arena = b.allocator; diff --git a/lib/std/Build/Step/InstallFile.zig b/lib/std/Build/Step/InstallFile.zig index f68e6e8aa0..d29ac21c1c 100644 --- a/lib/std/Build/Step/InstallFile.zig +++ b/lib/std/Build/Step/InstallFile.zig @@ -39,9 +39,7 @@ fn make(step: *Step, prog_node: std.Progress.Node) !void { _ = prog_node; const b = step.owner; const install_file: *InstallFile = @fieldParentPtr("step", step); - - // Inputs never change when re-running `make`. - if (!step.inputs.populated()) step.addWatchInput(install_file.source); + try step.singleUnchangingWatchInput(install_file.source); const full_src_path = install_file.source.getPath2(b, step); const full_dest_path = b.getInstallPath(install_file.dir, install_file.dest_rel_path); diff --git a/lib/std/Build/Step/ObjCopy.zig b/lib/std/Build/Step/ObjCopy.zig index 06c9a8ef0d..908341aefb 100644 --- a/lib/std/Build/Step/ObjCopy.zig +++ b/lib/std/Build/Step/ObjCopy.zig @@ -93,6 +93,7 @@ pub fn getOutputSeparatedDebug(objcopy: *const ObjCopy) ?std.Build.LazyPath { fn make(step: *Step, prog_node: std.Progress.Node) !void { const b = step.owner; const objcopy: *ObjCopy = @fieldParentPtr("step", step); + try step.singleUnchangingWatchInput(objcopy.input_file); var man = b.graph.cache.obtain(); defer man.deinit(); diff --git a/lib/std/Build/Step/Options.zig b/lib/std/Build/Step/Options.zig index 2937cf70e1..9ce23e0802 100644 --- a/lib/std/Build/Step/Options.zig +++ b/lib/std/Build/Step/Options.zig @@ -424,6 +424,9 @@ fn make(step: *Step, prog_node: std.Progress.Node) !void { item.path.getPath2(b, step), ); } + if (!step.inputs.populated()) for (options.args.items) |item| { + try step.addWatchInput(item.path); + }; const basename = "options.zig"; diff --git a/lib/std/Build/Step/RemoveDir.zig b/lib/std/Build/Step/RemoveDir.zig index 6483a684aa..1b7dc7feb8 100644 --- a/lib/std/Build/Step/RemoveDir.zig +++ b/lib/std/Build/Step/RemoveDir.zig @@ -2,22 +2,23 @@ const std = @import("std"); const fs = std.fs; const Step = std.Build.Step; const RemoveDir = @This(); +const LazyPath = std.Build.LazyPath; pub const base_id: Step.Id = .remove_dir; step: Step, -dir_path: []const u8, +doomed_path: LazyPath, -pub fn create(owner: *std.Build, dir_path: []const u8) *RemoveDir { +pub fn create(owner: *std.Build, doomed_path: LazyPath) *RemoveDir { const remove_dir = owner.allocator.create(RemoveDir) catch @panic("OOM"); remove_dir.* = .{ .step = Step.init(.{ .id = base_id, - .name = owner.fmt("RemoveDir {s}", .{dir_path}), + .name = owner.fmt("RemoveDir {s}", .{doomed_path.getDisplayName()}), .owner = owner, .makeFn = make, }), - .dir_path = owner.dupePath(dir_path), + .doomed_path = doomed_path.dupe(owner), }; return remove_dir; } @@ -30,14 +31,19 @@ fn make(step: *Step, prog_node: std.Progress.Node) !void { const b = step.owner; const remove_dir: *RemoveDir = @fieldParentPtr("step", step); - b.build_root.handle.deleteTree(remove_dir.dir_path) catch |err| { + step.clearWatchInputs(); + try step.addWatchInput(remove_dir.doomed_path); + + const full_doomed_path = remove_dir.doomed_path.getPath2(b, step); + + b.build_root.handle.deleteTree(full_doomed_path) catch |err| { if (b.build_root.path) |base| { return step.fail("unable to recursively delete path '{s}/{s}': {s}", .{ - base, remove_dir.dir_path, @errorName(err), + base, full_doomed_path, @errorName(err), }); } else { return step.fail("unable to recursively delete path '{s}': {s}", .{ - remove_dir.dir_path, @errorName(err), + full_doomed_path, @errorName(err), }); } }; diff --git a/test/tests.zig b/test/tests.zig index 95a86c68f6..e19a9efccf 100644 --- a/test/tests.zig +++ b/test/tests.zig @@ -771,7 +771,7 @@ pub fn addCliTests(b: *std.Build) *Step { run_run.expectStdErrEqual("All your codebase are belong to us.\n"); run_run.step.dependOn(&init_exe.step); - const cleanup = b.addRemoveDirTree(tmp_path); + const cleanup = b.addRemoveDirTree(.{ .cwd_relative = tmp_path }); cleanup.step.dependOn(&run_test.step); cleanup.step.dependOn(&run_run.step); cleanup.step.dependOn(&run_bad.step); @@ -816,7 +816,7 @@ pub fn addCliTests(b: *std.Build) *Step { }); checkfile.setName("check godbolt.org CLI usage generating valid asm"); - const cleanup = b.addRemoveDirTree(tmp_path); + const cleanup = b.addRemoveDirTree(.{ .cwd_relative = tmp_path }); cleanup.step.dependOn(&checkfile.step); step.dependOn(&cleanup.step); @@ -902,7 +902,7 @@ pub fn addCliTests(b: *std.Build) *Step { }); check6.step.dependOn(&run6.step); - const cleanup = b.addRemoveDirTree(tmp_path); + const cleanup = b.addRemoveDirTree(.{ .cwd_relative = tmp_path }); cleanup.step.dependOn(&check6.step); step.dependOn(&cleanup.step);