authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-07-01 14:41:47-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-07-01 14:41:47-07:00
log1fce802929a3db8971d1127e6b81c3799b00021c
tree8df9e445a3f93d9b0e4c458b6a3b67739829a5fc
parent554172e6258db4b391d31636ac9274a433f2f401

Maker: fix double use of Cache.hit() inside loop

The cache manifest needs to get recreated in the configure loop.

1 files changed, 23 insertions(+), 23 deletions(-)

lib/compiler/Maker.zig+23-23
......@@ -881,22 +881,6 @@ fn configure(graph: *Graph, options: ConfigureOptions) !ScannedConfig {
881881 const io = graph.io;
882882 const arena = graph.arena;
883883
884 // Cache lookup for configure options. If we get a match, we can skip
885 // execution of the configure script. If not, we get the file path to pass
886 // to the configure process.
887 //
888 // In the hot path, we only check this cache, which means that also
889 // configure source files need to go in here.
890 var config_man = graph.cache.obtain();
891 defer config_man.deinit();
892
893 for (options.cached_passthru_configure) |i|
894 config_man.hash.addBytes(configure_argv[i]);
895
896 // Prevents a `zig build` from getting a false positive cache hit following
897 // a `zig build --cache-poison=ignored`.
898 config_man.hash.add(options.cache_poison == .ignored);
899
900884 configure_argv[options.conf_argv_index_build_root] = options.build_root.directory.path orelse options.cwd_path;
901885
902886 var http_client: std.http.Client = .{ .allocator = gpa, .io = io };
......@@ -958,7 +942,6 @@ fn configure(graph: *Graph, options: ConfigureOptions) !ScannedConfig {
958942 // some code to help when debugging edits to the build runner so that you
959943 // can make sure it compiles successfully on other targets.
960944 const target_arch_os_abi: ?[]const u8 = if (options.debug_target) |triple| t: {
961 config_man.hash.addBytes(triple);
962945 try build_configurer_argv.appendSlice(gpa, &.{ "-target", triple });
963946 break :t triple;
964947 } else null;
......@@ -997,7 +980,26 @@ fn configure(graph: *Graph, options: ConfigureOptions) !ScannedConfig {
997980
998981 // This loop is re-evaluated when the build script exits with an indication that it
999982 // could not continue due to missing lazy dependencies.
1000 const configuration_path: Path, const poisoned: bool = cp: while (true) {
983 const configuration_path: Path, var configuration_lock: ?Cache.Lock = cp: while (true) {
984 // 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 pass
986 // to the configure process.
987 //
988 // In the hot path, we only check this cache, which means that also
989 // configure source files need to go in here.
990 var config_man = graph.cache.obtain();
991 defer config_man.deinit();
992
993 for (options.cached_passthru_configure) |i|
994 config_man.hash.addBytes(configure_argv[i]);
995
996 if (target_arch_os_abi) |triple|
997 config_man.hash.addBytes(triple);
998
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);
1002
10011003 build_mod.deps.clearRetainingCapacity();
10021004 deps_mod.deps.clearRetainingCapacity();
10031005
......@@ -1223,7 +1225,7 @@ fn configure(graph: *Graph, options: ConfigureOptions) !ScannedConfig {
12231225 .root_dir = graph.local_cache_root,
12241226 .sub_path = try arena.print("c/{s}", .{&digest}),
12251227 },
1226 false,
1228 config_man.toOwnedLock(),
12271229 };
12281230 },
12291231 .poisoned => {}, // Don't bother checking for cache hit.
......@@ -1327,7 +1329,7 @@ fn configure(graph: *Graph, options: ConfigureOptions) !ScannedConfig {
13271329 // If it is poisoned, there is no point in moving it to cached
13281330 // location. Just leave it in the tmp directory.
13291331 if (configuration.poisoned) {
1330 break :cp .{ config_tmp_path, true };
1332 break :cp .{ config_tmp_path, null };
13311333 } else {
13321334 const digest = config_man.final();
13331335 const final_path: Path = .{
......@@ -1361,12 +1363,10 @@ fn configure(graph: *Graph, options: ConfigureOptions) !ScannedConfig {
13611363 });
13621364 };
13631365 config_man.writeManifest() catch |err| log.warn("failed to write cache manifest: {t}", .{err});
1364 break :cp .{ final_path, false };
1366 break :cp .{ final_path, config_man.toOwnedLock() };
13651367 }
13661368 };
1367
13681369 // Hang on to the configuration file lock until we finish loading the configuration file.
1369 var configuration_lock = if (!poisoned) config_man.toOwnedLock() else null;
13701370 defer if (configuration_lock) |*l| l.release(io);
13711371
13721372 switch (options.print_configuration) {