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 {...@@ -981,27 +981,35 @@ fn configure(graph: *Graph, options: ConfigureOptions) !ScannedConfig {
981 // This loop is re-evaluated when the build script exits with an indication that it981 // This loop is re-evaluated when the build script exits with an indication that it
982 // could not continue due to missing lazy dependencies.982 // could not continue due to missing lazy dependencies.
983 const configuration_path: Path, var configuration_lock: ?Cache.Lock = cp: while (true) {983 const configuration_path: Path, var configuration_lock: ?Cache.Lock = cp: while (true) {
984 build_mod.deps.clearRetainingCapacity();
985 deps_mod.deps.clearRetainingCapacity();
986
984 // Cache lookup for configure options. If we get a match, we can skip987 // Cache lookup for configure options. If we get a match, we can skip
985 // execution of the configure script. If not, we get the file path to pass988 // execution of the configure script. If not, we get the file path to pass
986 // to the configure process.989 // to the configure process.
987 //990 //
988 // In the hot path, we only check this cache, which means that also991 // In the hot path, we only check this cache, which means that also
989 // configure source files need to go in here.992 // configure source files need to go in here.
990 var config_man = graph.cache.obtain();993 var config_man_allocation: Cache.Manifest = undefined;
991 defer config_man.deinit();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|998 for (options.cached_passthru_configure) |i|
994 config_man.hash.addBytes(configure_argv[i]);999 config_man_allocation.hash.addBytes(configure_argv[i]);
9951000
996 if (target_arch_os_abi) |triple|1001 if (target_arch_os_abi) |triple|
997 config_man.hash.addBytes(triple);1002 config_man_allocation.hash.addBytes(triple);
9981003
999 // Prevents a `zig build` from getting a false positive cache hit following1004 // Prevents a `zig build` from getting a false positive cache hit following
1000 // a `zig build --cache-poison=ignored`.1005 // a `zig build --cache-poison=ignored`.
1001 config_man.hash.add(options.cache_poison == .ignored);1006 config_man_allocation.hash.add(options.cache_poison == .ignored);
10021007
1003 build_mod.deps.clearRetainingCapacity();1008 break :m &config_man_allocation;
1004 deps_mod.deps.clearRetainingCapacity();1009 },
1010 .poisoned => null,
1011 };
1012 defer if (config_man) |man| man.deinit();
10051013
1006 // We want to release all the locks before executing the child process, so we make a nice1014 // We want to release all the locks before executing the child process, so we make a nice
1007 // big block here to ensure the cleanup gets run when we extract out our argv.1015 // 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 {...@@ -1217,26 +1225,24 @@ fn configure(graph: *Graph, options: ConfigureOptions) !ScannedConfig {
1217 const compile_prog_node = options.parent_progress_node.start("Compile Configure Script", 0);1225 const compile_prog_node = options.parent_progress_node.start("Compile Configure Script", 0);
1218 defer compile_prog_node.end();1226 defer compile_prog_node.end();
12191227
1220 switch (options.cache_poison) {1228 if (config_man) |man| {
1221 .pure, .disallowed, .ignored => if (try config_man.hit(compile_prog_node)) {1229 if (try man.hit(compile_prog_node)) {
1222 const digest = config_man.final();1230 const digest = man.final();
1223 break :cp .{1231 break :cp .{
1224 .{1232 .{
1225 .root_dir = graph.local_cache_root,1233 .root_dir = graph.local_cache_root,
1226 .sub_path = try arena.print("c/{s}", .{&digest}),1234 .sub_path = try arena.print("c/{s}", .{&digest}),
1227 },1235 },
1228 config_man.toOwnedLock(),1236 man.toOwnedLock(),
1229 };1237 };
1230 },1238 }
1231 .poisoned => {}, // Don't bother checking for cache hit.
1232 }1239 }
1233
1234 const configure_exe_path: Path = if (std.zig.buildExeSubprocess(gpa, io, .{1240 const configure_exe_path: Path = if (std.zig.buildExeSubprocess(gpa, io, .{
1235 .argv = build_configurer_argv.items,1241 .argv = build_configurer_argv.items,
1236 .cache_root = graph.local_cache_root,1242 .cache_root = graph.local_cache_root,
1237 .root_name = configurer_exe_name,1243 .root_name = configurer_exe_name,
1238 .environ_map = &graph.environ_map,1244 .environ_map = &graph.environ_map,
1239 .cache_manifest = &config_man,1245 .cache_manifest = config_man,
1240 .arch_os_abi = target_arch_os_abi,1246 .arch_os_abi = target_arch_os_abi,
1241 .progress_node = compile_prog_node,1247 .progress_node = compile_prog_node,
1242 .skip_log_cmdline_on_compile_errors = !graph.verbose,1248 .skip_log_cmdline_on_compile_errors = !graph.verbose,
...@@ -1318,20 +1324,21 @@ fn configure(graph: *Graph, options: ConfigureOptions) !ScannedConfig {...@@ -1318,20 +1324,21 @@ fn configure(graph: *Graph, options: ConfigureOptions) !ScannedConfig {
1318 continue :cp;1324 continue :cp;
1319 }1325 }
13201326
1321 for (configuration.path_deps) |path_dep| {1327 if (config_man) |man| for (configuration.path_deps) |path_dep| {
1322 switch (path_dep.flags.mode) {1328 switch (path_dep.flags.mode) {
1323 .directory => {}, // TODO1329 .directory => {}, // TODO
1324 .contents => try config_man.addPathPost(confPathDepToCachePath(graph, &configuration, path_dep)),1330 .contents => try man.addPathPost(confPathDepToCachePath(graph, &configuration, path_dep)),
1325 .metadata => {}, // TODO1331 .metadata => {}, // TODO
1326 }1332 }
1327 }1333 };
13281334
1329 // If it is poisoned, there is no point in moving it to cached1335 // If it is poisoned, there is no point in moving it to cached
1330 // location. Just leave it in the tmp directory.1336 // location. Just leave it in the tmp directory.
1331 if (configuration.poisoned) {1337 if (configuration.poisoned) {
1332 break :cp .{ config_tmp_path, null };1338 break :cp .{ config_tmp_path, null };
1333 } else {1339 } else {
1334 const digest = config_man.final();1340 const man = config_man.?;
1341 const digest = man.final();
1335 const final_path: Path = .{1342 const final_path: Path = .{
1336 .root_dir = graph.local_cache_root,1343 .root_dir = graph.local_cache_root,
1337 .sub_path = try arena.print("c/{s}", .{&digest}),1344 .sub_path = try arena.print("c/{s}", .{&digest}),
...@@ -1362,8 +1369,8 @@ fn configure(graph: *Graph, options: ConfigureOptions) !ScannedConfig {...@@ -1362,8 +1369,8 @@ fn configure(graph: *Graph, options: ConfigureOptions) !ScannedConfig {
1362 config_tmp_path, final_path, e,1369 config_tmp_path, final_path, e,
1363 });1370 });
1364 };1371 };
1365 config_man.writeManifest() catch |err| log.warn("failed to write cache manifest: {t}", .{err});1372 man.writeManifest() catch |err| log.warn("failed to write cache manifest: {t}", .{err});
1366 break :cp .{ final_path, config_man.toOwnedLock() };1373 break :cp .{ final_path, man.toOwnedLock() };
1367 }1374 }
1368 };1375 };
1369 // Hang on to the configuration file lock until we finish loading the configuration file.1376 // Hang on to the configuration file lock until we finish loading the configuration file.