authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-08-08 21:48:00+02:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-08-08 21:48:00+02:00
log8380531aecf20405bad6e008712a39795f224cb3
treec82d9b5ca44caba3398df96b211b4992e304ed51
parent6fd38ce13f4cff552272fcc33c8a23d735ac0a49
parent0f332fd536aee4fcff4d0875d1d7136ba5b6f01b

Merge pull request 'Serialize packages and root dependencies into configuration file' (#36419) from hemisputnik/zig:work/36387-configuration-deps into master

Reviewed-on: https://codeberg.org/ziglang/zig/pulls/36419 Reviewed-by: Andrew Kelley <andrew@ziglang.org>

5 files changed, 148 insertions(+), 344 deletions(-)

lib/compiler/Maker.zig+5-3
......@@ -3325,17 +3325,19 @@ pub fn packagePath(
33253325) Allocator.Error!Path {
33263326 const c = &maker.scanned_config.configuration;
33273327 const graph = maker.graph;
3328 const package = package_index.get(c) orelse return .{
3328
3329 if (package_index == .root) return .{
33293330 .root_dir = graph.build_root_directory,
33303331 .sub_path = sub_path,
33313332 };
3333
33323334 // Currently, neither configurer nor Maker is aware of the standard zig
33333335 // package path, and the root path is stored as a bare string rather than
33343336 // relative to a known base directory. Without changing that, we must
33353337 // construct a cwd relative path here.
33363338 return .{
33373339 .root_dir = .cwd(),
3338 .sub_path = try Dir.path.join(arena, &.{ package.root_path.slice(c), sub_path }),
3340 .sub_path = try Dir.path.join(arena, &.{ package_index.ptr(c).root_path.slice(c), sub_path }),
33393341 };
33403342}
33413343
......@@ -3965,7 +3967,7 @@ fn confPathDepToCachePath(
39653967 .root_dir = graph.build_root_directory,
39663968 .sub_path = switch (path_dep.pkg.unwrap().?) {
39673969 .root => sub_path,
3968 else => |index| try Dir.path.join(arena, &.{ index.get(c).?.root_path.slice(c), sub_path }),
3970 else => |index| try Dir.path.join(arena, &.{ index.ptr(c).root_path.slice(c), sub_path }),
39693971 },
39703972 },
39713973 .zig_lib => .{
lib/compiler/Maker/ScannedConfig.zig+21
......@@ -83,6 +83,27 @@ pub fn print(sc: *const ScannedConfig, w: *Writer) Writer.Error!void {
8383 try tf.end();
8484 }
8585
86 {
87 var tf = try s.beginTupleField("packages", .{});
88 for (c.packages) |package| {
89 var sf = try tf.beginStructField(.{});
90 try sf.field("dep_prefix", package.dep_prefix.slice(c), .{});
91 try sf.field("hash", package.hash.slice(c), .{});
92 try sf.field("root_path", package.root_path.slice(c), .{});
93
94 var dtf = try sf.beginTupleField("deps", .{});
95 for (package.deps.slice(c)) |dep| {
96 var dsf = try dtf.beginStructField(.{});
97 try sc.printStruct(&dsf, Configuration.Package.Dep, dep);
98 try dsf.end();
99 }
100 try dtf.end();
101
102 try sf.end();
103 }
104 try tf.end();
105 }
106
86107 try s.end();
87108}
88109
lib/std/Build.zig+3-2
......@@ -2144,7 +2144,7 @@ pub fn dependencyLazy(b: *Build, name: []const u8, args: anytype) error{LazyDepe
21442144 return dependencyResolved(b, name, entry, userInputOptionsFromArgs(b.graph.arena, args));
21452145}
21462146
2147const PackageEntry = struct {
2147pub const PackageEntry = struct {
21482148 hash: []const u8,
21492149 available: bool,
21502150 build_root: []const u8,
......@@ -2152,7 +2152,8 @@ const PackageEntry = struct {
21522152 run_build: ?*const fn (*Build) void,
21532153};
21542154
2155const package_map: std.StaticStringMap(PackageEntry) = blk: {
2155/// Build system implementation detail.
2156pub const package_map: std.StaticStringMap(PackageEntry) = blk: {
21562157 const deps = @import("root").dependencies;
21572158 const decl_names = @typeInfo(deps.packages).@"struct".decl_names;
21582159 var kvs: [decl_names.len]struct { []const u8, PackageEntry } = undefined;
lib/std/Build/Configuration.zig+51-321
......@@ -15,6 +15,8 @@ unlazy_deps: []String,
1515system_integrations: []SystemIntegration,
1616available_options: []AvailableOption,
1717search_prefixes: []String,
18/// Index 0 always exists and is the root package.
19packages: []Package,
1820extra: []u32,
1921default_step: Step.Index,
2022generated_files_len: u32,
......@@ -30,6 +32,7 @@ pub const Header = extern struct {
3032 system_integrations_len: u32,
3133 available_options_len: u32,
3234 search_prefixes_len: u32,
35 packages_len: u32,
3336 extra_len: u32,
3437
3538 default_step: Step.Index,
......@@ -58,6 +61,7 @@ pub const Wip = struct {
5861 steps: std.ArrayList(Step) = .empty,
5962 path_deps: std.ArrayList(PathDep) = .empty,
6063 search_prefixes: std.ArrayList(String) = .empty,
64 packages: std.ArrayList(Package) = .empty,
6165 extra: std.ArrayList(u32) = .empty,
6266 next_generated_file_index: u32 = 0,
6367 cache_poison: bool = false,
......@@ -139,6 +143,7 @@ pub const Wip = struct {
139143 wip.steps.deinit(gpa);
140144 wip.path_deps.deinit(gpa);
141145 wip.search_prefixes.deinit(gpa);
146 wip.packages.deinit(gpa);
142147 wip.extra.deinit(gpa);
143148 wip.* = undefined;
144149 }
......@@ -158,6 +163,7 @@ pub const Wip = struct {
158163 .system_integrations_len = @intCast(wip.system_integrations.items.len),
159164 .available_options_len = @intCast(wip.available_options.items.len),
160165 .search_prefixes_len = @intCast(wip.search_prefixes.items.len),
166 .packages_len = @intCast(wip.packages.items.len),
161167 .extra_len = @intCast(wip.extra.items.len),
162168
163169 .default_step = static.default_step,
......@@ -175,6 +181,7 @@ pub const Wip = struct {
175181 @ptrCast(wip.system_integrations.items),
176182 @ptrCast(wip.available_options.items),
177183 @ptrCast(wip.search_prefixes.items),
184 @ptrCast(wip.packages.items),
178185 @ptrCast(wip.extra.items),
179186 };
180187 try w.writeVecAll(&buffers);
......@@ -1602,30 +1609,28 @@ pub const OptionalGeneratedFileIndex = enum(u32) {
16021609 }
16031610};
16041611
1605pub const Package = struct {
1612pub const Package = extern struct {
16061613 dep_prefix: String,
16071614 hash: String,
16081615 root_path: String,
1616 deps: Dep.List.Index,
16091617
16101618 pub const Index = enum(u32) {
1611 root = max_u32,
1619 root,
16121620 _,
16131621
1614 /// Returns `null` for root package.
1615 pub fn get(i: @This(), c: *const Configuration) ?Package {
1616 if (i == .root) return null;
1617 return extraData(c, Package, @backingInt(i));
1622 pub fn ptr(i: @This(), c: *const Configuration) *const Package {
1623 return &c.packages[@backingInt(i)];
16181624 }
16191625
16201626 pub fn depPrefixSlice(i: @This(), c: *const Configuration) [:0]const u8 {
1621 const package = get(i, c) orelse return "";
1622 return package.dep_prefix.slice(c);
1627 return ptr(i, c).dep_prefix.slice(c);
16231628 }
16241629 };
16251630
16261631 pub const OptionalIndex = enum(u32) {
1627 none = max_u32 - 1,
1628 root = max_u32,
1632 root,
1633 none = max_u32,
16291634 _,
16301635
16311636 pub fn init(i: Index) OptionalIndex {
......@@ -1642,6 +1647,28 @@ pub const Package = struct {
16421647 };
16431648 }
16441649 };
1650
1651 pub const Dep = extern struct {
1652 name: String,
1653 /// Must not be `.root`.
1654 package: Package.Index,
1655
1656 pub const List = struct {
1657 deps: Storage.LengthPrefixedList(Dep),
1658
1659 pub const Index = enum(u32) {
1660 _,
1661
1662 pub fn get(this: @This(), c: *const Configuration) List {
1663 return extraData(c, List, @backingInt(this));
1664 }
1665
1666 pub fn slice(this: @This(), c: *const Configuration) []const Dep {
1667 return get(this, c).deps.slice;
1668 }
1669 };
1670 };
1671 };
16451672};
16461673
16471674pub const Module = struct {
......@@ -2126,27 +2153,18 @@ pub const OptionalCSourceLanguage = enum(u3) {
21262153 objective_cpp,
21272154 assembly,
21282155 assembly_with_preprocessor,
2156
21292157 default,
21302158
21312159 pub fn init(x: ?std.Build.Module.CSourceLanguage) @This() {
21322160 return switch (x orelse return .default) {
2133 .c => .c,
2134 .cpp => .cpp,
2135 .objective_c => .objective_c,
2136 .objective_cpp => .objective_cpp,
2137 .assembly => .assembly,
2138 .assembly_with_preprocessor => .assembly_with_preprocessor,
2161 inline else => |tag| @field(@This(), @tagName(tag)),
21392162 };
21402163 }
21412164
21422165 pub fn get(this: @This()) ?std.Build.Module.CSourceLanguage {
21432166 return switch (this) {
2144 .c => .c,
2145 .cpp => .cpp,
2146 .objective_c => .objective_c,
2147 .objective_cpp => .objective_cpp,
2148 .assembly => .assembly,
2149 .assembly_with_preprocessor => .assembly_with_preprocessor,
2167 inline else => |tag| @field(std.Build.Module.CSourceLanguage, @tagName(tag)),
21502168 .default => null,
21512169 };
21522170 }
......@@ -2274,10 +2292,7 @@ pub const TargetQuery = struct {
22742292
22752293 pub fn init(x: std.Target.Query.CpuModel) @This() {
22762294 return switch (x) {
2277 .native => .native,
2278 .baseline => .baseline,
2279 .determined_by_arch_os => .determined_by_arch_os,
2280 .explicit => .explicit,
2295 inline else => |_, tag| @field(@This(), @tagName(tag)),
22812296 };
22822297 }
22832298 };
......@@ -2335,71 +2350,13 @@ pub const TargetQuery = struct {
23352350
23362351 pub fn init(x: ?std.Target.Abi) @This() {
23372352 return switch (x orelse return .default) {
2338 .none => .none,
2339 .gnu => .gnu,
2340 .gnuabin32 => .gnuabin32,
2341 .gnuabi64 => .gnuabi64,
2342 .gnueabi => .gnueabi,
2343 .gnueabihf => .gnueabihf,
2344 .gnuf32 => .gnuf32,
2345 .gnusf => .gnusf,
2346 .gnux32 => .gnux32,
2347 .eabi => .eabi,
2348 .eabihf => .eabihf,
2349 .abin32 => .abin32,
2350 .x32 => .x32,
2351 .ilp32 => .ilp32,
2352 .android => .android,
2353 .androideabi => .androideabi,
2354 .musl => .musl,
2355 .muslabin32 => .muslabin32,
2356 .muslabi64 => .muslabi64,
2357 .musleabi => .musleabi,
2358 .musleabihf => .musleabihf,
2359 .muslf32 => .muslf32,
2360 .muslsf => .muslsf,
2361 .muslx32 => .muslx32,
2362 .msvc => .msvc,
2363 .itanium => .itanium,
2364 .simulator => .simulator,
2365 .ohos => .ohos,
2366 .ohoseabi => .ohoseabi,
2367 .call0 => .call0,
2353 inline else => |tag| @field(@This(), @tagName(tag)),
23682354 };
23692355 }
23702356
23712357 pub fn unwrap(this: @This()) ?std.Target.Abi {
23722358 return switch (this) {
2373 .none => .none,
2374 .gnu => .gnu,
2375 .gnuabin32 => .gnuabin32,
2376 .gnuabi64 => .gnuabi64,
2377 .gnueabi => .gnueabi,
2378 .gnueabihf => .gnueabihf,
2379 .gnuf32 => .gnuf32,
2380 .gnusf => .gnusf,
2381 .gnux32 => .gnux32,
2382 .eabi => .eabi,
2383 .eabihf => .eabihf,
2384 .abin32 => .abin32,
2385 .x32 => .x32,
2386 .ilp32 => .ilp32,
2387 .android => .android,
2388 .androideabi => .androideabi,
2389 .musl => .musl,
2390 .muslabin32 => .muslabin32,
2391 .muslabi64 => .muslabi64,
2392 .musleabi => .musleabi,
2393 .musleabihf => .musleabihf,
2394 .muslf32 => .muslf32,
2395 .muslsf => .muslsf,
2396 .muslx32 => .muslx32,
2397 .msvc => .msvc,
2398 .itanium => .itanium,
2399 .simulator => .simulator,
2400 .ohos => .ohos,
2401 .ohoseabi => .ohoseabi,
2402 .call0 => .call0,
2359 inline else => |tag| @field(std.Target.Abi, @tagName(tag)),
24032360 .default => null,
24042361 };
24052362 }
......@@ -2471,132 +2428,13 @@ pub const TargetQuery = struct {
24712428
24722429 pub fn init(x: ?std.Target.Cpu.Arch) @This() {
24732430 return switch (x orelse return .default) {
2474 .aarch64 => .aarch64,
2475 .aarch64_be => .aarch64_be,
2476 .alpha => .alpha,
2477 .amdgcn => .amdgcn,
2478 .arc => .arc,
2479 .arceb => .arceb,
2480 .arm => .arm,
2481 .armeb => .armeb,
2482 .avr => .avr,
2483 .bpfeb => .bpfeb,
2484 .bpfel => .bpfel,
2485 .csky => .csky,
2486 .ez80 => .ez80,
2487 .hexagon => .hexagon,
2488 .hppa => .hppa,
2489 .hppa64 => .hppa64,
2490 .kalimba => .kalimba,
2491 .kvx => .kvx,
2492 .lanai => .lanai,
2493 .loongarch32 => .loongarch32,
2494 .loongarch64 => .loongarch64,
2495 .m68k => .m68k,
2496 .m88k => .m88k,
2497 .microblaze => .microblaze,
2498 .microblazeel => .microblazeel,
2499 .mips => .mips,
2500 .mipsel => .mipsel,
2501 .mips64 => .mips64,
2502 .mips64el => .mips64el,
2503 .msp430 => .msp430,
2504 .nvptx => .nvptx,
2505 .nvptx64 => .nvptx64,
2506 .or1k => .or1k,
2507 .powerpc => .powerpc,
2508 .powerpcle => .powerpcle,
2509 .powerpc64 => .powerpc64,
2510 .powerpc64le => .powerpc64le,
2511 .propeller => .propeller,
2512 .riscv32 => .riscv32,
2513 .riscv32be => .riscv32be,
2514 .riscv64 => .riscv64,
2515 .riscv64be => .riscv64be,
2516 .s390x => .s390x,
2517 .sh => .sh,
2518 .sheb => .sheb,
2519 .sparc => .sparc,
2520 .sparc64 => .sparc64,
2521 .spirv32 => .spirv32,
2522 .spirv64 => .spirv64,
2523 .thumb => .thumb,
2524 .thumbeb => .thumbeb,
2525 .ve => .ve,
2526 .wasm32 => .wasm32,
2527 .wasm64 => .wasm64,
2528 .x86_16 => .x86_16,
2529 .x86 => .x86,
2530 .x86_64 => .x86_64,
2531 .xcore => .xcore,
2532 .xtensa => .xtensa,
2533 .xtensaeb => .xtensaeb,
2431 inline else => |tag| @field(@This(), @tagName(tag)),
25342432 };
25352433 }
25362434
25372435 pub fn unwrap(this: @This()) ?std.Target.Cpu.Arch {
25382436 return switch (this) {
2539 .aarch64 => .aarch64,
2540 .aarch64_be => .aarch64_be,
2541 .alpha => .alpha,
2542 .amdgcn => .amdgcn,
2543 .arc => .arc,
2544 .arceb => .arceb,
2545 .arm => .arm,
2546 .armeb => .armeb,
2547 .avr => .avr,
2548 .bpfeb => .bpfeb,
2549 .bpfel => .bpfel,
2550 .csky => .csky,
2551 .ez80 => .ez80,
2552 .hexagon => .hexagon,
2553 .hppa => .hppa,
2554 .hppa64 => .hppa64,
2555 .kalimba => .kalimba,
2556 .kvx => .kvx,
2557 .lanai => .lanai,
2558 .loongarch32 => .loongarch32,
2559 .loongarch64 => .loongarch64,
2560 .m68k => .m68k,
2561 .m88k => .m88k,
2562 .microblaze => .microblaze,
2563 .microblazeel => .microblazeel,
2564 .mips => .mips,
2565 .mipsel => .mipsel,
2566 .mips64 => .mips64,
2567 .mips64el => .mips64el,
2568 .msp430 => .msp430,
2569 .nvptx => .nvptx,
2570 .nvptx64 => .nvptx64,
2571 .or1k => .or1k,
2572 .powerpc => .powerpc,
2573 .powerpcle => .powerpcle,
2574 .powerpc64 => .powerpc64,
2575 .powerpc64le => .powerpc64le,
2576 .propeller => .propeller,
2577 .riscv32 => .riscv32,
2578 .riscv32be => .riscv32be,
2579 .riscv64 => .riscv64,
2580 .riscv64be => .riscv64be,
2581 .s390x => .s390x,
2582 .sh => .sh,
2583 .sheb => .sheb,
2584 .sparc => .sparc,
2585 .sparc64 => .sparc64,
2586 .spirv32 => .spirv32,
2587 .spirv64 => .spirv64,
2588 .thumb => .thumb,
2589 .thumbeb => .thumbeb,
2590 .ve => .ve,
2591 .wasm32 => .wasm32,
2592 .wasm64 => .wasm64,
2593 .x86_16 => .x86_16,
2594 .x86 => .x86,
2595 .x86_64 => .x86_64,
2596 .xcore => .xcore,
2597 .xtensa => .xtensa,
2598 .xtensaeb => .xtensaeb,
2599
2437 inline else => |tag| @field(std.Target.Cpu.Arch, @tagName(tag)),
26002438 .default => null,
26012439 };
26022440 }
......@@ -2655,106 +2493,13 @@ pub const TargetQuery = struct {
26552493
26562494 pub fn init(x: ?std.Target.Os.Tag) @This() {
26572495 return switch (x orelse return .default) {
2658 .freestanding => .freestanding,
2659 .other => .other,
2660 .contiki => .contiki,
2661 .fuchsia => .fuchsia,
2662 .hermit => .hermit,
2663 .managarm => .managarm,
2664 .haiku => .haiku,
2665 .hurd => .hurd,
2666 .illumos => .illumos,
2667 .linux => .linux,
2668 .plan9 => .plan9,
2669 .rtems => .rtems,
2670 .serenity => .serenity,
2671 .dragonfly => .dragonfly,
2672 .freebsd => .freebsd,
2673 .netbsd => .netbsd,
2674 .openbsd => .openbsd,
2675 .driverkit => .driverkit,
2676 .ios => .ios,
2677 .maccatalyst => .maccatalyst,
2678 .macos => .macos,
2679 .tvos => .tvos,
2680 .visionos => .visionos,
2681 .watchos => .watchos,
2682 .windows => .windows,
2683 .uefi => .uefi,
2684 .@"3ds" => .@"3ds",
2685 .wiiu => .wiiu,
2686 .@"switch" => .@"switch",
2687 .psx => .psx,
2688 .ps3 => .ps3,
2689 .ps4 => .ps4,
2690 .ps5 => .ps5,
2691 .psp => .psp,
2692 .vita => .vita,
2693 .emscripten => .emscripten,
2694 .wasi => .wasi,
2695 .amdhsa => .amdhsa,
2696 .amdpal => .amdpal,
2697 .cuda => .cuda,
2698 .mesa3d => .mesa3d,
2699 .nvcl => .nvcl,
2700 .opencl => .opencl,
2701 .opengl => .opengl,
2702 .vulkan => .vulkan,
2703 .tios => .tios,
2704 .ashetos => .ashetos,
2496 inline else => |tag| @field(@This(), @tagName(tag)),
27052497 };
27062498 }
27072499
27082500 pub fn unwrap(this: @This()) ?std.Target.Os.Tag {
27092501 return switch (this) {
2710 .freestanding => .freestanding,
2711 .other => .other,
2712 .contiki => .contiki,
2713 .fuchsia => .fuchsia,
2714 .hermit => .hermit,
2715 .managarm => .managarm,
2716 .haiku => .haiku,
2717 .hurd => .hurd,
2718 .illumos => .illumos,
2719 .linux => .linux,
2720 .plan9 => .plan9,
2721 .rtems => .rtems,
2722 .serenity => .serenity,
2723 .dragonfly => .dragonfly,
2724 .freebsd => .freebsd,
2725 .netbsd => .netbsd,
2726 .openbsd => .openbsd,
2727 .driverkit => .driverkit,
2728 .ios => .ios,
2729 .maccatalyst => .maccatalyst,
2730 .macos => .macos,
2731 .tvos => .tvos,
2732 .visionos => .visionos,
2733 .watchos => .watchos,
2734 .windows => .windows,
2735 .uefi => .uefi,
2736 .@"3ds" => .@"3ds",
2737 .wiiu => .wiiu,
2738 .@"switch" => .@"switch",
2739 .psx => .psx,
2740 .ps3 => .ps3,
2741 .ps4 => .ps4,
2742 .ps5 => .ps5,
2743 .psp => .psp,
2744 .vita => .vita,
2745 .emscripten => .emscripten,
2746 .wasi => .wasi,
2747 .amdhsa => .amdhsa,
2748 .amdpal => .amdpal,
2749 .cuda => .cuda,
2750 .mesa3d => .mesa3d,
2751 .nvcl => .nvcl,
2752 .opencl => .opencl,
2753 .opengl => .opengl,
2754 .vulkan => .vulkan,
2755 .tios => .tios,
2756 .ashetos => .ashetos,
2757
2502 inline else => |tag| @field(std.Target.Os.Tag, @tagName(tag)),
27582503 .default => null,
27592504 };
27602505 }
......@@ -2775,30 +2520,13 @@ pub const TargetQuery = struct {
27752520
27762521 pub fn init(x: ?std.Target.ObjectFormat) @This() {
27772522 return switch (x orelse return .default) {
2778 .c => .c,
2779 .coff => .coff,
2780 .elf => .elf,
2781 .hex => .hex,
2782 .macho => .macho,
2783 .plan9 => .plan9,
2784 .raw => .raw,
2785 .spirv => .spirv,
2786 .wasm => .wasm,
2523 inline else => |tag| @field(@This(), @tagName(tag)),
27872524 };
27882525 }
27892526
27902527 pub fn unwrap(this: @This()) ?std.Target.ObjectFormat {
27912528 return switch (this) {
2792 .c => .c,
2793 .coff => .coff,
2794 .elf => .elf,
2795 .hex => .hex,
2796 .macho => .macho,
2797 .plan9 => .plan9,
2798 .raw => .raw,
2799 .spirv => .spirv,
2800 .wasm => .wasm,
2801
2529 inline else => |tag| @field(std.Target.ObjectFormat, @tagName(tag)),
28022530 .default => null,
28032531 };
28042532 }
......@@ -3475,6 +3203,7 @@ pub fn load(arena: Allocator, reader: *Io.Reader) LoadError!Configuration {
34753203 .system_integrations = try arena.alloc(SystemIntegration, header.system_integrations_len),
34763204 .available_options = try arena.alloc(AvailableOption, header.available_options_len),
34773205 .search_prefixes = try arena.alloc(String, header.search_prefixes_len),
3206 .packages = try arena.alloc(Package, header.packages_len),
34783207 .extra = try arena.alloc(u32, header.extra_len),
34793208 .default_step = header.default_step,
34803209 .generated_files_len = header.generated_files_len,
......@@ -3488,6 +3217,7 @@ pub fn load(arena: Allocator, reader: *Io.Reader) LoadError!Configuration {
34883217 @ptrCast(result.system_integrations),
34893218 @ptrCast(result.available_options),
34903219 @ptrCast(result.search_prefixes),
3220 @ptrCast(result.packages),
34913221 @ptrCast(result.extra),
34923222 };
34933223 try reader.readVecAll(&vecs);
lib/std/Build/Serialize.zig+68-18
......@@ -10,7 +10,8 @@ const log = std.log;
1010arena: Allocator,
1111wc: *Configuration.Wip,
1212module_map: std.array_hash_map.Auto(*std.Build.Module, Configuration.Module.Index) = .empty,
13package_map: std.array_hash_map.Auto(*std.Build, Configuration.Package.Index) = .empty,
13/// Keyed by package hash.
14package_map: std.array_hash_map.String(Configuration.Package.Index) = .empty,
1415/// Index corresponds to `Configuration.steps` index.
1516step_map: std.array_hash_map.Auto(*Step, void) = .empty,
1617
......@@ -21,6 +22,10 @@ pub fn write(b: *std.Build, wc: *Configuration.Wip, writer: *std.Io.Writer) !voi
2122
2223 var s: Serialize = .{ .wc = wc, .arena = arena };
2324
25 // Serialize all of the packages first to seed the package_map, which is
26 // later used in calls to packageFromHash.
27 try s.addRootPackage(b);
28
2429 try wc.path_deps.ensureTotalCapacityPrecise(gpa, graph.configure_dependencies.items.len);
2530 for (
2631 graph.configure_dependencies.items,
......@@ -44,10 +49,10 @@ pub fn write(b: *std.Build, wc: *Configuration.Wip, writer: *std.Io.Writer) !voi
4449 .relative => |r| try wc.addString(r.sub_path),
4550 },
4651 .pkg = switch (src.lazy_path) {
47 .src_path => |sp| .init(try s.builderToPackage(sp.owner)),
52 .src_path => |sp| .init(s.packageFromHash(sp.owner.pkg_hash)),
4853 .generated => unreachable,
4954 .cwd_relative, .relative => .none,
50 .dependency => |d| .init(try s.builderToPackage(d.dependency.builder)),
55 .dependency => |d| .init(s.packageFromHash(d.dependency.builder.pkg_hash)),
5156 },
5257 };
5358 }
......@@ -84,7 +89,7 @@ pub fn write(b: *std.Build, wc: *Configuration.Wip, writer: *std.Io.Writer) !voi
8489 try wc.steps.ensureTotalCapacity(gpa, s.step_map.entries.capacity);
8590 wc.steps.appendAssumeCapacity(.{
8691 .name = try wc.addString(step.name),
87 .owner = try s.builderToPackage(step.owner),
92 .owner = s.packageFromHash(step.owner.pkg_hash),
8893 .deps = deps,
8994 .max_rss = .fromBytes(step.max_rss),
9095 .extended = @fromBackingInt(@intCast(switch (step.tag) {
......@@ -722,19 +727,64 @@ pub fn packageOptions(b: *std.Build, wc: *Configuration.Wip) Allocator.Error!voi
722727 }
723728}
724729
725fn builderToPackage(s: *Serialize, b: *std.Build) !Configuration.Package.Index {
726 if (b.pkg_hash.len == 0) return .root;
730fn addRootPackage(s: *Serialize, b: *std.Build) Allocator.Error!void {
727731 const arena = s.arena;
728732 const wc = s.wc;
729 const gop = try s.package_map.getOrPut(arena, b);
730 if (!gop.found_existing) {
731 gop.value_ptr.* = try wc.addExtra(Configuration.Package, .{
732 .hash = try wc.addString(b.pkg_hash),
733 .dep_prefix = try wc.addString(b.dep_prefix),
734 .root_path = try wc.addString(try b.root.toString(arena)),
735 });
736 }
737 return gop.value_ptr.*;
733
734 try wc.packages.append(wc.gpa, .{
735 .dep_prefix = .empty,
736 .hash = .empty,
737 .root_path = try wc.addString(try b.root.toString(arena)),
738 .deps = undefined,
739 });
740
741 const deps = try arena.alloc(Configuration.Package.Dep, b.available_deps.len);
742 for (deps, b.available_deps) |*dest, src| dest.* = try s.makePackageDep("", src[0], src[1]);
743
744 wc.packages.items[0].deps = try wc.addExtra(Configuration.Package.Dep.List, .{
745 .deps = .{ .slice = deps },
746 });
747}
748
749fn makePackageDep(s: *Serialize, parent_dep_prefix: []const u8, name: []const u8, hash: []const u8) Allocator.Error!Configuration.Package.Dep {
750 const arena = s.arena;
751 const wc = s.wc;
752
753 if (s.package_map.get(hash)) |index| return .{
754 .name = try wc.addString(name),
755 .package = index,
756 };
757
758 const entry = std.Build.package_map.get(hash) orelse unreachable;
759
760 const dep_prefix = try arena.print("{s}{s}.", .{ parent_dep_prefix, name });
761
762 const index: Configuration.Package.Index = @fromBackingInt(@intCast(wc.packages.items.len));
763 try s.package_map.put(arena, hash, index);
764
765 try wc.packages.append(wc.gpa, .{
766 .dep_prefix = try wc.addString(dep_prefix),
767 .hash = try wc.addString(hash),
768 .root_path = try wc.addString(entry.build_root),
769 .deps = undefined,
770 });
771
772 const deps = try arena.alloc(Configuration.Package.Dep, entry.deps.len);
773 for (deps, entry.deps) |*dest, src| dest.* = try s.makePackageDep(dep_prefix, src[0], src[1]);
774
775 wc.packages.items[@backingInt(index)].deps = try wc.addExtra(Configuration.Package.Dep.List, .{
776 .deps = .{ .slice = deps },
777 });
778
779 return .{
780 .name = try wc.addString(name),
781 .package = index,
782 };
783}
784
785fn packageFromHash(s: *Serialize, pkg_hash: []const u8) Configuration.Package.Index {
786 if (pkg_hash.len == 0) return .root;
787 return s.package_map.get(pkg_hash) orelse std.debug.panic("unrecognized package hash: {q}", .{pkg_hash});
738788}
739789
740790fn addOptionalLazyPathEnum(s: *Serialize, lp: ?std.Build.LazyPath) !Configuration.LazyPath.OptionalIndex {
......@@ -743,7 +793,7 @@ fn addOptionalLazyPathEnum(s: *Serialize, lp: ?std.Build.LazyPath) !Configuratio
743793 .src_path => |src_path| i: {
744794 const sub_path = try wc.addString(src_path.sub_path);
745795 break :i try wc.addExtraErased(Configuration.LazyPath.SourcePath, .{
746 .owner = try s.builderToPackage(src_path.owner),
796 .owner = s.packageFromHash(src_path.owner.pkg_hash),
747797 .sub_path = sub_path,
748798 });
749799 },
......@@ -771,7 +821,7 @@ fn addOptionalLazyPathEnum(s: *Serialize, lp: ?std.Build.LazyPath) !Configuratio
771821 .dependency => |dependency| i: {
772822 const sub_path = try wc.addString(dependency.sub_path);
773823 break :i try wc.addExtraErased(Configuration.LazyPath.SourcePath, .{
774 .owner = try s.builderToPackage(dependency.dependency.builder),
824 .owner = s.packageFromHash(dependency.dependency.builder.pkg_hash),
775825 .sub_path = sub_path,
776826 });
777827 },
......@@ -1231,7 +1281,7 @@ fn addModule(s: *Serialize, m: *std.Build.Module) !Configuration.Module.Index {
12311281 .link_libcpp = .init(m.link_libcpp),
12321282 .no_builtin = .init(m.no_builtin),
12331283 },
1234 .owner = try s.builderToPackage(m.owner),
1284 .owner = s.packageFromHash(m.owner.pkg_hash),
12351285 .root_source_file = try s.addOptionalLazyPathEnum(m.root_source_file),
12361286 .import_table = .invalid,
12371287 .resolved_target = try addOptionalResolvedTarget(wc, m.resolved_target),