authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-06-29 23:48:35-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-06-29 23:50:20-07:00
log779b6cc63cbf1ab0f132996506a238eae72dcbf9
treee42c3573b14e21ceec05c9360d63dc9325a60a0e
parentfc7924d393c909fef785614b8273e719398db2c1

Maker: partially implement configurer cache invalidation

progress towards #35473

7 files changed, 78 insertions(+), 34 deletions(-)

build.zig+1-1
......@@ -268,7 +268,7 @@ pub fn build(b: *std.Build) !void {
268268 }
269269
270270 // Ensure git version changes get picked up.
271 b.dependOnFileContents(b.graph.path(.build_root, ".git/HEAD"));
271 b.dependOnFileContents(b.path(".git/HEAD"));
272272
273273 const version_string = b.fmt("{d}.{d}.{d}", .{ zig_version.major, zig_version.minor, zig_version.patch });
274274
lib/compiler/Maker.zig+50-11
......@@ -1318,7 +1318,11 @@ fn configure(graph: *Graph, options: ConfigureOptions) !ScannedConfig {
13181318 }
13191319
13201320 for (configuration.path_deps) |path_dep| {
1321 try config_man.addPathPost(path_dep.toCachePath(&configuration, arena));
1321 switch (path_dep.flags.mode) {
1322 .directory => {}, // TODO
1323 .contents => try config_man.addPathPost(confPathDepToCachePath(graph, &configuration, path_dep)),
1324 .metadata => {}, // TODO
1325 }
13221326 }
13231327
13241328 // If it is poisoned, there is no point in moving it to cached
......@@ -1825,7 +1829,7 @@ fn cmdInit(gpa: Allocator, graph: *Graph, args: []const []const u8) !void {
18251829 return process.cleanExit(io);
18261830 },
18271831 .minimal => {
1828 writeSimpleTemplateFile(io, Package.Manifest.basename,
1832 Templates.writeSimpleFile(io, Package.Manifest.basename,
18291833 \\.{{
18301834 \\ .name = .{s},
18311835 \\ .version = "0.0.1",
......@@ -1842,7 +1846,7 @@ fn cmdInit(gpa: Allocator, graph: *Graph, args: []const []const u8) !void {
18421846 else => fatal("failed to create {q}: {t}", .{ Package.Manifest.basename, err }),
18431847 error.PathAlreadyExists => fatal("refusing to overwrite {q}", .{Package.Manifest.basename}),
18441848 };
1845 writeSimpleTemplateFile(io, default_build_zig_basename,
1849 Templates.writeSimpleFile(io, default_build_zig_basename,
18461850 \\const std = @import("std");
18471851 \\
18481852 \\pub fn build(b: *std.Build) void {{
......@@ -3498,7 +3502,7 @@ fn loadManifest(
34983502 0,
34993503 ) catch |err| switch (err) {
35003504 error.FileNotFound => {
3501 writeSimpleTemplateFile(io, Package.Manifest.basename,
3505 Templates.writeSimpleFile(io, Package.Manifest.basename,
35023506 \\.{{
35033507 \\ .name = .{s},
35043508 \\ .version = "{s}",
......@@ -3658,12 +3662,47 @@ const Templates = struct {
36583662 .buffer = std.array_list.Managed(u8).init(gpa),
36593663 };
36603664 }
3665
3666 fn writeSimpleFile(io: Io, file_name: []const u8, comptime format: []const u8, args: anytype) !void {
3667 const f = try Io.Dir.cwd().createFile(io, file_name, .{ .exclusive = true });
3668 defer f.close(io);
3669 var buf: [4096]u8 = undefined;
3670 var fw = f.writer(io, &buf);
3671 try fw.interface.print(format, args);
3672 try fw.interface.flush();
3673 }
36613674};
3662fn writeSimpleTemplateFile(io: Io, file_name: []const u8, comptime format: []const u8, args: anytype) !void {
3663 const f = try Io.Dir.cwd().createFile(io, file_name, .{ .exclusive = true });
3664 defer f.close(io);
3665 var buf: [4096]u8 = undefined;
3666 var fw = f.writer(io, &buf);
3667 try fw.interface.print(format, args);
3668 try fw.interface.flush();
3675
3676fn confPathDepToCachePath(graph: *const Graph, c: *const Configuration, path_dep: Configuration.PathDep) Path {
3677 const sub_path = path_dep.sub.slice(c);
3678 return switch (path_dep.flags.base) {
3679 .cwd => .{
3680 .root_dir = .cwd(),
3681 .sub_path = sub_path,
3682 },
3683 .local_cache => .{
3684 .root_dir = graph.local_cache_root,
3685 .sub_path = sub_path,
3686 },
3687 .global_cache => .{
3688 .root_dir = graph.global_cache_root,
3689 .sub_path = sub_path,
3690 },
3691 .build_root => .{
3692 .root_dir = switch (path_dep.pkg.unwrap().?) {
3693 .root => graph.build_root_directory,
3694 _ => @panic("TODO"),
3695 },
3696 .sub_path = sub_path,
3697 },
3698 .zig_lib => .{
3699 .root_dir = graph.zig_lib_directory,
3700 .sub_path = sub_path,
3701 },
3702 .zig_exe => @panic("TODO"),
3703 .install_prefix => @panic("TODO"),
3704 .install_lib => @panic("TODO"),
3705 .install_bin => @panic("TODO"),
3706 .install_include => @panic("TODO"),
3707 };
36693708}
lib/compiler/Maker/Graph.zig-1
......@@ -4,7 +4,6 @@ const Graph = @This();
44const std = @import("std");
55const Io = std.Io;
66const Allocator = std.mem.Allocator;
7const Configuration = std.Build.Configuration;
87const Path = std.Build.Cache.Path;
98const Directory = std.Build.Cache.Directory;
109
lib/compiler/configurer.zig+2-3
......@@ -633,8 +633,7 @@ fn serialize(b: *std.Build, wc: *Configuration.Wip, writer: *Io.Writer) !void {
633633 var s: Serialize = .{ .wc = wc, .arena = arena };
634634
635635 try wc.path_deps.ensureTotalCapacityPrecise(gpa, graph.configure_dependencies.items.len);
636 // TODO remove this
637 if (false) for (
636 for (
638637 graph.configure_dependencies.items,
639638 wc.path_deps.addManyAsSliceAssumeCapacity(graph.configure_dependencies.items.len),
640639 ) |src, *dest| {
......@@ -662,7 +661,7 @@ fn serialize(b: *std.Build, wc: *Configuration.Wip, writer: *Io.Writer) !void {
662661 .dependency => |d| .init(try s.builderToPackage(d.dependency.builder)),
663662 },
664663 };
665 };
664 }
666665
667666 // Starting from all top-level steps in `b`, traverse the entire step graph
668667 // and add all step dependencies implied by module graphs.
lib/std/Build.zig+1
......@@ -177,6 +177,7 @@ pub const Graph = struct {
177177 /// A path whose components and contents are known at some point during
178178 /// `Step` resolution, relative to the provided base directory.
179179 pub fn path(graph: *Graph, base: Configuration.LazyPath.Relative.Base, sub_path: []const u8) LazyPath {
180 assert(base != .build_root);
180181 return .{ .relative = .{
181182 .base = base,
182183 .sub_path = @This().dupePath(graph, sub_path),
lib/std/Build/Cache.zig+23-11
......@@ -70,6 +70,15 @@ pub const PrefixedPath = struct {
7070 }
7171};
7272
73fn findPrefixPath(cache: *const Cache, path: Path) !PrefixedPath {
74 const gpa = cache.gpa;
75 const resolved_path = try std.fs.path.resolve(gpa, &.{
76 cache.cwd, path.root_dir.path orelse ".", path.subPathOrDot(),
77 });
78 errdefer gpa.free(resolved_path);
79 return findPrefixResolved(cache, resolved_path);
80}
81
7382fn findPrefix(cache: *const Cache, file_path: []const u8) !PrefixedPath {
7483 const gpa = cache.gpa;
7584 const resolved_path = try std.fs.path.resolve(gpa, &.{file_path});
......@@ -998,13 +1007,22 @@ pub const Manifest = struct {
9981007 /// This is useful for processes that don't know the all the files that are
9991008 /// depended on ahead of time. For example, a source file that can import
10001009 /// other files will need to be recompiled if the imported file is changed.
1001 pub fn addFilePost(self: *Manifest, file_path: []const u8) !void {
1002 assert(self.manifest_file != null);
1003 const gpa = self.cache.gpa;
1004 const prefixed_path = try self.cache.findPrefix(file_path);
1010 pub fn addFilePost(man: *Manifest, file_path: []const u8) !void {
1011 assert(man.manifest_file != null);
1012 const gpa = man.cache.gpa;
1013 const prefixed_path = try man.cache.findPrefix(file_path);
10051014 var keep = false;
10061015 defer if (!keep) gpa.free(prefixed_path.sub_path);
1007 keep = try addPrefixedPathPost(self, prefixed_path);
1016 keep = try addPrefixedPathPost(man, prefixed_path);
1017 }
1018
1019 pub fn addPathPost(man: *Manifest, path: Path) !void {
1020 assert(man.manifest_file != null);
1021 const gpa = man.cache.gpa;
1022 const prefixed_path: PrefixedPath = try man.cache.findPrefixPath(path);
1023 var keep = false;
1024 defer if (!keep) gpa.free(prefixed_path.sub_path);
1025 keep = try addPrefixedPathPost(man, prefixed_path);
10081026 }
10091027
10101028 /// Low level function. `prefixed_path` references cloned memory. Returns
......@@ -1034,12 +1052,6 @@ pub const Manifest = struct {
10341052 return true;
10351053 }
10361054
1037 pub fn addPathPost(man: *Manifest, path: Path) !void {
1038 _ = man;
1039 _ = path;
1040 std.log.err("TODO Build.Cache.addPathPost", .{});
1041 }
1042
10431055 /// Like `addFilePost` but when the file contents have already been loaded from disk.
10441056 pub fn addFilePostContents(
10451057 self: *Manifest,
lib/std/Build/Configuration.zig+1-7
......@@ -1557,6 +1557,7 @@ pub const LazyPath = union(@This().Tag) {
15571557 cwd,
15581558 local_cache,
15591559 global_cache,
1560 /// Must not be used with Relative since package index is missing.
15601561 build_root,
15611562 zig_exe,
15621563 zig_lib,
......@@ -1876,13 +1877,6 @@ pub const PathDep = extern struct {
18761877 };
18771878
18781879 pub const Mode = enum(u8) { directory, contents, metadata };
1879
1880 pub fn toCachePath(path: PathDep, c: *const Configuration, arena: Allocator) std.Build.Cache.Path {
1881 _ = c;
1882 _ = arena;
1883 _ = path;
1884 if (true) @panic("TODO Configuration.PathDep.toCachePath");
1885 }
18861880};
18871881
18881882pub const InstallDestDir = enum(u32) {