make more build steps integrate with the watch system

This commit is contained in:
Andrew Kelley 2024-07-09 21:08:20 -07:00
parent 956f1ebc70
commit 0cc492a272
10 changed files with 35 additions and 20 deletions

View file

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

View file

@ -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),

View file

@ -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| {

View file

@ -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(

View file

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

View file

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

View file

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

View file

@ -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";

View file

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

View file

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