authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-09-11 19:08:30-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-09-16 13:12:47-07:00
logb91a6dc5b1c99ec8308fd14224d9cd8c44785021
tree1eaf4bf93c93ca9150785b62f522dfb7a01ed0a7
parenta24b4758f4cabe7c690a5707f2fe2fda913b549c

update to newest std.Build.Cache API


15 files changed, 184 insertions(+), 151 deletions(-)

lib/compiler/Maker.zig+2-2
...@@ -1543,7 +1543,7 @@ fn configure(graph: *Graph, options: ConfigureOptions) !ScannedConfig {...@@ -1543,7 +1543,7 @@ fn configure(graph: *Graph, options: ConfigureOptions) !ScannedConfig {
1543 config_tmp_path, final_path, e,1543 config_tmp_path, final_path, e,
1544 });1544 });
1545 };1545 };
1546 man.writeManifest() catch |err| log.warn("failed to write cache manifest: {t}", .{err});1546 man.finalize() catch |err| log.warn("failed to write cache manifest: {t}", .{err});
1547 options.src_files.* = man.takeFiles();1547 options.src_files.* = man.takeFiles();
1548 break :cp .{ final_path, man.toOwnedLock() };1548 break :cp .{ final_path, man.toOwnedLock() };
1549 }1549 }
...@@ -1934,7 +1934,7 @@ fn cacheCatOne(input_hex_digest: []const u8, contents: []const u8, writer: *Io.W...@@ -1934,7 +1934,7 @@ fn cacheCatOne(input_hex_digest: []const u8, contents: []const u8, writer: *Io.W
1934 while (off + 1 < contents.len) {1934 while (off + 1 < contents.len) {
1935 const file_off: Cache.Manifest.File.Offset = @fromBackingInt(@intCast(off));1935 const file_off: Cache.Manifest.File.Offset = @fromBackingInt(@intCast(off));
1936 const file = try file_off.getFallibleConst(contents);1936 const file = try file_off.getFallibleConst(contents);
1937 const path = try Cache.Manifest.filePathFallible(contents, file_off);1937 const path = try file_off.pathFallible(contents);
1938 if (path.len == 0) return error.InvalidFormat;1938 if (path.len == 0) return error.InvalidFormat;
19391939
1940 var file_obj = try files_tuple.beginStructField(.{ .whitespace_style = .{ .wrap = false } });1940 var file_obj = try files_tuple.beginStructField(.{ .whitespace_style = .{ .wrap = false } });
lib/compiler/Maker/Step.zig+7-8
...@@ -734,7 +734,7 @@ pub fn cacheHit(s: *Step, maker: *Maker, man: *Cache.Manifest, parent_progress_n...@@ -734,7 +734,7 @@ pub fn cacheHit(s: *Step, maker: *Maker, man: *Cache.Manifest, parent_progress_n
734/// Clears previous watch inputs, if any, and then populates watch inputs from734/// Clears previous watch inputs, if any, and then populates watch inputs from
735/// the full set of files picked up by the cache manifest.735/// the full set of files picked up by the cache manifest.
736///736///
737/// Must be accompanied with `writeManifestAndWatch`.737/// Must be accompanied with `finalizeManifestAndWatch`.
738pub fn cacheHitWatched(s: *Step, maker: *Maker, man: *Cache.Manifest, parent_progress_node: std.Progress.Node) !bool {738pub fn cacheHitWatched(s: *Step, maker: *Maker, man: *Cache.Manifest, parent_progress_node: std.Progress.Node) !bool {
739 const hit = .hit == (man.check(parent_progress_node) catch |err| return failWithCacheError(s, maker, man, err));739 const hit = .hit == (man.check(parent_progress_node) catch |err| return failWithCacheError(s, maker, man, err));
740 s.result_cached = hit;740 s.result_cached = hit;
...@@ -748,7 +748,7 @@ fn failWithCacheError(...@@ -748,7 +748,7 @@ fn failWithCacheError(
748 s: *Step,748 s: *Step,
749 maker: *Maker,749 maker: *Maker,
750 man: *const Cache.Manifest,750 man: *const Cache.Manifest,
751 err: Cache.Manifest.Check.Error,751 err: Cache.Manifest.CheckError,
752) error{ OutOfMemory, Canceled, MakeFailed } {752) error{ OutOfMemory, Canceled, MakeFailed } {
753 switch (err) {753 switch (err) {
754 error.CacheCheckFailed => switch (man.diagnostic) {754 error.CacheCheckFailed => switch (man.diagnostic) {
...@@ -762,15 +762,14 @@ fn failWithCacheError(...@@ -762,15 +762,14 @@ fn failWithCacheError(
762 },762 },
763 },763 },
764 error.OutOfMemory, error.Canceled => |e| return e,764 error.OutOfMemory, error.Canceled => |e| return e,
765 error.InvalidFormat => return s.fail(maker, "failed checking cache: invalid manifest file format", .{}),
766 }765 }
767}766}
768767
769/// Prefer `writeManifestAndWatch` unless you already added watch inputs768/// Prefer `finalizeManifestAndWatch` unless you already added watch inputs
770/// separately from using the cache system.769/// separately from using the cache system.
771pub fn writeManifest(s: *Step, maker: *Maker, man: *Cache.Manifest) !void {770pub fn finalizeManifest(s: *Step, maker: *Maker, man: *Cache.Manifest) !void {
772 if (s.test_results.isSuccess()) {771 if (s.test_results.isSuccess()) {
773 man.writeManifest() catch |err| switch (err) {772 man.finalize() catch |err| switch (err) {
774 error.Canceled => |e| return e,773 error.Canceled => |e| return e,
775 else => |e| try s.addError(maker, "failed writing cache manifest: {t}", .{e}),774 else => |e| try s.addError(maker, "failed writing cache manifest: {t}", .{e}),
776 };775 };
...@@ -781,8 +780,8 @@ pub fn writeManifest(s: *Step, maker: *Maker, man: *Cache.Manifest) !void {...@@ -781,8 +780,8 @@ pub fn writeManifest(s: *Step, maker: *Maker, man: *Cache.Manifest) !void {
781/// the full set of files picked up by the cache manifest.780/// the full set of files picked up by the cache manifest.
782///781///
783/// Must be accompanied with `cacheHitWatched`.782/// Must be accompanied with `cacheHitWatched`.
784pub fn writeManifestAndWatch(s: *Step, maker: *Maker, man: *Cache.Manifest) !void {783pub fn finalizeManifestAndWatch(s: *Step, maker: *Maker, man: *Cache.Manifest) !void {
785 try writeManifest(s, maker, man);784 try finalizeManifest(s, maker, man);
786 try setWatchInputsFromManifest(s, maker, man);785 try setWatchInputsFromManifest(s, maker, man);
787}786}
788787
lib/compiler/Maker/Step/ConfigHeader.zig+1-1
...@@ -169,7 +169,7 @@ pub fn make(...@@ -169,7 +169,7 @@ pub fn make(
169 .sub_path = try Io.Dir.path.join(arena, &.{ "o", &digest }),169 .sub_path = try Io.Dir.path.join(arena, &.{ "o", &digest }),
170 };170 };
171171
172 try step.writeManifest(maker, &man);172 try step.finalizeManifest(maker, &man);
173}173}
174174
175fn ensureAllValuesUsed(175fn ensureAllValuesUsed(
lib/compiler/Maker/Step/ObjCopy.zig+1-1
...@@ -165,7 +165,7 @@ pub fn make(...@@ -165,7 +165,7 @@ pub fn make(
165165
166 maker.generatedPath(conf_oc.output_file).* = dest_path;166 maker.generatedPath(conf_oc.output_file).* = dest_path;
167167
168 step.writeManifest(maker, &man) catch |err| switch (err) {168 step.finalizeManifest(maker, &man) catch |err| switch (err) {
169 error.Canceled => |e| return e,169 error.Canceled => |e| return e,
170 else => |e| try step.addError(maker, "failed writing cache manifest: {t}", .{e}),170 else => |e| try step.addError(maker, "failed writing cache manifest: {t}", .{e}),
171 };171 };
lib/compiler/Maker/Step/Options.zig+1-1
...@@ -95,7 +95,7 @@ pub fn make(...@@ -95,7 +95,7 @@ pub fn make(
95 },95 },
96 };96 };
9797
98 try step.writeManifestAndWatch(maker, &man);98 try step.finalizeManifestAndWatch(maker, &man);
9999
100 maker.generatedPath(conf_options.generated_file).* = out_path;100 maker.generatedPath(conf_options.generated_file).* = out_path;
101}101}
lib/compiler/Maker/Step/Run.zig+2-2
...@@ -275,7 +275,7 @@ pub fn make(...@@ -275,7 +275,7 @@ pub fn make(
275 try populateGeneratedStdIo(maker, &conf_run, cache_root, &digest);275 try populateGeneratedStdIo(maker, &conf_run, cache_root, &digest);
276 try populateGeneratedPathsCreateDirs(arena, run_index, maker, output_dir_path, output_placeholders.items, argv_list.items);276 try populateGeneratedPathsCreateDirs(arena, run_index, maker, output_dir_path, output_placeholders.items, argv_list.items);
277 try runCommand(arena, run, run_index, maker, progress_node, argv_list.items, has_side_effects, output_dir_path, null);277 try runCommand(arena, run, run_index, maker, progress_node, argv_list.items, has_side_effects, output_dir_path, null);
278 if (!has_side_effects) try step.writeManifestAndWatch(maker, &man);278 if (!has_side_effects) try step.finalizeManifestAndWatch(maker, &man);
279 return;279 return;
280 }280 }
281281
...@@ -344,7 +344,7 @@ pub fn make(...@@ -344,7 +344,7 @@ pub fn make(
344 };344 };
345 }345 }
346346
347 if (!has_side_effects) try step.writeManifestAndWatch(maker, &man);347 if (!has_side_effects) try step.finalizeManifestAndWatch(maker, &man);
348348
349 try populateGeneratedStdIo(maker, &conf_run, cache_root, &digest);349 try populateGeneratedStdIo(maker, &conf_run, cache_root, &digest);
350 try populateGeneratedPaths(maker, output_placeholders.items, cache_root, &digest);350 try populateGeneratedPaths(maker, output_placeholders.items, cache_root, &digest);
lib/compiler/Maker/Step/WriteFile.zig+1-1
...@@ -122,7 +122,7 @@ pub fn make(...@@ -122,7 +122,7 @@ pub fn make(
122122
123 progress_node.setEstimatedTotalItems(total_items);123 progress_node.setEstimatedTotalItems(total_items);
124 try operate(maker, step_index, open_dir_cache, out_path, progress_node);124 try operate(maker, step_index, open_dir_cache, out_path, progress_node);
125 try step.writeManifest(maker, &man);125 try step.finalizeManifest(maker, &man);
126126
127 maker.generatedPath(conf_wf.generated_directory).* = out_path;127 maker.generatedPath(conf_wf.generated_directory).* = out_path;
128 },128 },
lib/std/Build/Cache.zig+154-107
...@@ -325,30 +325,59 @@ pub const Manifest = struct {...@@ -325,30 +325,59 @@ pub const Manifest = struct {
325 have_stat: bool,325 have_stat: bool,
326 /// Determines whether `File.digest` is populated.326 /// Determines whether `File.digest` is populated.
327 have_digest: bool,327 have_digest: bool,
328 contents: packed union(u64) {328 contents: struct {
329 status: enum(u64) {329 pop_off: enum(u32) { unpopulated = std.math.maxInt(u32), _ },
330 unrequested = std.math.maxInt(u64) - 1,330 req_len: enum(u32) { unrequested = std.math.maxInt(u32) - 1, requested = std.math.maxInt(u32), _ },
331 requested = std.math.maxInt(u64),331
332 _,332 pub const requested: @This() = .{
333 pub fn populated(this: @This()) bool {333 .pop_off = .unpopulated,
334 return switch (this) {334 .req_len = .requested,
335 .unrequested, .requested => false,335 };
336 _ => true,336
337 };337 pub const unrequested: @This() = .{
338 }338 .pop_off = .unpopulated,
339 },339 .req_len = .unrequested,
340 populated: packed struct(u64) {340 };
341
342 pub fn populated(p: Populated) @This() {
343 return .{
344 .pop_off = @fromBackingInt(p.off),
345 .req_len = @fromBackingInt(p.len),
346 };
347 }
348
349 pub const Unwrapped = union(enum) {
350 unrequested,
351 requested,
352 populated: Populated,
353 };
354
355 pub const Populated = struct {
341 off: u32,356 off: u32,
342 len: u32,357 len: u32,
343 },358 };
359
360 pub fn unwrap(this: @This()) Unwrapped {
361 return switch (this.pop_off) {
362 .unpopulated => switch (this.req_len) {
363 .unrequested => .unrequested,
364 .requested => .requested,
365 _ => unreachable,
366 },
367 _ => .{ .populated = .{
368 .off = @backingInt(this.pop_off),
369 .len = @backingInt(this.req_len),
370 } },
371 };
372 }
344373
345 pub fn get(this: @This(), all_contents: []const u8) ?[]const u8 {374 pub fn get(this: @This(), all_contents: []const u8) ?[]const u8 {
346 return if (this.status.populated())375 return switch (this.unwrap()) {
347 all_contents[this.status.populated.off..][0..this.status.populated.len]376 .unrequested, .requested => null,
348 else377 .populated => |p| all_contents[p.off..][0..p.len],
349 null;378 };
350 }379 }
351 } align(@alignOf(u32)),380 },
352 /// `have_handle` determines whether this is populated.381 /// `have_handle` determines whether this is populated.
353 handle: union {382 handle: union {
354 file: Io.File,383 file: Io.File,
...@@ -369,14 +398,13 @@ pub const Manifest = struct {...@@ -369,14 +398,13 @@ pub const Manifest = struct {
369 return manifest.input_paths.items[@backingInt(i)];398 return manifest.input_paths.items[@backingInt(i)];
370 }399 }
371400
401 pub fn offset(i: @This(), manifest: *const Manifest) File.Offset {
402 return manifest.files.keys()[@backingInt(i)];
403 }
404
372 pub fn contents(i: @This(), manifest: *const Manifest) []const u8 {405 pub fn contents(i: @This(), manifest: *const Manifest) []const u8 {
373 const input_path = get(i, manifest);406 const input_path = get(i, manifest);
374 const populated = switch (input_path.contents.status) {407 return input_path.contents.get(manifest.all_input_content.items).?;
375 .unrequested => unreachable, // Must request contents before calling `check`.
376 .requested => unreachable, // Must call `check` first.
377 _ => input_path.contents.populated,
378 };
379 return manifest.all_input_content.items[populated.off..][0..populated.len];
380 }408 }
381 };409 };
382410
...@@ -454,7 +482,7 @@ pub const Manifest = struct {...@@ -454,7 +482,7 @@ pub const Manifest = struct {
454 comptime assert(@offsetOf(File, "path_start") - flags_off == 1);482 comptime assert(@offsetOf(File, "path_start") - flags_off == 1);
455 const hash_start = @backingInt(off) + flags_off;483 const hash_start = @backingInt(off) + flags_off;
456 const hash_end = mem.findScalarPos(u8, contents, hash_start, 0).?;484 const hash_end = mem.findScalarPos(u8, contents, hash_start, 0).?;
457 return contents[hash_start..hash_end];485 return contents[hash_start..hash_end :0];
458 }486 }
459487
460 pub fn pathFallible(off: File.Offset, contents: []const u8) error{InvalidFormat}![:0]const u8 {488 pub fn pathFallible(off: File.Offset, contents: []const u8) error{InvalidFormat}![:0]const u8 {
...@@ -464,7 +492,7 @@ pub const Manifest = struct {...@@ -464,7 +492,7 @@ pub const Manifest = struct {
464 }492 }
465493
466 pub fn path(off: File.Offset, contents: []const u8) [:0]const u8 {494 pub fn path(off: File.Offset, contents: []const u8) [:0]const u8 {
467 return pathFallible(contents, off) catch unreachable;495 return pathFallible(off, contents) catch unreachable;
468 }496 }
469 };497 };
470498
...@@ -501,7 +529,7 @@ pub const Manifest = struct {...@@ -501,7 +529,7 @@ pub const Manifest = struct {
501 return .{529 return .{
502 .size = file.size,530 .size = file.size,
503 .inode = file.inode,531 .inode = file.inode,
504 .mtime = file.mtime,532 .mtime = .fromNanoseconds(file.mtime),
505 };533 };
506 }534 }
507535
...@@ -664,9 +692,9 @@ pub const Manifest = struct {...@@ -664,9 +692,9 @@ pub const Manifest = struct {
664 existing_input_file.have_handle = true;692 existing_input_file.have_handle = true;
665 },693 },
666 }694 }
667 if (options.request_contents) switch (existing_input_file.contents.status) {695 if (options.request_contents) switch (existing_input_file.contents.unwrap()) {
668 .requested, .unrequested => existing_input_file.contents = .{ .status = .requested },696 .requested, .unrequested => existing_input_file.contents = .requested,
669 _ => {},697 .populated => {},
670 };698 };
671 const existing_header = m.files.keys()[gop.index].get(m.contents.items);699 const existing_header = m.files.keys()[gop.index].get(m.contents.items);
672 if (options.stat) |stat| {700 if (options.stat) |stat| {
...@@ -689,7 +717,7 @@ pub const Manifest = struct {...@@ -689,7 +717,7 @@ pub const Manifest = struct {
689 .file => |opt_file| if (opt_file) |file| .{ .file = file } else undefined,717 .file => |opt_file| if (opt_file) |file| .{ .file = file } else undefined,
690 .dir => |opt_dir| if (opt_dir) |dir| .{ .dir = dir } else undefined,718 .dir => |opt_dir| if (opt_dir) |dir| .{ .dir = dir } else undefined,
691 },719 },
692 .contents = .{ .status = if (options.request_contents) .requested else .unrequested },720 .contents = if (options.request_contents) .requested else .unrequested,
693 .have_digest = false,721 .have_digest = false,
694 .have_stat = options.stat != null,722 .have_stat = options.stat != null,
695 });723 });
...@@ -712,6 +740,7 @@ pub const Manifest = struct {...@@ -712,6 +740,7 @@ pub const Manifest = struct {
712 pub const CheckResult = union(enum) {740 pub const CheckResult = union(enum) {
713 hit,741 hit,
714 incomplete_manifest,742 incomplete_manifest,
743 invalid_manifest,
715 path_deleted: File.Offset,744 path_deleted: File.Offset,
716 directory_status_changed: File.Offset,745 directory_status_changed: File.Offset,
717 metadata_changed: File.Offset,746 metadata_changed: File.Offset,
...@@ -858,7 +887,7 @@ pub const Manifest = struct {...@@ -858,7 +887,7 @@ pub const Manifest = struct {
858 // We've just had a miss with the shared lock, and upgraded to an exclusive lock. Someone887 // We've just had a miss with the shared lock, and upgraded to an exclusive lock. Someone
859 // else might have modified the digest, so we need to check again before deciding to miss.888 // else might have modified the digest, so we need to check again before deciding to miss.
860 // Before trying again, we must reset `man.hash.hasher` and `man.files`.889 // Before trying again, we must reset `man.hash.hasher` and `man.files`.
861 // This is basically just the first half of `unhit`.890 // This is basically just the first half of `undoCheck`.
862 man.hash.hasher = hasher_init;891 man.hash.hasher = hasher_init;
863 man.hash.hasher.update(&input_digest);892 man.hash.hasher.update(&input_digest);
864 man.shrinkFilesToInput();893 man.shrinkFilesToInput();
...@@ -870,7 +899,7 @@ pub const Manifest = struct {...@@ -870,7 +899,7 @@ pub const Manifest = struct {
870 // Cache miss, but `checkLocked` guarantees that all input files have their digests computed, even on a899 // Cache miss, but `checkLocked` guarantees that all input files have their digests computed, even on a
871 // cache miss, which is needed because they will be used in the manifest digest.900 // cache miss, which is needed because they will be used in the manifest digest.
872 man.dirty = true;901 man.dirty = true;
873 unhit(man, &input_digest);902 undoCheck(man, &input_digest);
874 return miss_result;903 return miss_result;
875 }904 }
876905
...@@ -918,7 +947,7 @@ pub const Manifest = struct {...@@ -918,7 +947,7 @@ pub const Manifest = struct {
918 // contents on disk, and then later truncate the contents array.947 // contents on disk, and then later truncate the contents array.
919 //948 //
920 // The file on disk already supposedly includes the extra null byte that we have to maintain.949 // The file on disk already supposedly includes the extra null byte that we have to maintain.
921 const input_contents_len = m.contents.len;950 const input_contents_len = m.contents.items.len;
922 // After this resize, every return statement needs to modify m.contents length.951 // After this resize, every return statement needs to modify m.contents length.
923 try m.contents.resize(gpa, input_contents_len + manifest_size);952 try m.contents.resize(gpa, input_contents_len + manifest_size);
924 errdefer m.contents.shrinkRetainingCapacity(input_contents_len);953 errdefer m.contents.shrinkRetainingCapacity(input_contents_len);
...@@ -931,7 +960,7 @@ pub const Manifest = struct {...@@ -931,7 +960,7 @@ pub const Manifest = struct {
931 if (n != manifest_size) return checkLockedMiss(m, input_contents_len, .incomplete_manifest);960 if (n != manifest_size) return checkLockedMiss(m, input_contents_len, .incomplete_manifest);
932 }961 }
933 const disk_contents = m.contents.items[0..manifest_size];962 const disk_contents = m.contents.items[0..manifest_size];
934 const input_contents = m.contents.items[manifest_size..input_contents_len];963 const input_contents = m.contents.items[manifest_size..][0..input_contents_len];
935964
936 // First the input files section, which must match our input files, otherwise it's invalid or incomplete.965 // First the input files section, which must match our input files, otherwise it's invalid or incomplete.
937 var off: usize = 0;966 var off: usize = 0;
...@@ -955,14 +984,16 @@ pub const Manifest = struct {...@@ -955,14 +984,16 @@ pub const Manifest = struct {
955 // Validate and check discovered files.984 // Validate and check discovered files.
956 while (off + 1 < disk_contents.len) {985 while (off + 1 < disk_contents.len) {
957 const file_off: File.Offset = @fromBackingInt(@intCast(off));986 const file_off: File.Offset = @fromBackingInt(@intCast(off));
958 const file = try file_off.getFallible(disk_contents);987 const file = file_off.getFallible(disk_contents) catch
988 return checkLockedMiss(m, input_contents_len, .invalid_manifest);
959 if (file.flags.prefix >= m.cache.prefixes_len)989 if (file.flags.prefix >= m.cache.prefixes_len)
960 return checkLockedMiss(m, input_contents_len, .invalid_manifest);990 return checkLockedMiss(m, input_contents_len, .invalid_manifest);
961 const path = try file_off.pathFallible(disk_contents);991 const path = file_off.pathFallible(disk_contents) catch
992 return checkLockedMiss(m, input_contents_len, .invalid_manifest);
962 if (path.len == 0) return checkLockedMiss(m, input_contents_len, .invalid_manifest);993 if (path.len == 0) return checkLockedMiss(m, input_contents_len, .invalid_manifest);
963994
964 try m.files.putContext(gpa, file_off, {}, .{ .contents = disk_contents });995 try m.files.putContext(gpa, file_off, {}, .{ .contents = disk_contents });
965 const result = try checkDiscoveredPath(file_off, file_off.path(disk_contents));996 const result = try checkDiscoveredPath(m, file_off, disk_contents);
966 if (result != .hit) return checkLockedMiss(m, input_contents_len, result);997 if (result != .hit) return checkLockedMiss(m, input_contents_len, result);
967998
968 off += File.sizeOf(path.len);999 off += File.sizeOf(path.len);
...@@ -994,7 +1025,10 @@ pub const Manifest = struct {...@@ -994,7 +1025,10 @@ pub const Manifest = struct {
994 result: CheckResult,1025 result: CheckResult,
995 ) CheckError!CheckResult {1026 ) CheckError!CheckResult {
996 const file_offs = m.files.keys();1027 const file_offs = m.files.keys();
997 const off = if (file_offs.len - next_file_index == 0) input_contents_len else file_offs[next_file_index];1028 const off = if (file_offs.len - next_file_index == 0)
1029 input_contents_len
1030 else
1031 @backingInt(file_offs[next_file_index]);
998 const copy_len = input_contents_len - off;1032 const copy_len = input_contents_len - off;
999 @memcpy(1033 @memcpy(
1000 m.contents.items[off..][0..copy_len],1034 m.contents.items[off..][0..copy_len],
...@@ -1021,7 +1055,7 @@ pub const Manifest = struct {...@@ -1021,7 +1055,7 @@ pub const Manifest = struct {
1021 m: *Manifest,1055 m: *Manifest,
1022 file_off: File.Offset,1056 file_off: File.Offset,
1023 input_path: *InputPath,1057 input_path: *InputPath,
1024 contents: []const u8,1058 contents: []u8,
1025 ) CheckError!void {1059 ) CheckError!void {
1026 const cache = m.cache;1060 const cache = m.cache;
1027 const io = cache.io;1061 const io = cache.io;
...@@ -1031,7 +1065,10 @@ pub const Manifest = struct {...@@ -1031,7 +1065,10 @@ pub const Manifest = struct {
10311065
1032 if (input_path.have_digest) return;1066 if (input_path.have_digest) return;
10331067
1034 const stat_path_ok = input_path.contents.status.populated() or input_file.flags.metadata_only;1068 const stat_path_ok = switch (input_path.contents.unwrap()) {
1069 .populated => true,
1070 .unrequested, .requested => input_file.flags.metadata_only,
1071 };
1035 if (!input_path.have_stat and stat_path_ok) {1072 if (!input_path.have_stat and stat_path_ok) {
1036 // Since this is an input file, FileNotFound counts as a failure, not a cache miss.1073 // Since this is an input file, FileNotFound counts as a failure, not a cache miss.
1037 const actual_stat = switch (input_path.getHandle(input_file)) {1074 const actual_stat = switch (input_path.getHandle(input_file)) {
...@@ -1074,7 +1111,7 @@ pub const Manifest = struct {...@@ -1074,7 +1111,7 @@ pub const Manifest = struct {
1074 return;1111 return;
1075 }1112 }
10761113
1077 if (input_path.contents.get()) |file_or_dir_contents| {1114 if (input_path.contents.get(m.all_input_content.items)) |file_or_dir_contents| {
1078 assert(stat_path_ok);1115 assert(stat_path_ok);
1079 var hasher = hasher_init;1116 var hasher = hasher_init;
1080 hasher.update(file_or_dir_contents);1117 hasher.update(file_or_dir_contents);
...@@ -1122,12 +1159,14 @@ pub const Manifest = struct {...@@ -1122,12 +1159,14 @@ pub const Manifest = struct {
1122 .err = e,1159 .err = e,
1123 } }),1160 } }),
1124 };1161 };
1125 defer if (input_path.contents.status == .requested) {1162 defer switch (input_path.contents.unwrap()) {
1126 input_path.contents = .{ .populated = .{1163 .requested => input_path.contents = .populated(.{
1127 .off = @intCast(dir_contents_start),1164 .off = @intCast(dir_contents_start),
1128 .len = @intCast(m.all_input_content.items.len - dir_contents_start),1165 .len = @intCast(m.all_input_content.items.len - dir_contents_start),
1129 } };1166 }),
1130 } else m.all_input_content.shrinkRetainingCapacity(dir_contents_start);1167 .unrequested => m.all_input_content.shrinkRetainingCapacity(dir_contents_start),
1168 .populated => unreachable,
1169 };
1131 } else {1170 } else {
1132 const opened_file = if (input_path.have_handle)1171 const opened_file = if (input_path.have_handle)
1133 input_path.handle.file1172 input_path.handle.file
...@@ -1164,7 +1203,11 @@ pub const Manifest = struct {...@@ -1164,7 +1203,11 @@ pub const Manifest = struct {
1164 } }),1203 } }),
1165 };1204 };
11661205
1167 if (input_path.contents.status == .requested) @panic("TODO");1206 switch (input_path.contents.unwrap()) {
1207 .requested => @panic("TODO"),
1208 .unrequested => {},
1209 .populated => unreachable,
1210 }
1168 }1211 }
1169 }1212 }
11701213
...@@ -1173,8 +1216,8 @@ pub const Manifest = struct {...@@ -1173,8 +1216,8 @@ pub const Manifest = struct {
1173 m: *Manifest,1216 m: *Manifest,
1174 file_off: File.Offset,1217 file_off: File.Offset,
1175 input_path: *InputPath,1218 input_path: *InputPath,
1176 disk_contents: []const u8,1219 disk_contents: []u8,
1177 input_contents: []const u8,1220 input_contents: []u8,
1178 ) CheckError!CheckResult {1221 ) CheckError!CheckResult {
1179 const cache = m.cache;1222 const cache = m.cache;
1180 const io = cache.io;1223 const io = cache.io;
...@@ -1191,7 +1234,7 @@ pub const Manifest = struct {...@@ -1191,7 +1234,7 @@ pub const Manifest = struct {
1191 }1234 }
11921235
1193 if (input_path.have_stat) {1236 if (input_path.have_stat) {
1194 const changed = try disk_file.setStatChanged(m, input_file.stat);1237 const changed = try disk_file.setStatChanged(m, input_file.stat());
1195 if (!changed) return .hit;1238 if (!changed) return .hit;
1196 }1239 }
11971240
...@@ -1239,7 +1282,7 @@ pub const Manifest = struct {...@@ -1239,7 +1282,7 @@ pub const Manifest = struct {
1239 return .{ .metadata_changed = file_off };1282 return .{ .metadata_changed = file_off };
1240 }1283 }
12411284
1242 if (input_path.contents.get()) |file_or_dir_contents| {1285 if (input_path.contents.get(m.all_input_content.items)) |file_or_dir_contents| {
1243 var hasher = hasher_init;1286 var hasher = hasher_init;
1244 hasher.update(file_or_dir_contents);1287 hasher.update(file_or_dir_contents);
1245 hasher.final(&disk_file.digest);1288 hasher.final(&disk_file.digest);
...@@ -1287,12 +1330,14 @@ pub const Manifest = struct {...@@ -1287,12 +1330,14 @@ pub const Manifest = struct {
1287 .err = e,1330 .err = e,
1288 } }),1331 } }),
1289 };1332 };
1290 defer if (input_path.contents.status == .requested) {1333 defer switch (input_path.contents.unwrap()) {
1291 input_path.contents = .{ .populated = .{1334 .requested => input_path.contents = .populated(.{
1292 .off = @intCast(dir_contents_start),1335 .off = @intCast(dir_contents_start),
1293 .len = @intCast(m.all_input_content.items.len - dir_contents_start),1336 .len = @intCast(m.all_input_content.items.len - dir_contents_start),
1294 } };1337 }),
1295 } else m.all_input_content.shrinkRetainingCapacity(dir_contents_start);1338 .unrequested => m.all_input_content.shrinkRetainingCapacity(dir_contents_start),
1339 .populated => unreachable,
1340 };
12961341
1297 if (mem.eql(u8, &disk_file.digest, &input_file.digest)) return .hit;1342 if (mem.eql(u8, &disk_file.digest, &input_file.digest)) return .hit;
1298 return .{ .contents_changed = file_off };1343 return .{ .contents_changed = file_off };
...@@ -1330,30 +1375,30 @@ pub const Manifest = struct {...@@ -1330,30 +1375,30 @@ pub const Manifest = struct {
1330 .err = e,1375 .err = e,
1331 } }),1376 } }),
1332 };1377 };
1333 if (input_path.contents.status == .requested) @panic("TODO");1378 switch (input_path.contents.unwrap()) {
1379 .requested => @panic("TODO"),
1380 .unrequested => {},
1381 .populated => unreachable,
1382 }
13341383
1335 if (mem.eql(u8, &disk_file.digest, &input_file.digest)) return .hit;1384 if (mem.eql(u8, &disk_file.digest, &input_file.digest)) return .hit;
1336 return .{ .contents_changed = file_off };1385 return .{ .contents_changed = file_off };
1337 }1386 }
1338 }1387 }
13391388
1340 fn checkDiscoveredPath(1389 fn checkDiscoveredPath(m: *Manifest, file_off: File.Offset, contents: []u8) CheckError!CheckResult {
1341 m: *Manifest,
1342 file_off: File.Offset,
1343 file_path: [:0]const u8,
1344 contents: []const u8,
1345 ) CheckError!CheckResult {
1346 const file = file_off.get(contents);1390 const file = file_off.get(contents);
1347 const cache = m.cache;1391 const cache = m.cache;
1348 const gpa = cache.gpa;1392 const gpa = cache.gpa;
1349 const io = cache.io;1393 const io = cache.io;
1350 const parent_dir = cache.prefixes()[file.flags.prefix].handle;1394 const parent_dir = cache.prefixes()[file.flags.prefix].handle;
1395 const file_path = file_off.path(contents);
13511396
1352 if (file.flags.metadata_only) {1397 if (file.flags.metadata_only) {
1353 const actual_stat = parent_dir.statFile(io, file_path, .{}) catch |err| switch (err) {1398 const actual_stat = parent_dir.statFile(io, file_path, .{}) catch |err| switch (err) {
1354 error.FileNotFound => return .{ .path_deleted = file_off },1399 error.FileNotFound => return .{ .path_deleted = file_off },
1355 error.Canceled => |e| return e,1400 error.Canceled => |e| return e,
1356 else => |e| return fail(m, .{ .file_stat = .{1401 else => |e| return fail(&m.diagnostic, .{ .file_stat = .{
1357 .file_offset = file_off,1402 .file_offset = file_off,
1358 .err = e,1403 .err = e,
1359 } }),1404 } }),
...@@ -1376,7 +1421,7 @@ pub const Manifest = struct {...@@ -1376,7 +1421,7 @@ pub const Manifest = struct {
1376 error.FileNotFound => return .{ .path_deleted = file_off },1421 error.FileNotFound => return .{ .path_deleted = file_off },
1377 error.NotDir => return .{ .directory_status_changed = file_off },1422 error.NotDir => return .{ .directory_status_changed = file_off },
1378 error.Canceled => |e| return e,1423 error.Canceled => |e| return e,
1379 else => |e| return fail(m, .{ .file_open = .{1424 else => |e| return fail(&m.diagnostic, .{ .file_open = .{
1380 .file_offset = file_off,1425 .file_offset = file_off,
1381 .err = e,1426 .err = e,
1382 } }),1427 } }),
...@@ -1385,7 +1430,7 @@ pub const Manifest = struct {...@@ -1385,7 +1430,7 @@ pub const Manifest = struct {
13851430
1386 const actual_stat = opened_dir.stat(io) catch |err| switch (err) {1431 const actual_stat = opened_dir.stat(io) catch |err| switch (err) {
1387 error.Canceled => |e| return e,1432 error.Canceled => |e| return e,
1388 else => |e| return fail(m, .{ .file_stat = .{1433 else => |e| return fail(&m.diagnostic, .{ .file_stat = .{
1389 .file_offset = file_off,1434 .file_offset = file_off,
1390 .err = e,1435 .err = e,
1391 } }),1436 } }),
...@@ -1394,9 +1439,9 @@ pub const Manifest = struct {...@@ -1394,9 +1439,9 @@ pub const Manifest = struct {
1394 const prev_digest: BinDigest = file.digest;1439 const prev_digest: BinDigest = file.digest;
1395 const dir_contents_start = m.all_input_content.items.len;1440 const dir_contents_start = m.all_input_content.items.len;
1396 defer m.all_input_content.shrinkRetainingCapacity(dir_contents_start);1441 defer m.all_input_content.shrinkRetainingCapacity(dir_contents_start);
1397 hashDir(gpa, io, opened_dir, &file.digest, &m.all_input_contents) catch |err| switch (err) {1442 hashDir(gpa, io, opened_dir, &file.digest, &m.all_input_content) catch |err| switch (err) {
1398 error.Canceled, error.OutOfMemory => |e| return e,1443 error.Canceled, error.OutOfMemory => |e| return e,
1399 else => |e| return fail(m, .{ .file_read = .{1444 else => |e| return fail(&m.diagnostic, .{ .file_read = .{
1400 .file_offset = file_off,1445 .file_offset = file_off,
1401 .err = e,1446 .err = e,
1402 } }),1447 } }),
...@@ -1411,7 +1456,7 @@ pub const Manifest = struct {...@@ -1411,7 +1456,7 @@ pub const Manifest = struct {
1411 error.FileNotFound => return .{ .path_deleted = file_off },1456 error.FileNotFound => return .{ .path_deleted = file_off },
1412 error.IsDir => return .{ .directory_status_changed = file_off },1457 error.IsDir => return .{ .directory_status_changed = file_off },
1413 error.Canceled => |e| return e,1458 error.Canceled => |e| return e,
1414 else => |e| return fail(m, .{ .file_open = .{1459 else => |e| return fail(&m.diagnostic, .{ .file_open = .{
1415 .file_offset = file_off,1460 .file_offset = file_off,
1416 .err = e,1461 .err = e,
1417 } }),1462 } }),
...@@ -1420,7 +1465,7 @@ pub const Manifest = struct {...@@ -1420,7 +1465,7 @@ pub const Manifest = struct {
14201465
1421 const actual_stat = opened_file.stat(io) catch |err| switch (err) {1466 const actual_stat = opened_file.stat(io) catch |err| switch (err) {
1422 error.Canceled => |e| return e,1467 error.Canceled => |e| return e,
1423 else => |e| return fail(m, .{ .file_stat = .{1468 else => |e| return fail(&m.diagnostic, .{ .file_stat = .{
1424 .file_offset = file_off,1469 .file_offset = file_off,
1425 .err = e,1470 .err = e,
1426 } }),1471 } }),
...@@ -1430,7 +1475,7 @@ pub const Manifest = struct {...@@ -1430,7 +1475,7 @@ pub const Manifest = struct {
1430 const prev_digest: BinDigest = file.digest;1475 const prev_digest: BinDigest = file.digest;
1431 hashFile(io, opened_file, &file.digest) catch |err| switch (err) {1476 hashFile(io, opened_file, &file.digest) catch |err| switch (err) {
1432 error.Canceled => |e| return e,1477 error.Canceled => |e| return e,
1433 else => |e| return fail(m, .{ .file_read = .{1478 else => |e| return fail(&m.diagnostic, .{ .file_read = .{
1434 .file_offset = file_off,1479 .file_offset = file_off,
1435 .err = e,1480 .err = e,
1436 } }),1481 } }),
...@@ -1453,7 +1498,7 @@ pub const Manifest = struct {...@@ -1453,7 +1498,7 @@ pub const Manifest = struct {
1453 /// not including discovered files).1498 /// not including discovered files).
1454 ///1499 ///
1455 /// Assumes that `digest` is populated for all input files.1500 /// Assumes that `digest` is populated for all input files.
1456 pub fn unhit(man: *Manifest, input_digest: *const BinDigest) void {1501 pub fn undoCheck(man: *Manifest, input_digest: *const BinDigest) void {
1457 // Reset the hash.1502 // Reset the hash.
1458 man.hash.hasher = hasher_init;1503 man.hash.hasher = hasher_init;
1459 man.hash.hasher.update(input_digest);1504 man.hash.hasher.update(input_digest);
...@@ -2117,8 +2162,7 @@ test "cache file and then recall it" {...@@ -2117,8 +2162,7 @@ test "cache file and then recall it" {
2117 ch.hash.addBytes("1234");2162 ch.hash.addBytes("1234");
2118 _ = try ch.addInputPath(.initCwd(temp_file), .{});2163 _ = try ch.addInputPath(.initCwd(temp_file), .{});
21192164
2120 // There should be nothing in the cache2165 try testing.expectEqual(.incomplete_manifest, try ch.check(.none));
2121 try testing.expectEqual(.miss, try ch.check(.none));
21222166
2123 digest1 = ch.final();2167 digest1 = ch.final();
2124 try ch.finalize();2168 try ch.finalize();
...@@ -2185,8 +2229,7 @@ test "check that changing a file makes cache fail" {...@@ -2185,8 +2229,7 @@ test "check that changing a file makes cache fail" {
2185 man.hash.addBytes("1234");2229 man.hash.addBytes("1234");
2186 const temp_file_idx = try man.addInputPath(.initCwd(temp_file), .{ .request_contents = true });2230 const temp_file_idx = try man.addInputPath(.initCwd(temp_file), .{ .request_contents = true });
21872231
2188 // There should be nothing in the cache2232 try testing.expectEqual(.incomplete_manifest, try man.check(.none));
2189 try testing.expectEqual(.miss, try man.check(.none));
21902233
2191 try testing.expectEqualStrings(original_temp_file_contents, temp_file_idx.contents(&man));2234 try testing.expectEqualStrings(original_temp_file_contents, temp_file_idx.contents(&man));
21922235
...@@ -2204,11 +2247,13 @@ test "check that changing a file makes cache fail" {...@@ -2204,11 +2247,13 @@ test "check that changing a file makes cache fail" {
2204 man.hash.addBytes("1234");2247 man.hash.addBytes("1234");
2205 const temp_file_idx = try man.addInputPath(.initCwd(temp_file), .{ .request_contents = true });2248 const temp_file_idx = try man.addInputPath(.initCwd(temp_file), .{ .request_contents = true });
22062249
2207 // A file that we depend on has been updated, so the cache should not contain an entry for it2250 // The one input file changed.
2208 try testing.expectEqual(.miss, try man.check(.none));2251 try testing.expectEqual(
2252 @as(Manifest.CheckResult, .{ .contents_changed = temp_file_idx.offset(&man) }),
2253 try man.check(.none),
2254 );
22092255
2210 // The cache system does not keep the contents of re-hashed input files.2256 try testing.expectEqualStrings(updated_temp_file_contents, temp_file_idx.contents(&man));
2211 try testing.expectEqual(false, temp_file_idx.get(&man).contents.status.populated());
22122257
2213 digest2 = man.final();2258 digest2 = man.final();
22142259
...@@ -2248,8 +2293,7 @@ test "no file inputs" {...@@ -2248,8 +2293,7 @@ test "no file inputs" {
22482293
2249 man.hash.addBytes("1234");2294 man.hash.addBytes("1234");
22502295
2251 // There should be nothing in the cache2296 try testing.expectEqual(.incomplete_manifest, try man.check(.none));
2252 try testing.expectEqual(.miss, try man.check(.none));
22532297
2254 digest1 = man.final();2298 digest1 = man.final();
22552299
...@@ -2306,31 +2350,30 @@ test "Manifest with files added after initial hash work" {...@@ -2306,31 +2350,30 @@ test "Manifest with files added after initial hash work" {
2306 defer cache.manifest_dir.close(io);2350 defer cache.manifest_dir.close(io);
23072351
2308 {2352 {
2309 var ch = cache.obtain();2353 var man = cache.obtain();
2310 defer ch.deinit();2354 defer man.deinit();
23112355
2312 ch.hash.addBytes("1234");2356 man.hash.addBytes("1234");
2313 _ = try ch.addInputPath(.initCwd(temp_file1), .{});2357 _ = try man.addInputPath(.initCwd(temp_file1), .{});
23142358
2315 // There should be nothing in the cache2359 try testing.expectEqual(.incomplete_manifest, try man.check(.none));
2316 try testing.expectEqual(.miss, try ch.check(.none));
23172360
2318 _ = try ch.addDiscoveredPath(.{ .discovered_path = .{ .unresolved = .initCwd(temp_file2) } });2361 try man.addDiscoveredPath(.{ .discovered_path = .{ .unresolved = .initCwd(temp_file2) } });
23192362
2320 digest1 = ch.final();2363 digest1 = man.final();
2321 try ch.finalize();2364 try man.finalize();
2322 }2365 }
2323 {2366 {
2324 var ch = cache.obtain();2367 var man = cache.obtain();
2325 defer ch.deinit();2368 defer man.deinit();
23262369
2327 ch.hash.addBytes("1234");2370 man.hash.addBytes("1234");
2328 _ = try ch.addInputPath(.initCwd(temp_file1), .{});2371 _ = try man.addInputPath(.initCwd(temp_file1), .{});
23292372
2330 try testing.expect(.hit == try ch.check(.none));2373 try testing.expect(.hit == try man.check(.none));
2331 digest2 = ch.final();2374 digest2 = man.final();
23322375
2333 try testing.expectEqual(false, ch.have_exclusive_lock);2376 try testing.expectEqual(false, man.have_exclusive_lock);
2334 }2377 }
2335 try testing.expect(mem.eql(u8, &digest1, &digest2));2378 try testing.expect(mem.eql(u8, &digest1, &digest2));
23362379
...@@ -2344,20 +2387,24 @@ test "Manifest with files added after initial hash work" {...@@ -2344,20 +2387,24 @@ test "Manifest with files added after initial hash work" {
2344 }2387 }
23452388
2346 {2389 {
2347 var ch = cache.obtain();2390 var man = cache.obtain();
2348 defer ch.deinit();2391 defer man.deinit();
23492392
2350 ch.hash.addBytes("1234");2393 man.hash.addBytes("1234");
2351 _ = try ch.addInputPath(.initCwd(temp_file1), .{});2394 _ = try man.addInputPath(.initCwd(temp_file1), .{});
23522395
2353 // A file that we depend on has been updated, so the cache should not contain an entry for it2396 switch (try man.check(.none)) {
2354 try testing.expectEqual(.miss, try ch.check(.none));2397 .contents_changed => |off| {
2398 try testing.expectEqualStrings(temp_file2, off.path(man.contents.items));
2399 },
2400 else => return error.TestFailed,
2401 }
23552402
2356 _ = try ch.addDiscoveredPath(.{ .discovered_path = .{ .unresolved = .initCwd(temp_file2) } });2403 try man.addDiscoveredPath(.{ .discovered_path = .{ .unresolved = .initCwd(temp_file2) } });
23572404
2358 digest3 = ch.final();2405 digest3 = man.final();
23592406
2360 try ch.finalize();2407 try man.finalize();
2361 }2408 }
23622409
2363 try testing.expect(!mem.eql(u8, &digest1, &digest3));2410 try testing.expect(!mem.eql(u8, &digest1, &digest3));
src/Compilation.zig+8-12
...@@ -2856,7 +2856,7 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) UpdateE...@@ -2856,7 +2856,7 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) UpdateE
2856 log.debug("CacheMode.whole cache miss for {s}", .{comp.root_name});2856 log.debug("CacheMode.whole cache miss for {s}", .{comp.root_name});
28572857
2858 if (ignore_hit) {2858 if (ignore_hit) {
2859 // Okay, now set this back so that `writeManifest` will downgrade our lock later.2859 // Okay, now set this back so that `Manifest.finalize` will downgrade our lock later.
2860 man.want_shared_lock = true;2860 man.want_shared_lock = true;
2861 }2861 }
28622862
...@@ -3144,7 +3144,7 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) UpdateE...@@ -3144,7 +3144,7 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) UpdateE
3144 }3144 }
31453145
3146 // Failure here only means an unnecessary cache miss.3146 // Failure here only means an unnecessary cache miss.
3147 man.writeManifest() catch |err| log.warn("failed to write cache manifest: {t}", .{err});3147 man.finalize() catch |err| log.warn("failed to write cache manifest: {t}", .{err});
31483148
3149 assert(whole.lock == null);3149 assert(whole.lock == null);
3150 whole.lock = man.toOwnedLock();3150 whole.lock = man.toOwnedLock();
...@@ -5810,11 +5810,8 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr...@@ -5810,11 +5810,8 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr
5810 // possible we had a hit and the manifest is dirty, for example if the file mtime changed but5810 // possible we had a hit and the manifest is dirty, for example if the file mtime changed but
5811 // the contents were the same, we hit the cache but the manifest is dirty and we need to update5811 // the contents were the same, we hit the cache but the manifest is dirty and we need to update
5812 // it to prevent doing a full file content comparison the next time around.5812 // it to prevent doing a full file content comparison the next time around.
5813 man.writeManifest() catch |err| {5813 man.finalize() catch |err|
5814 log.warn("failed to write cache manifest when compiling '{s}': {s}", .{5814 log.warn("failed to write cache manifest when compiling {q}: {t}", .{ c_object.src.src_path, err });
5815 c_object.src.src_path, @errorName(err),
5816 });
5817 };
5818 }5815 }
58195816
5820 const o_basename = try std.fmt.allocPrint(arena, "{s}{s}", .{ o_basename_noext, o_ext });5817 const o_basename = try std.fmt.allocPrint(arena, "{s}{s}", .{ o_basename_noext, o_ext });
...@@ -5950,9 +5947,8 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32...@@ -5950,9 +5947,8 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32
5950 };5947 };
59515948
5952 if (man.have_exclusive_lock) {5949 if (man.have_exclusive_lock) {
5953 man.writeManifest() catch |err| {5950 man.finalize() catch |err|
5954 log.warn("failed to write cache manifest when compiling '{s}': {s}", .{ src_path, @errorName(err) });5951 log.warn("failed to write cache manifest when compiling {q}: {t}", .{ src_path, err });
5955 };
5956 }5952 }
59575953
5958 win32_resource.status = .{5954 win32_resource.status = .{
...@@ -6060,8 +6056,8 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32...@@ -6060,8 +6056,8 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32
6060 // possible we had a hit and the manifest is dirty, for example if the file mtime changed but6056 // possible we had a hit and the manifest is dirty, for example if the file mtime changed but
6061 // the contents were the same, we hit the cache but the manifest is dirty and we need to update6057 // the contents were the same, we hit the cache but the manifest is dirty and we need to update
6062 // it to prevent doing a full file content comparison the next time around.6058 // it to prevent doing a full file content comparison the next time around.
6063 man.writeManifest() catch |err| {6059 man.finalize() catch |err| {
6064 log.warn("failed to write cache manifest when compiling '{s}': {s}", .{ rc_src.src_path, @errorName(err) });6060 log.warn("failed to write cache manifest when compiling {q}: {t}", .{ rc_src.src_path, err });
6065 };6061 };
6066 }6062 }
60676063
src/libs/freebsd.zig+1-3
...@@ -982,9 +982,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye...@@ -982,9 +982,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
982 try buildSharedLib(comp, arena, o_directory, asm_file_basename, lib, prog_node);982 try buildSharedLib(comp, arena, o_directory, asm_file_basename, lib, prog_node);
983 }983 }
984984
985 man.writeManifest() catch |err| {985 man.finalize() catch |err| log.warn("failed to write cache manifest for FreeBSD libc stubs: {t}", .{err});
986 log.warn("failed to write cache manifest for FreeBSD libc stubs: {s}", .{@errorName(err)});
987 };
988986
989 return queueSharedObjects(comp, .{987 return queueSharedObjects(comp, .{
990 .lock = man.toOwnedLock(),988 .lock = man.toOwnedLock(),
src/libs/glibc.zig+1-3
...@@ -1131,9 +1131,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye...@@ -1131,9 +1131,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
1131 try buildSharedLib(comp, arena, o_directory, asm_file_basename, lib, prog_node);1131 try buildSharedLib(comp, arena, o_directory, asm_file_basename, lib, prog_node);
1132 }1132 }
11331133
1134 man.writeManifest() catch |err| {1134 man.finalize() catch |err| log.warn("failed to write cache manifest for glibc stubs: {t}", .{err});
1135 log.warn("failed to write cache manifest for glibc stubs: {s}", .{@errorName(err)});
1136 };
11371135
1138 return queueSharedObjects(comp, .{1136 return queueSharedObjects(comp, .{
1139 .lock = man.toOwnedLock(),1137 .lock = man.toOwnedLock(),
src/libs/mingw.zig+2-3
...@@ -363,9 +363,8 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8, prog_node: std.P...@@ -363,9 +363,8 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8, prog_node: std.P
363 try file_writer.interface.flush();363 try file_writer.interface.flush();
364 }364 }
365365
366 man.writeManifest() catch |err| {366 man.finalize() catch |err|
367 log.warn("failed to write cache manifest for DLL import {s}.lib: {s}", .{ lib_name, @errorName(err) });367 log.warn("failed to write cache manifest for DLL import {s}.lib: {t}", .{ lib_name, err });
368 };
369368
370 comp.mutex.lockUncancelable(io);369 comp.mutex.lockUncancelable(io);
371 defer comp.mutex.unlock(io);370 defer comp.mutex.unlock(io);
src/libs/netbsd.zig+1-3
...@@ -643,9 +643,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye...@@ -643,9 +643,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
643 try buildSharedLib(comp, arena, o_directory, asm_file_basename, lib, prog_node);643 try buildSharedLib(comp, arena, o_directory, asm_file_basename, lib, prog_node);
644 }644 }
645645
646 man.writeManifest() catch |err| {646 man.finalize() catch |err| log.warn("failed to write cache manifest for NetBSD libc stubs: {t}", .{err});
647 log.warn("failed to write cache manifest for NetBSD libc stubs: {s}", .{@errorName(err)});
648 };
649647
650 return queueSharedObjects(comp, .{648 return queueSharedObjects(comp, .{
651 .lock = man.toOwnedLock(),649 .lock = man.toOwnedLock(),
src/libs/openbsd.zig+1-3
...@@ -564,9 +564,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye...@@ -564,9 +564,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
564 try buildSharedLib(comp, arena, o_directory, asm_file_basename, lib, prog_node);564 try buildSharedLib(comp, arena, o_directory, asm_file_basename, lib, prog_node);
565 }565 }
566566
567 man.writeManifest() catch |err| {567 man.finalize() catch |err| log.warn("failed to write cache manifest for OpenBSD libc stubs: {t}", .{err});
568 log.warn("failed to write cache manifest for OpenBSD libc stubs: {s}", .{@errorName(err)});
569 };
570568
571 return queueSharedObjects(comp, .{569 return queueSharedObjects(comp, .{
572 .lock = man.toOwnedLock(),570 .lock = man.toOwnedLock(),
src/main.zig+1-1
...@@ -4906,7 +4906,7 @@ fn cmdTranslateC(...@@ -4906,7 +4906,7 @@ fn cmdTranslateC(
4906 }4906 }
4907 }4907 }
49084908
4909 man.writeManifest() catch |err| warn("failed to write cache manifest: {t}", .{err});4909 man.finalize() catch |err| warn("failed to write cache manifest: {t}", .{err});
4910 break :result result;4910 break :result result;
4911 };4911 };
49124912