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(...@@ -3325,17 +3325,19 @@ pub fn packagePath(
3325) Allocator.Error!Path {3325) Allocator.Error!Path {
3326 const c = &maker.scanned_config.configuration;3326 const c = &maker.scanned_config.configuration;
3327 const graph = maker.graph;3327 const graph = maker.graph;
3328 const package = package_index.get(c) orelse return .{3328
3329 if (package_index == .root) return .{
3329 .root_dir = graph.build_root_directory,3330 .root_dir = graph.build_root_directory,
3330 .sub_path = sub_path,3331 .sub_path = sub_path,
3331 };3332 };
3333
3332 // Currently, neither configurer nor Maker is aware of the standard zig3334 // Currently, neither configurer nor Maker is aware of the standard zig
3333 // package path, and the root path is stored as a bare string rather than3335 // package path, and the root path is stored as a bare string rather than
3334 // relative to a known base directory. Without changing that, we must3336 // relative to a known base directory. Without changing that, we must
3335 // construct a cwd relative path here.3337 // construct a cwd relative path here.
3336 return .{3338 return .{
3337 .root_dir = .cwd(),3339 .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 }),
3339 };3341 };
3340}3342}
33413343
...@@ -3965,7 +3967,7 @@ fn confPathDepToCachePath(...@@ -3965,7 +3967,7 @@ fn confPathDepToCachePath(
3965 .root_dir = graph.build_root_directory,3967 .root_dir = graph.build_root_directory,
3966 .sub_path = switch (path_dep.pkg.unwrap().?) {3968 .sub_path = switch (path_dep.pkg.unwrap().?) {
3967 .root => sub_path,3969 .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 }),
3969 },3971 },
3970 },3972 },
3971 .zig_lib => .{3973 .zig_lib => .{
lib/compiler/Maker/ScannedConfig.zig+21
...@@ -83,6 +83,27 @@ pub fn print(sc: *const ScannedConfig, w: *Writer) Writer.Error!void {...@@ -83,6 +83,27 @@ pub fn print(sc: *const ScannedConfig, w: *Writer) Writer.Error!void {
83 try tf.end();83 try tf.end();
84 }84 }
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
86 try s.end();107 try s.end();
87}108}
88109
lib/std/Build.zig+3-2
...@@ -2144,7 +2144,7 @@ pub fn dependencyLazy(b: *Build, name: []const u8, args: anytype) error{LazyDepe...@@ -2144,7 +2144,7 @@ pub fn dependencyLazy(b: *Build, name: []const u8, args: anytype) error{LazyDepe
2144 return dependencyResolved(b, name, entry, userInputOptionsFromArgs(b.graph.arena, args));2144 return dependencyResolved(b, name, entry, userInputOptionsFromArgs(b.graph.arena, args));
2145}2145}
21462146
2147const PackageEntry = struct {2147pub const PackageEntry = struct {
2148 hash: []const u8,2148 hash: []const u8,
2149 available: bool,2149 available: bool,
2150 build_root: []const u8,2150 build_root: []const u8,
...@@ -2152,7 +2152,8 @@ const PackageEntry = struct {...@@ -2152,7 +2152,8 @@ const PackageEntry = struct {
2152 run_build: ?*const fn (*Build) void,2152 run_build: ?*const fn (*Build) void,
2153};2153};
21542154
2155const package_map: std.StaticStringMap(PackageEntry) = blk: {2155/// Build system implementation detail.
2156pub const package_map: std.StaticStringMap(PackageEntry) = blk: {
2156 const deps = @import("root").dependencies;2157 const deps = @import("root").dependencies;
2157 const decl_names = @typeInfo(deps.packages).@"struct".decl_names;2158 const decl_names = @typeInfo(deps.packages).@"struct".decl_names;
2158 var kvs: [decl_names.len]struct { []const u8, PackageEntry } = undefined;2159 var kvs: [decl_names.len]struct { []const u8, PackageEntry } = undefined;
lib/std/Build/Configuration.zig+51-321
...@@ -15,6 +15,8 @@ unlazy_deps: []String,...@@ -15,6 +15,8 @@ unlazy_deps: []String,
15system_integrations: []SystemIntegration,15system_integrations: []SystemIntegration,
16available_options: []AvailableOption,16available_options: []AvailableOption,
17search_prefixes: []String,17search_prefixes: []String,
18/// Index 0 always exists and is the root package.
19packages: []Package,
18extra: []u32,20extra: []u32,
19default_step: Step.Index,21default_step: Step.Index,
20generated_files_len: u32,22generated_files_len: u32,
...@@ -30,6 +32,7 @@ pub const Header = extern struct {...@@ -30,6 +32,7 @@ pub const Header = extern struct {
30 system_integrations_len: u32,32 system_integrations_len: u32,
31 available_options_len: u32,33 available_options_len: u32,
32 search_prefixes_len: u32,34 search_prefixes_len: u32,
35 packages_len: u32,
33 extra_len: u32,36 extra_len: u32,
3437
35 default_step: Step.Index,38 default_step: Step.Index,
...@@ -58,6 +61,7 @@ pub const Wip = struct {...@@ -58,6 +61,7 @@ pub const Wip = struct {
58 steps: std.ArrayList(Step) = .empty,61 steps: std.ArrayList(Step) = .empty,
59 path_deps: std.ArrayList(PathDep) = .empty,62 path_deps: std.ArrayList(PathDep) = .empty,
60 search_prefixes: std.ArrayList(String) = .empty,63 search_prefixes: std.ArrayList(String) = .empty,
64 packages: std.ArrayList(Package) = .empty,
61 extra: std.ArrayList(u32) = .empty,65 extra: std.ArrayList(u32) = .empty,
62 next_generated_file_index: u32 = 0,66 next_generated_file_index: u32 = 0,
63 cache_poison: bool = false,67 cache_poison: bool = false,
...@@ -139,6 +143,7 @@ pub const Wip = struct {...@@ -139,6 +143,7 @@ pub const Wip = struct {
139 wip.steps.deinit(gpa);143 wip.steps.deinit(gpa);
140 wip.path_deps.deinit(gpa);144 wip.path_deps.deinit(gpa);
141 wip.search_prefixes.deinit(gpa);145 wip.search_prefixes.deinit(gpa);
146 wip.packages.deinit(gpa);
142 wip.extra.deinit(gpa);147 wip.extra.deinit(gpa);
143 wip.* = undefined;148 wip.* = undefined;
144 }149 }
...@@ -158,6 +163,7 @@ pub const Wip = struct {...@@ -158,6 +163,7 @@ pub const Wip = struct {
158 .system_integrations_len = @intCast(wip.system_integrations.items.len),163 .system_integrations_len = @intCast(wip.system_integrations.items.len),
159 .available_options_len = @intCast(wip.available_options.items.len),164 .available_options_len = @intCast(wip.available_options.items.len),
160 .search_prefixes_len = @intCast(wip.search_prefixes.items.len),165 .search_prefixes_len = @intCast(wip.search_prefixes.items.len),
166 .packages_len = @intCast(wip.packages.items.len),
161 .extra_len = @intCast(wip.extra.items.len),167 .extra_len = @intCast(wip.extra.items.len),
162168
163 .default_step = static.default_step,169 .default_step = static.default_step,
...@@ -175,6 +181,7 @@ pub const Wip = struct {...@@ -175,6 +181,7 @@ pub const Wip = struct {
175 @ptrCast(wip.system_integrations.items),181 @ptrCast(wip.system_integrations.items),
176 @ptrCast(wip.available_options.items),182 @ptrCast(wip.available_options.items),
177 @ptrCast(wip.search_prefixes.items),183 @ptrCast(wip.search_prefixes.items),
184 @ptrCast(wip.packages.items),
178 @ptrCast(wip.extra.items),185 @ptrCast(wip.extra.items),
179 };186 };
180 try w.writeVecAll(&buffers);187 try w.writeVecAll(&buffers);
...@@ -1602,30 +1609,28 @@ pub const OptionalGeneratedFileIndex = enum(u32) {...@@ -1602,30 +1609,28 @@ pub const OptionalGeneratedFileIndex = enum(u32) {
1602 }1609 }
1603};1610};
16041611
1605pub const Package = struct {1612pub const Package = extern struct {
1606 dep_prefix: String,1613 dep_prefix: String,
1607 hash: String,1614 hash: String,
1608 root_path: String,1615 root_path: String,
1616 deps: Dep.List.Index,
16091617
1610 pub const Index = enum(u32) {1618 pub const Index = enum(u32) {
1611 root = max_u32,1619 root,
1612 _,1620 _,
16131621
1614 /// Returns `null` for root package.1622 pub fn ptr(i: @This(), c: *const Configuration) *const Package {
1615 pub fn get(i: @This(), c: *const Configuration) ?Package {1623 return &c.packages[@backingInt(i)];
1616 if (i == .root) return null;
1617 return extraData(c, Package, @backingInt(i));
1618 }1624 }
16191625
1620 pub fn depPrefixSlice(i: @This(), c: *const Configuration) [:0]const u8 {1626 pub fn depPrefixSlice(i: @This(), c: *const Configuration) [:0]const u8 {
1621 const package = get(i, c) orelse return "";1627 return ptr(i, c).dep_prefix.slice(c);
1622 return package.dep_prefix.slice(c);
1623 }1628 }
1624 };1629 };
16251630
1626 pub const OptionalIndex = enum(u32) {1631 pub const OptionalIndex = enum(u32) {
1627 none = max_u32 - 1,1632 root,
1628 root = max_u32,1633 none = max_u32,
1629 _,1634 _,
16301635
1631 pub fn init(i: Index) OptionalIndex {1636 pub fn init(i: Index) OptionalIndex {
...@@ -1642,6 +1647,28 @@ pub const Package = struct {...@@ -1642,6 +1647,28 @@ pub const Package = struct {
1642 };1647 };
1643 }1648 }
1644 };1649 };
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 };
1645};1672};
16461673
1647pub const Module = struct {1674pub const Module = struct {
...@@ -2126,27 +2153,18 @@ pub const OptionalCSourceLanguage = enum(u3) {...@@ -2126,27 +2153,18 @@ pub const OptionalCSourceLanguage = enum(u3) {
2126 objective_cpp,2153 objective_cpp,
2127 assembly,2154 assembly,
2128 assembly_with_preprocessor,2155 assembly_with_preprocessor,
2156
2129 default,2157 default,
21302158
2131 pub fn init(x: ?std.Build.Module.CSourceLanguage) @This() {2159 pub fn init(x: ?std.Build.Module.CSourceLanguage) @This() {
2132 return switch (x orelse return .default) {2160 return switch (x orelse return .default) {
2133 .c => .c,2161 inline else => |tag| @field(@This(), @tagName(tag)),
2134 .cpp => .cpp,
2135 .objective_c => .objective_c,
2136 .objective_cpp => .objective_cpp,
2137 .assembly => .assembly,
2138 .assembly_with_preprocessor => .assembly_with_preprocessor,
2139 };2162 };
2140 }2163 }
21412164
2142 pub fn get(this: @This()) ?std.Build.Module.CSourceLanguage {2165 pub fn get(this: @This()) ?std.Build.Module.CSourceLanguage {
2143 return switch (this) {2166 return switch (this) {
2144 .c => .c,2167 inline else => |tag| @field(std.Build.Module.CSourceLanguage, @tagName(tag)),
2145 .cpp => .cpp,
2146 .objective_c => .objective_c,
2147 .objective_cpp => .objective_cpp,
2148 .assembly => .assembly,
2149 .assembly_with_preprocessor => .assembly_with_preprocessor,
2150 .default => null,2168 .default => null,
2151 };2169 };
2152 }2170 }
...@@ -2274,10 +2292,7 @@ pub const TargetQuery = struct {...@@ -2274,10 +2292,7 @@ pub const TargetQuery = struct {
22742292
2275 pub fn init(x: std.Target.Query.CpuModel) @This() {2293 pub fn init(x: std.Target.Query.CpuModel) @This() {
2276 return switch (x) {2294 return switch (x) {
2277 .native => .native,2295 inline else => |_, tag| @field(@This(), @tagName(tag)),
2278 .baseline => .baseline,
2279 .determined_by_arch_os => .determined_by_arch_os,
2280 .explicit => .explicit,
2281 };2296 };
2282 }2297 }
2283 };2298 };
...@@ -2335,71 +2350,13 @@ pub const TargetQuery = struct {...@@ -2335,71 +2350,13 @@ pub const TargetQuery = struct {
23352350
2336 pub fn init(x: ?std.Target.Abi) @This() {2351 pub fn init(x: ?std.Target.Abi) @This() {
2337 return switch (x orelse return .default) {2352 return switch (x orelse return .default) {
2338 .none => .none,2353 inline else => |tag| @field(@This(), @tagName(tag)),
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,
2368 };2354 };
2369 }2355 }
23702356
2371 pub fn unwrap(this: @This()) ?std.Target.Abi {2357 pub fn unwrap(this: @This()) ?std.Target.Abi {
2372 return switch (this) {2358 return switch (this) {
2373 .none => .none,2359 inline else => |tag| @field(std.Target.Abi, @tagName(tag)),
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,
2403 .default => null,2360 .default => null,
2404 };2361 };
2405 }2362 }
...@@ -2471,132 +2428,13 @@ pub const TargetQuery = struct {...@@ -2471,132 +2428,13 @@ pub const TargetQuery = struct {
24712428
2472 pub fn init(x: ?std.Target.Cpu.Arch) @This() {2429 pub fn init(x: ?std.Target.Cpu.Arch) @This() {
2473 return switch (x orelse return .default) {2430 return switch (x orelse return .default) {
2474 .aarch64 => .aarch64,2431 inline else => |tag| @field(@This(), @tagName(tag)),
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,
2534 };2432 };
2535 }2433 }
25362434
2537 pub fn unwrap(this: @This()) ?std.Target.Cpu.Arch {2435 pub fn unwrap(this: @This()) ?std.Target.Cpu.Arch {
2538 return switch (this) {2436 return switch (this) {
2539 .aarch64 => .aarch64,2437 inline else => |tag| @field(std.Target.Cpu.Arch, @tagName(tag)),
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
2600 .default => null,2438 .default => null,
2601 };2439 };
2602 }2440 }
...@@ -2655,106 +2493,13 @@ pub const TargetQuery = struct {...@@ -2655,106 +2493,13 @@ pub const TargetQuery = struct {
26552493
2656 pub fn init(x: ?std.Target.Os.Tag) @This() {2494 pub fn init(x: ?std.Target.Os.Tag) @This() {
2657 return switch (x orelse return .default) {2495 return switch (x orelse return .default) {
2658 .freestanding => .freestanding,2496 inline else => |tag| @field(@This(), @tagName(tag)),
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,
2705 };2497 };
2706 }2498 }
27072499
2708 pub fn unwrap(this: @This()) ?std.Target.Os.Tag {2500 pub fn unwrap(this: @This()) ?std.Target.Os.Tag {
2709 return switch (this) {2501 return switch (this) {
2710 .freestanding => .freestanding,2502 inline else => |tag| @field(std.Target.Os.Tag, @tagName(tag)),
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
2758 .default => null,2503 .default => null,
2759 };2504 };
2760 }2505 }
...@@ -2775,30 +2520,13 @@ pub const TargetQuery = struct {...@@ -2775,30 +2520,13 @@ pub const TargetQuery = struct {
27752520
2776 pub fn init(x: ?std.Target.ObjectFormat) @This() {2521 pub fn init(x: ?std.Target.ObjectFormat) @This() {
2777 return switch (x orelse return .default) {2522 return switch (x orelse return .default) {
2778 .c => .c,2523 inline else => |tag| @field(@This(), @tagName(tag)),
2779 .coff => .coff,
2780 .elf => .elf,
2781 .hex => .hex,
2782 .macho => .macho,
2783 .plan9 => .plan9,
2784 .raw => .raw,
2785 .spirv => .spirv,
2786 .wasm => .wasm,
2787 };2524 };
2788 }2525 }
27892526
2790 pub fn unwrap(this: @This()) ?std.Target.ObjectFormat {2527 pub fn unwrap(this: @This()) ?std.Target.ObjectFormat {
2791 return switch (this) {2528 return switch (this) {
2792 .c => .c,2529 inline else => |tag| @field(std.Target.ObjectFormat, @tagName(tag)),
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
2802 .default => null,2530 .default => null,
2803 };2531 };
2804 }2532 }
...@@ -3475,6 +3203,7 @@ pub fn load(arena: Allocator, reader: *Io.Reader) LoadError!Configuration {...@@ -3475,6 +3203,7 @@ pub fn load(arena: Allocator, reader: *Io.Reader) LoadError!Configuration {
3475 .system_integrations = try arena.alloc(SystemIntegration, header.system_integrations_len),3203 .system_integrations = try arena.alloc(SystemIntegration, header.system_integrations_len),
3476 .available_options = try arena.alloc(AvailableOption, header.available_options_len),3204 .available_options = try arena.alloc(AvailableOption, header.available_options_len),
3477 .search_prefixes = try arena.alloc(String, header.search_prefixes_len),3205 .search_prefixes = try arena.alloc(String, header.search_prefixes_len),
3206 .packages = try arena.alloc(Package, header.packages_len),
3478 .extra = try arena.alloc(u32, header.extra_len),3207 .extra = try arena.alloc(u32, header.extra_len),
3479 .default_step = header.default_step,3208 .default_step = header.default_step,
3480 .generated_files_len = header.generated_files_len,3209 .generated_files_len = header.generated_files_len,
...@@ -3488,6 +3217,7 @@ pub fn load(arena: Allocator, reader: *Io.Reader) LoadError!Configuration {...@@ -3488,6 +3217,7 @@ pub fn load(arena: Allocator, reader: *Io.Reader) LoadError!Configuration {
3488 @ptrCast(result.system_integrations),3217 @ptrCast(result.system_integrations),
3489 @ptrCast(result.available_options),3218 @ptrCast(result.available_options),
3490 @ptrCast(result.search_prefixes),3219 @ptrCast(result.search_prefixes),
3220 @ptrCast(result.packages),
3491 @ptrCast(result.extra),3221 @ptrCast(result.extra),
3492 };3222 };
3493 try reader.readVecAll(&vecs);3223 try reader.readVecAll(&vecs);
lib/std/Build/Serialize.zig+68-18
...@@ -10,7 +10,8 @@ const log = std.log;...@@ -10,7 +10,8 @@ const log = std.log;
10arena: Allocator,10arena: Allocator,
11wc: *Configuration.Wip,11wc: *Configuration.Wip,
12module_map: std.array_hash_map.Auto(*std.Build.Module, Configuration.Module.Index) = .empty,12module_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,
14/// Index corresponds to `Configuration.steps` index.15/// Index corresponds to `Configuration.steps` index.
15step_map: std.array_hash_map.Auto(*Step, void) = .empty,16step_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...@@ -21,6 +22,10 @@ pub fn write(b: *std.Build, wc: *Configuration.Wip, writer: *std.Io.Writer) !voi
2122
22 var s: Serialize = .{ .wc = wc, .arena = arena };23 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
24 try wc.path_deps.ensureTotalCapacityPrecise(gpa, graph.configure_dependencies.items.len);29 try wc.path_deps.ensureTotalCapacityPrecise(gpa, graph.configure_dependencies.items.len);
25 for (30 for (
26 graph.configure_dependencies.items,31 graph.configure_dependencies.items,
...@@ -44,10 +49,10 @@ pub fn write(b: *std.Build, wc: *Configuration.Wip, writer: *std.Io.Writer) !voi...@@ -44,10 +49,10 @@ pub fn write(b: *std.Build, wc: *Configuration.Wip, writer: *std.Io.Writer) !voi
44 .relative => |r| try wc.addString(r.sub_path),49 .relative => |r| try wc.addString(r.sub_path),
45 },50 },
46 .pkg = switch (src.lazy_path) {51 .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)),
48 .generated => unreachable,53 .generated => unreachable,
49 .cwd_relative, .relative => .none,54 .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)),
51 },56 },
52 };57 };
53 }58 }
...@@ -84,7 +89,7 @@ pub fn write(b: *std.Build, wc: *Configuration.Wip, writer: *std.Io.Writer) !voi...@@ -84,7 +89,7 @@ pub fn write(b: *std.Build, wc: *Configuration.Wip, writer: *std.Io.Writer) !voi
84 try wc.steps.ensureTotalCapacity(gpa, s.step_map.entries.capacity);89 try wc.steps.ensureTotalCapacity(gpa, s.step_map.entries.capacity);
85 wc.steps.appendAssumeCapacity(.{90 wc.steps.appendAssumeCapacity(.{
86 .name = try wc.addString(step.name),91 .name = try wc.addString(step.name),
87 .owner = try s.builderToPackage(step.owner),92 .owner = s.packageFromHash(step.owner.pkg_hash),
88 .deps = deps,93 .deps = deps,
89 .max_rss = .fromBytes(step.max_rss),94 .max_rss = .fromBytes(step.max_rss),
90 .extended = @fromBackingInt(@intCast(switch (step.tag) {95 .extended = @fromBackingInt(@intCast(switch (step.tag) {
...@@ -722,19 +727,64 @@ pub fn packageOptions(b: *std.Build, wc: *Configuration.Wip) Allocator.Error!voi...@@ -722,19 +727,64 @@ pub fn packageOptions(b: *std.Build, wc: *Configuration.Wip) Allocator.Error!voi
722 }727 }
723}728}
724729
725fn builderToPackage(s: *Serialize, b: *std.Build) !Configuration.Package.Index {730fn addRootPackage(s: *Serialize, b: *std.Build) Allocator.Error!void {
726 if (b.pkg_hash.len == 0) return .root;
727 const arena = s.arena;731 const arena = s.arena;
728 const wc = s.wc;732 const wc = s.wc;
729 const gop = try s.package_map.getOrPut(arena, b);733
730 if (!gop.found_existing) {734 try wc.packages.append(wc.gpa, .{
731 gop.value_ptr.* = try wc.addExtra(Configuration.Package, .{735 .dep_prefix = .empty,
732 .hash = try wc.addString(b.pkg_hash),736 .hash = .empty,
733 .dep_prefix = try wc.addString(b.dep_prefix),737 .root_path = try wc.addString(try b.root.toString(arena)),
734 .root_path = try wc.addString(try b.root.toString(arena)),738 .deps = undefined,
735 });739 });
736 }740
737 return gop.value_ptr.*;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});
738}788}
739789
740fn addOptionalLazyPathEnum(s: *Serialize, lp: ?std.Build.LazyPath) !Configuration.LazyPath.OptionalIndex {790fn addOptionalLazyPathEnum(s: *Serialize, lp: ?std.Build.LazyPath) !Configuration.LazyPath.OptionalIndex {
...@@ -743,7 +793,7 @@ fn addOptionalLazyPathEnum(s: *Serialize, lp: ?std.Build.LazyPath) !Configuratio...@@ -743,7 +793,7 @@ fn addOptionalLazyPathEnum(s: *Serialize, lp: ?std.Build.LazyPath) !Configuratio
743 .src_path => |src_path| i: {793 .src_path => |src_path| i: {
744 const sub_path = try wc.addString(src_path.sub_path);794 const sub_path = try wc.addString(src_path.sub_path);
745 break :i try wc.addExtraErased(Configuration.LazyPath.SourcePath, .{795 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),
747 .sub_path = sub_path,797 .sub_path = sub_path,
748 });798 });
749 },799 },
...@@ -771,7 +821,7 @@ fn addOptionalLazyPathEnum(s: *Serialize, lp: ?std.Build.LazyPath) !Configuratio...@@ -771,7 +821,7 @@ fn addOptionalLazyPathEnum(s: *Serialize, lp: ?std.Build.LazyPath) !Configuratio
771 .dependency => |dependency| i: {821 .dependency => |dependency| i: {
772 const sub_path = try wc.addString(dependency.sub_path);822 const sub_path = try wc.addString(dependency.sub_path);
773 break :i try wc.addExtraErased(Configuration.LazyPath.SourcePath, .{823 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),
775 .sub_path = sub_path,825 .sub_path = sub_path,
776 });826 });
777 },827 },
...@@ -1231,7 +1281,7 @@ fn addModule(s: *Serialize, m: *std.Build.Module) !Configuration.Module.Index {...@@ -1231,7 +1281,7 @@ fn addModule(s: *Serialize, m: *std.Build.Module) !Configuration.Module.Index {
1231 .link_libcpp = .init(m.link_libcpp),1281 .link_libcpp = .init(m.link_libcpp),
1232 .no_builtin = .init(m.no_builtin),1282 .no_builtin = .init(m.no_builtin),
1233 },1283 },
1234 .owner = try s.builderToPackage(m.owner),1284 .owner = s.packageFromHash(m.owner.pkg_hash),
1235 .root_source_file = try s.addOptionalLazyPathEnum(m.root_source_file),1285 .root_source_file = try s.addOptionalLazyPathEnum(m.root_source_file),
1236 .import_table = .invalid,1286 .import_table = .invalid,
1237 .resolved_target = try addOptionalResolvedTarget(wc, m.resolved_target),1287 .resolved_target = try addOptionalResolvedTarget(wc, m.resolved_target),