Build.Step.Run: fix cache management when there are side effects

Closes #19947
This commit is contained in:
Jacob Young 2024-05-12 23:09:40 -04:00 committed by Andrew Kelley
parent 657442485a
commit ad72172293
2 changed files with 28 additions and 7 deletions

View File

@ -397,6 +397,11 @@ pub const Manifest = struct {
}
}
pub fn addDepFile(self: *Manifest, dir: fs.Dir, dep_file_basename: []const u8) !void {
assert(self.manifest_file == null);
return self.addDepFileMaybePost(dir, dep_file_basename);
}
/// Check the cache to see if the input exists in it. If it exists, returns `true`.
/// A hex encoding of its hash is available by calling `final`.
///
@ -843,7 +848,10 @@ pub const Manifest = struct {
pub fn addDepFilePost(self: *Manifest, dir: fs.Dir, dep_file_basename: []const u8) !void {
assert(self.manifest_file != null);
return self.addDepFileMaybePost(dir, dep_file_basename);
}
fn addDepFileMaybePost(self: *Manifest, dir: fs.Dir, dep_file_basename: []const u8) !void {
const dep_file_contents = try dir.readFileAlloc(self.cache.gpa, dep_file_basename, manifest_file_size_max);
defer self.cache.gpa.free(dep_file_contents);
@ -857,7 +865,9 @@ pub const Manifest = struct {
// We don't care about targets, we only want the prereqs
// Clang is invoked in single-source mode but other programs may not
.target, .target_must_resolve => {},
.prereq => |file_path| try self.addFilePost(file_path),
.prereq => |file_path| if (self.manifest_file == null) {
_ = try self.addFile(file_path, null);
} else try self.addFilePost(file_path),
else => |err| {
try err.printError(error_buf.writer());
log.err("failed parsing {s}: {s}", .{ dep_file_basename, error_buf.items });

View File

@ -659,7 +659,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
_ = try man.addFile(lazy_path.getPath2(b, step), null);
}
if (try step.cacheHit(&man) and !has_side_effects) {
if (!has_side_effects and try step.cacheHit(&man)) {
// cache hit, skip running command
const digest = man.final();
@ -678,7 +678,10 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
const dep_output_file = run.dep_output_file orelse {
// We already know the final output paths, use them directly.
const digest = man.final();
const digest = if (has_side_effects)
man.hash.final()
else
man.final();
try populateGeneratedPaths(
arena,
@ -710,7 +713,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
}
try runCommand(run, argv_list.items, has_side_effects, output_dir_path, prog_node);
try step.writeManifest(&man);
if (!has_side_effects) try step.writeManifest(&man);
return;
};
@ -741,9 +744,17 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
try runCommand(run, argv_list.items, has_side_effects, tmp_dir_path, prog_node);
try man.addDepFilePost(std.fs.cwd(), dep_output_file.generated_file.getPath());
const dep_file_dir = std.fs.cwd();
const dep_file_basename = dep_output_file.generated_file.getPath();
if (has_side_effects)
try man.addDepFile(dep_file_dir, dep_file_basename)
else
try man.addDepFilePost(dep_file_dir, dep_file_basename);
const digest = man.final();
const digest = if (has_side_effects)
man.hash.final()
else
man.final();
const any_output = output_placeholders.items.len > 0 or
run.captured_stdout != null or run.captured_stderr != null;
@ -778,7 +789,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
};
}
try step.writeManifest(&man);
if (!has_side_effects) try step.writeManifest(&man);
try populateGeneratedPaths(
arena,