authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-10-14 17:38:43-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-10-16 12:32:44-07:00
log026e105afaf33c4887a02102b21f8c2e233cd930
treefefc1069b5df09d8037657125a037f30652cc96b
parent26265e29f4599660a4bfcbc196fc98110bdac6d0

Maker: fix use case when --fork matches 2 or more pkgs

Previously this always caused a compilation failure because it would correctly substitute multiple packages with the provided forked package, however, this ends up constructing a zig build-exe command line for the configurer that included multiple differnt modules that used the same files. Closes #31677

2 files changed, 40 insertions(+), 15 deletions(-)

lib/compiler/Maker.zig+28-11
...@@ -1385,17 +1385,34 @@ fn configure(graph: *Graph, options: ConfigureOptions) !ScannedConfig {...@@ -1385,17 +1385,34 @@ fn configure(graph: *Graph, options: ConfigureOptions) !ScannedConfig {
1385 // The first one is a dummy package for the current project.1385 // The first one is a dummy package for the current project.
1386 continue;1386 continue;
1387 }1387 }
1388 if (!f.has_build_zig)1388 if (!f.has_build_zig) continue;
1389 continue;1389
1390 const hash_slice = try arena.dupe(u8, hash.toSlice());1390 const project_id: Package.ProjectId = .init(f.manifest.name, f.manifest.id);
13911391 if (fork_set.getKeyPtrAdapted(project_id, @as(Fetch.JobQueue.Fork.Adapter, .{}))) |fork| {
1392 const m = try arena.create(CliModule);1392 const path = try fork.path.toString(arena);
1393 m.* = .{1393 const gop = deps_mod.deps.getOrPutAssumeCapacity(path);
1394 .root_path = try f.package_root.toString(arena),1394 if (gop.found_existing) {
1395 .name = hash_slice,1395 assert(fork.uses > 1);
1396 };1396 f.cli_module = gop.value_ptr.*;
1397 deps_mod.deps.putAssumeCapacityNoClobber(hash_slice, m);1397 } else {
1398 f.cli_module = m;1398 const m = try arena.create(CliModule);
1399 m.* = .{
1400 .root_path = try f.package_root.toString(arena),
1401 .name = path,
1402 };
1403 gop.value_ptr.* = m;
1404 f.cli_module = m;
1405 }
1406 } else {
1407 const hash_slice = try arena.dupe(u8, hash.toSlice());
1408 const m = try arena.create(CliModule);
1409 m.* = .{
1410 .root_path = try f.package_root.toString(arena),
1411 .name = hash_slice,
1412 };
1413 deps_mod.deps.putAssumeCapacityNoClobber(hash_slice, m);
1414 f.cli_module = m;
1415 }
1399 }1416 }
14001417
1401 // Each build.zig module needs access to each of its dependencies' build.zig modules by1418 // Each build.zig module needs access to each of its dependencies' build.zig modules by
lib/compiler/Maker/Fetch.zig+12-4
...@@ -290,10 +290,18 @@ pub const JobQueue = struct {...@@ -290,10 +290,18 @@ pub const JobQueue = struct {
290 , .{std.fmt.alt(fetch.package_root, .formatEscapeString)});290 , .{std.fmt.alt(fetch.package_root, .formatEscapeString)});
291291
292 if (fetch.has_build_zig) {292 if (fetch.has_build_zig) {
293 try w.print(293 const project_id: Package.ProjectId = .init(fetch.manifest.name, fetch.manifest.id);
294 \\ pub const build_zig = @import("{f}");294 if (jq.fork_set.getKeyPtrAdapted(project_id, @as(JobQueue.Fork.Adapter, .{}))) |fork| {
295 \\295 try w.print(
296 , .{std.zig.fmtString(hash_slice)});296 \\ pub const build_zig = @import({qf});
297 \\
298 , .{fork.path});
299 } else {
300 try w.print(
301 \\ pub const build_zig = @import({q});
302 \\
303 , .{hash_slice});
304 }
297 }305 }
298306
299 if (fetch.have_manifest) {307 if (fetch.have_manifest) {