authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-07-01 19:44:27-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-07-01 20:03:17-07:00
log161ac7081a2b9b71800d0d5993af054efd408a34
tree4a6a47fef26c317d3e3bcc5a70398d1b06adf098
parent3889112380e1c14978d8be512068b99d2a7f774b

Maker: fix implementation of --cache-poison=poisoned

it needed to avoid calling functions on the Cache instance in that case

1 files changed, 32 insertions(+), 25 deletions(-)

lib/compiler/Maker.zig+32-25
......@@ -981,27 +981,35 @@ fn configure(graph: *Graph, options: ConfigureOptions) !ScannedConfig {
981981 // This loop is re-evaluated when the build script exits with an indication that it
982982 // could not continue due to missing lazy dependencies.
983983 const configuration_path: Path, var configuration_lock: ?Cache.Lock = cp: while (true) {
984 build_mod.deps.clearRetainingCapacity();
985 deps_mod.deps.clearRetainingCapacity();
986
984987 // Cache lookup for configure options. If we get a match, we can skip
985988 // execution of the configure script. If not, we get the file path to pass
986989 // to the configure process.
987990 //
988991 // In the hot path, we only check this cache, which means that also
989992 // configure source files need to go in here.
990 var config_man = graph.cache.obtain();
991 defer config_man.deinit();
993 var config_man_allocation: Cache.Manifest = undefined;
994 const config_man: ?*Cache.Manifest = switch (options.cache_poison) {
995 .pure, .disallowed, .ignored => m: {
996 config_man_allocation = graph.cache.obtain();
992997
993 for (options.cached_passthru_configure) |i|
994 config_man.hash.addBytes(configure_argv[i]);
998 for (options.cached_passthru_configure) |i|
999 config_man_allocation.hash.addBytes(configure_argv[i]);
9951000
996 if (target_arch_os_abi) |triple|
997 config_man.hash.addBytes(triple);
1001 if (target_arch_os_abi) |triple|
1002 config_man_allocation.hash.addBytes(triple);
9981003
999 // Prevents a `zig build` from getting a false positive cache hit following
1000 // a `zig build --cache-poison=ignored`.
1001 config_man.hash.add(options.cache_poison == .ignored);
1004 // Prevents a `zig build` from getting a false positive cache hit following
1005 // a `zig build --cache-poison=ignored`.
1006 config_man_allocation.hash.add(options.cache_poison == .ignored);
10021007
1003 build_mod.deps.clearRetainingCapacity();
1004 deps_mod.deps.clearRetainingCapacity();
1008 break :m &config_man_allocation;
1009 },
1010 .poisoned => null,
1011 };
1012 defer if (config_man) |man| man.deinit();
10051013
10061014 // We want to release all the locks before executing the child process, so we make a nice
10071015 // big block here to ensure the cleanup gets run when we extract out our argv.
......@@ -1217,26 +1225,24 @@ fn configure(graph: *Graph, options: ConfigureOptions) !ScannedConfig {
12171225 const compile_prog_node = options.parent_progress_node.start("Compile Configure Script", 0);
12181226 defer compile_prog_node.end();
12191227
1220 switch (options.cache_poison) {
1221 .pure, .disallowed, .ignored => if (try config_man.hit(compile_prog_node)) {
1222 const digest = config_man.final();
1228 if (config_man) |man| {
1229 if (try man.hit(compile_prog_node)) {
1230 const digest = man.final();
12231231 break :cp .{
12241232 .{
12251233 .root_dir = graph.local_cache_root,
12261234 .sub_path = try arena.print("c/{s}", .{&digest}),
12271235 },
1228 config_man.toOwnedLock(),
1236 man.toOwnedLock(),
12291237 };
1230 },
1231 .poisoned => {}, // Don't bother checking for cache hit.
1238 }
12321239 }
1233
12341240 const configure_exe_path: Path = if (std.zig.buildExeSubprocess(gpa, io, .{
12351241 .argv = build_configurer_argv.items,
12361242 .cache_root = graph.local_cache_root,
12371243 .root_name = configurer_exe_name,
12381244 .environ_map = &graph.environ_map,
1239 .cache_manifest = &config_man,
1245 .cache_manifest = config_man,
12401246 .arch_os_abi = target_arch_os_abi,
12411247 .progress_node = compile_prog_node,
12421248 .skip_log_cmdline_on_compile_errors = !graph.verbose,
......@@ -1318,20 +1324,21 @@ fn configure(graph: *Graph, options: ConfigureOptions) !ScannedConfig {
13181324 continue :cp;
13191325 }
13201326
1321 for (configuration.path_deps) |path_dep| {
1327 if (config_man) |man| for (configuration.path_deps) |path_dep| {
13221328 switch (path_dep.flags.mode) {
13231329 .directory => {}, // TODO
1324 .contents => try config_man.addPathPost(confPathDepToCachePath(graph, &configuration, path_dep)),
1330 .contents => try man.addPathPost(confPathDepToCachePath(graph, &configuration, path_dep)),
13251331 .metadata => {}, // TODO
13261332 }
1327 }
1333 };
13281334
13291335 // If it is poisoned, there is no point in moving it to cached
13301336 // location. Just leave it in the tmp directory.
13311337 if (configuration.poisoned) {
13321338 break :cp .{ config_tmp_path, null };
13331339 } else {
1334 const digest = config_man.final();
1340 const man = config_man.?;
1341 const digest = man.final();
13351342 const final_path: Path = .{
13361343 .root_dir = graph.local_cache_root,
13371344 .sub_path = try arena.print("c/{s}", .{&digest}),
......@@ -1362,8 +1369,8 @@ fn configure(graph: *Graph, options: ConfigureOptions) !ScannedConfig {
13621369 config_tmp_path, final_path, e,
13631370 });
13641371 };
1365 config_man.writeManifest() catch |err| log.warn("failed to write cache manifest: {t}", .{err});
1366 break :cp .{ final_path, config_man.toOwnedLock() };
1372 man.writeManifest() catch |err| log.warn("failed to write cache manifest: {t}", .{err});
1373 break :cp .{ final_path, man.toOwnedLock() };
13671374 }
13681375 };
13691376 // Hang on to the configuration file lock until we finish loading the configuration file.