authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2024-05-12 23:09:40-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-05-20 07:45:31-04:00
logad721722932b8cb0d22b2f0048d3bd952319ef97
tree933b867aff65507b9cb838d61d5de8597a0710e2
parent657442485a6386aad80eadb5a4217fe86c126e24

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

Closes #19947

2 files changed, 28 insertions(+), 7 deletions(-)

lib/std/Build/Cache.zig+11-1
...@@ -397,6 +397,11 @@ pub const Manifest = struct {...@@ -397,6 +397,11 @@ pub const Manifest = struct {
397 }397 }
398 }398 }
399399
400 pub fn addDepFile(self: *Manifest, dir: fs.Dir, dep_file_basename: []const u8) !void {
401 assert(self.manifest_file == null);
402 return self.addDepFileMaybePost(dir, dep_file_basename);
403 }
404
400 /// Check the cache to see if the input exists in it. If it exists, returns `true`.405 /// Check the cache to see if the input exists in it. If it exists, returns `true`.
401 /// A hex encoding of its hash is available by calling `final`.406 /// A hex encoding of its hash is available by calling `final`.
402 ///407 ///
...@@ -843,7 +848,10 @@ pub const Manifest = struct {...@@ -843,7 +848,10 @@ pub const Manifest = struct {
843848
844 pub fn addDepFilePost(self: *Manifest, dir: fs.Dir, dep_file_basename: []const u8) !void {849 pub fn addDepFilePost(self: *Manifest, dir: fs.Dir, dep_file_basename: []const u8) !void {
845 assert(self.manifest_file != null);850 assert(self.manifest_file != null);
851 return self.addDepFileMaybePost(dir, dep_file_basename);
852 }
846853
854 fn addDepFileMaybePost(self: *Manifest, dir: fs.Dir, dep_file_basename: []const u8) !void {
847 const dep_file_contents = try dir.readFileAlloc(self.cache.gpa, dep_file_basename, manifest_file_size_max);855 const dep_file_contents = try dir.readFileAlloc(self.cache.gpa, dep_file_basename, manifest_file_size_max);
848 defer self.cache.gpa.free(dep_file_contents);856 defer self.cache.gpa.free(dep_file_contents);
849857
...@@ -857,7 +865,9 @@ pub const Manifest = struct {...@@ -857,7 +865,9 @@ pub const Manifest = struct {
857 // We don't care about targets, we only want the prereqs865 // We don't care about targets, we only want the prereqs
858 // Clang is invoked in single-source mode but other programs may not866 // Clang is invoked in single-source mode but other programs may not
859 .target, .target_must_resolve => {},867 .target, .target_must_resolve => {},
860 .prereq => |file_path| try self.addFilePost(file_path),868 .prereq => |file_path| if (self.manifest_file == null) {
869 _ = try self.addFile(file_path, null);
870 } else try self.addFilePost(file_path),
861 else => |err| {871 else => |err| {
862 try err.printError(error_buf.writer());872 try err.printError(error_buf.writer());
863 log.err("failed parsing {s}: {s}", .{ dep_file_basename, error_buf.items });873 log.err("failed parsing {s}: {s}", .{ dep_file_basename, error_buf.items });
lib/std/Build/Step/Run.zig+17-6
...@@ -659,7 +659,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -659,7 +659,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
659 _ = try man.addFile(lazy_path.getPath2(b, step), null);659 _ = try man.addFile(lazy_path.getPath2(b, step), null);
660 }660 }
661661
662 if (try step.cacheHit(&man) and !has_side_effects) {662 if (!has_side_effects and try step.cacheHit(&man)) {
663 // cache hit, skip running command663 // cache hit, skip running command
664 const digest = man.final();664 const digest = man.final();
665665
...@@ -678,7 +678,10 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -678,7 +678,10 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
678678
679 const dep_output_file = run.dep_output_file orelse {679 const dep_output_file = run.dep_output_file orelse {
680 // We already know the final output paths, use them directly.680 // We already know the final output paths, use them directly.
681 const digest = man.final();681 const digest = if (has_side_effects)
682 man.hash.final()
683 else
684 man.final();
682685
683 try populateGeneratedPaths(686 try populateGeneratedPaths(
684 arena,687 arena,
...@@ -710,7 +713,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -710,7 +713,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
710 }713 }
711714
712 try runCommand(run, argv_list.items, has_side_effects, output_dir_path, prog_node);715 try runCommand(run, argv_list.items, has_side_effects, output_dir_path, prog_node);
713 try step.writeManifest(&man);716 if (!has_side_effects) try step.writeManifest(&man);
714 return;717 return;
715 };718 };
716719
...@@ -741,9 +744,17 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -741,9 +744,17 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
741744
742 try runCommand(run, argv_list.items, has_side_effects, tmp_dir_path, prog_node);745 try runCommand(run, argv_list.items, has_side_effects, tmp_dir_path, prog_node);
743746
744 try man.addDepFilePost(std.fs.cwd(), dep_output_file.generated_file.getPath());747 const dep_file_dir = std.fs.cwd();
748 const dep_file_basename = dep_output_file.generated_file.getPath();
749 if (has_side_effects)
750 try man.addDepFile(dep_file_dir, dep_file_basename)
751 else
752 try man.addDepFilePost(dep_file_dir, dep_file_basename);
745753
746 const digest = man.final();754 const digest = if (has_side_effects)
755 man.hash.final()
756 else
757 man.final();
747758
748 const any_output = output_placeholders.items.len > 0 or759 const any_output = output_placeholders.items.len > 0 or
749 run.captured_stdout != null or run.captured_stderr != null;760 run.captured_stdout != null or run.captured_stderr != null;
...@@ -778,7 +789,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -778,7 +789,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
778 };789 };
779 }790 }
780791
781 try step.writeManifest(&man);792 if (!has_side_effects) try step.writeManifest(&man);
782793
783 try populateGeneratedPaths(794 try populateGeneratedPaths(
784 arena,795 arena,