authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-09-03 19:19:24-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-09-04 17:42:22-07:00
log1c31826ef78783918c9af9a2608895b786d004a4
treeb2cb04ffd25b2d4831f1385c06677be5cf9d7ddb
parent61e2e70b1e8c3e3ee9b6f524187c4453308f98f5

std.Build.Cache: fix adding files

no longer adding unwanted padding bytes

3 files changed, 41 insertions(+), 47 deletions(-)

lib/std/Build.zig+8-4
......@@ -58,7 +58,8 @@ available_deps: AvailableDeps,
5858
5959pub const ConfigureDependency = struct {
6060 lazy_path: LazyPath,
61 mode: std.Build.Configuration.PathDep.Mode,
61 is_directory: bool,
62 metadata_only: bool,
6263};
6364
6465pub const ReleaseMode = enum {
......@@ -102,7 +103,8 @@ pub const Graph = struct {
102103 /// Populated by calling one of:
103104 /// * `dependOnFileContents`
104105 /// * `dependOnFileMetadata`
105 /// * `dependOnDirectory`
106 /// * `dependOnDirectoryContents`
107 /// * `dependOnDirectoryMetadata`
106108 configure_dependencies: ArrayList(ConfigureDependency) = .empty,
107109
108110 /// If the cache is poisoned means that the **configure logic** had side
......@@ -2602,7 +2604,8 @@ pub fn dependOnFileContents(b: *Build, lazy_path: LazyPath) void {
26022604 const graph = b.graph;
26032605 graph.configure_dependencies.append(graph.arena, .{
26042606 .lazy_path = lazy_path.dupe(graph),
2605 .mode = .contents,
2607 .is_directory = false,
2608 .metadata_only = false,
26062609 }) catch @panic("OOM");
26072610}
26082611
......@@ -2627,7 +2630,8 @@ pub fn dependOnFileMetadata(b: *Build, lazy_path: LazyPath) void {
26272630 const graph = b.graph;
26282631 graph.configure_dependencies.append(graph.arena, .{
26292632 .lazy_path = lazy_path.dupe(graph),
2630 .mode = .metadata,
2633 .is_directory = false,
2634 .metadata_only = true,
26312635 }) catch @panic("OOM");
26322636}
26332637
lib/std/Build/Cache.zig+31-42
......@@ -363,9 +363,9 @@ pub const Manifest = struct {
363363 pub const File = extern struct {
364364 size: u64,
365365 inode: u64,
366 digest: BinDigest,
367366 /// Nanoseconds.
368367 mtime: i64,
368 digest: BinDigest,
369369 /// Starting with this field and continuing into the path, excluding the null byte,
370370 /// is the string that is hashed for the manifest digest.
371371 flags: Flags,
......@@ -546,35 +546,29 @@ pub const Manifest = struct {
546546 pub fn addInputPath(m: *Manifest, path: Path, options: AddInputPathOptions) Allocator.Error!InputPath.Index {
547547 const cache = m.cache;
548548 const gpa = cache.gpa;
549 const is_directory = options.handle.isDirectory();
550
549551 try m.files.ensureUnusedCapacityContext(gpa, 1, .{ .contents = m.contents.items });
550552 try m.input_paths.ensureUnusedCapacity(gpa, 1);
551553
552 const prev_contents_len = m.contents.items.len;
553 const header: *File = @ptrCast(@alignCast(try m.contents.addManyAsSlice(gpa, @sizeOf(File))));
554 errdefer m.contents.shrinkRetainingCapacity(prev_contents_len);
554 const new_file_offset: File.Offset = @fromBackingInt(@intCast(m.contents.items.len));
555 try m.contents.appendNTimes(gpa, 0, @offsetOf(File, "path_start"));
556 errdefer m.contents.shrinkRetainingCapacity(@backingInt(new_file_offset));
555557
556 header.* = .{
557 .flags = .{
558 .prefix = try cache.resolveAppendPath(&m.contents, path),
559 .is_directory = options.handle.isDirectory(),
560 .metadata_only = options.metadata_only,
561 },
562 .size = undefined,
563 .inode = undefined,
564 .mtime = undefined,
565 .digest = undefined,
566 .path_start = .{},
567 };
558 const new_prefix = try cache.resolveAppendPath(&m.contents, path);
568559 assert(mem.isAligned(m.contents.items.len, @alignOf(File)));
560 new_file_offset.get(m.contents.items).flags = .{
561 .prefix = new_prefix,
562 .is_directory = is_directory,
563 .metadata_only = options.metadata_only,
564 };
569565
570 const gop = m.files.getOrPutAssumeCapacityContext(@fromBackingInt(@intCast(prev_contents_len)), .{
571 .contents = m.contents.items,
572 });
566 const gop = m.files.getOrPutAssumeCapacityContext(new_file_offset, .{ .contents = m.contents.items });
573567 m.files.lockPointers();
574568 defer m.files.unlockPointers();
575569
576570 if (gop.found_existing) {
577 m.contents.shrinkRetainingCapacity(prev_contents_len);
571 m.contents.shrinkRetainingCapacity(@backingInt(new_file_offset));
578572 const existing_input_file = &m.input_paths.items[gop.index];
579573 switch (options.handle) {
580574 .file => |opt_file| if (opt_file) |file| {
......@@ -600,7 +594,7 @@ pub const Manifest = struct {
600594 // If it trips, the same file path has been added to the cache
601595 // manifest both as a directory and as a normal file, making the
602596 // intended caching behavior ambiguous.
603 assert(existing_header.flags.is_directory == options.handle.isDirectory());
597 assert(existing_header.flags.is_directory == is_directory);
604598 if (!options.metadata_only)
605599 existing_header.flags.metadata_only = false;
606600 } else {
......@@ -617,6 +611,7 @@ pub const Manifest = struct {
617611 });
618612 assert(m.input_paths.items.len - 1 == gop.index);
619613 if (options.stat) |stat| {
614 const header = new_file_offset.get(m.contents.items);
620615 header.size = stat.size;
621616 header.inode = stat.inode;
622617 header.mtime = @intCast(stat.mtime.toNanoseconds());
......@@ -1134,33 +1129,25 @@ pub const Manifest = struct {
11341129 try m.files.ensureUnusedCapacityContext(gpa, 1, .{ .contents = m.contents.items });
11351130
11361131 const new_file_offset: File.Offset = @fromBackingInt(@intCast(m.contents.items.len));
1137 const new_header: *File = @ptrCast(@alignCast(try m.contents.addManyAsSlice(gpa, @sizeOf(File))));
1132 try m.contents.appendNTimes(gpa, 0, @offsetOf(File, "path_start"));
11381133 errdefer m.contents.shrinkRetainingCapacity(@backingInt(new_file_offset));
11391134
1140 new_header.* = .{
1141 .flags = .{
1142 .prefix = switch (options.path) {
1143 .unresolved => |unresolved| try cache.resolveAppendPath(&m.contents, unresolved),
1144 .prefixed => |prefixed| try cache.appendPrefixedPath(&m.contents, prefixed),
1145 },
1146 .is_directory = is_directory,
1147 .metadata_only = options.metadata_only,
1148 },
1149 .size = undefined,
1150 .inode = undefined,
1151 .mtime = undefined,
1152 .digest = @splat(0),
1153 .path_start = .{},
1135 const new_prefix = switch (options.path) {
1136 .unresolved => |unresolved| try cache.resolveAppendPath(&m.contents, unresolved),
1137 .prefixed => |prefixed| try cache.appendPrefixedPath(&m.contents, prefixed),
11541138 };
11551139 assert(mem.isAligned(m.contents.items.len, @alignOf(File)));
1140 new_file_offset.get(m.contents.items).flags = .{
1141 .prefix = new_prefix,
1142 .is_directory = is_directory,
1143 .metadata_only = options.metadata_only,
1144 };
11561145
1157 const gop = m.files.getOrPutAssumeCapacityContext(new_file_offset, .{
1158 .contents = m.contents.items,
1159 });
1146 const gop = m.files.getOrPutAssumeCapacityContext(new_file_offset, .{ .contents = m.contents.items });
11601147 m.files.lockPointers();
11611148 defer m.files.unlockPointers();
11621149
1163 const header, const file_offset = if (gop.found_existing) h: {
1150 const file_offset = if (gop.found_existing) h: {
11641151 m.contents.shrinkRetainingCapacity(@backingInt(new_file_offset));
11651152 const existing_off = gop.key_ptr.*;
11661153 const header = existing_off.get(m.contents.items);
......@@ -1170,8 +1157,10 @@ pub const Manifest = struct {
11701157 assert(header.flags.is_directory == is_directory);
11711158 if (!options.metadata_only)
11721159 header.flags.metadata_only = false;
1173 break :h .{ header, existing_off };
1174 } else .{ new_header, new_file_offset };
1160 break :h existing_off;
1161 } else new_file_offset;
1162
1163 const header = file_offset.get(m.contents.items);
11751164
11761165 if (options.stat) |stat| {
11771166 try header.setStat(m, stat);
lib/std/Build/Serialize.zig+2-1
......@@ -34,7 +34,8 @@ pub fn write(b: *std.Build, wc: *Configuration.Wip, writer: *std.Io.Writer) !voi
3434 .cwd_relative => .cwd,
3535 .relative => |r| r.base,
3636 },
37 .mode = src.mode,
37 .is_directory = src.is_directory,
38 .metadata_only = src.metadata_only,
3839 },
3940 .sub = switch (src.lazy_path) {
4041 .src_path => |sp| try wc.addString(sp.sub_path),