authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-03-08 22:42:41-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-05-25 18:54:34-07:00
logeaffd5551349be6132ab33827e307f28ca8ac051
tree51cbb7ed774b3c949f00b07b0d732b492c9f35ed
parent8f36a83b45eedef92b3fcda605e0ccb3828ddbd3

maker: progress towards lowering Compile Step CLI args

next thing to do is figure out how LazyPath is supposed to work now. something like this: * each Step that provides LazyPath objects has a setLazyPath and getLazyPath function which takes a tagged union identifying which one to access * steps that fulfill LazyPath objects can freely call setLazyPath without obtaining a lock because the dependency graph prevents simultaneous access. * similarly, steps that access LazyPath results can freely call getLazyPath without obtaining a lock, because after modification, there may be simultaneous reads from dependencies but they will all be read-only * a fulfilled LazyPath object is a read-only std.Build.Cache.Path.

6 files changed, 431 insertions(+), 304 deletions(-)

lib/compiler/Maker/ScannedConfig.zig+1-1
......@@ -135,7 +135,7 @@ fn printValue(sc: *const ScannedConfig, s: *Serializer, comptime Field: type, fi
135135 .extended => @compileError("TODO"),
136136 .union_list => {
137137 var slice_field = try s.beginTuple(.{});
138 for (field_value.get(c.extra), 0..) |elem, i| switch (field_value.tag(c.extra, i)) {
138 for (field_value.slice(c.extra), 0..) |elem, i| switch (field_value.tag(c.extra, i)) {
139139 inline else => |tag| {
140140 var sub_struct = try s.beginStruct(.{});
141141 try sub_struct.fieldPrefix(@tagName(tag));
lib/compiler/Maker/Step.zig+5-4
......@@ -316,13 +316,14 @@ pub fn captureChildProcess(
316316 return result;
317317}
318318
319pub fn fail(step: *Step, comptime fmt: []const u8, args: anytype) error{ OutOfMemory, MakeFailed } {
320 try step.addError(fmt, args);
319pub fn fail(step: *Step, maker: *const Maker, comptime fmt: []const u8, args: anytype) error{ OutOfMemory, MakeFailed } {
320 try step.addError(maker, fmt, args);
321321 return error.MakeFailed;
322322}
323323
324pub fn addError(step: *Step, comptime fmt: []const u8, args: anytype) error{OutOfMemory}!void {
325 const arena = step.owner.allocator;
324pub fn addError(step: *Step, maker: *const Maker, comptime fmt: []const u8, args: anytype) error{OutOfMemory}!void {
325 const graph = maker.graph;
326 const arena = graph.arena; // TODO don't leak into the process_arena
326327 const msg = try std.fmt.allocPrint(arena, fmt, args);
327328 try step.result_error_msgs.append(arena, msg);
328329}
lib/compiler/Maker/Step/Compile.zig+394-290
......@@ -23,14 +23,17 @@ zig_args: std.ArrayList([]const u8) = .empty,
2323
2424pub fn make(
2525 compile: *Compile,
26 step_index: Configuration.Step.Index,
26 compile_index: Configuration.Step.Index,
2727 maker: *Maker,
2828 progress_node: std.Progress.Node,
2929) Step.ExtendedMakeError!void {
3030 const graph = maker.graph;
31 const step = maker.stepByIndex(step_index);
31 const step = maker.stepByIndex(compile_index);
32
33 // Reset / repopulate persistent state.
3234 compile.zig_args.clearRetainingCapacity();
33 try lowerZigArgs(compile, step_index, maker, &compile.zig_args, false);
35
36 try lowerZigArgs(compile, compile_index, maker, &compile.zig_args, false);
3437 if (true) @panic("TODO implement compile.make()");
3538 const process_arena = graph.arena; // TODO don't leak into the process_arena
3639
......@@ -42,7 +45,7 @@ pub fn make(
4245 ) catch |err| switch (err) {
4346 error.NeedCompileErrorCheck => {
4447 assert(compile.expect_errors != null);
45 try checkCompileErrors(compile);
48 try checkCompileErrors(compile, maker);
4649 return;
4750 },
4851 else => |e| return e,
......@@ -81,19 +84,50 @@ pub fn make(
8184 }
8285}
8386
87/// List of importable modules in a compilation's module graph, including
88/// the root module. The root module is guaranteed to be first.
89const ModuleList = std.AutoArrayHashMapUnmanaged(Configuration.Module.Index, Configuration.String);
90/// Keyed on the first key in the module list.
91const ModuleGraph = std.ArrayHashMapUnmanaged(ModuleList, void, ModuleListContext, false);
92
93const ModuleListContext = struct {
94 pub fn eql(ctx: @This(), a: ModuleList, b: ModuleList) bool {
95 _ = ctx;
96 return a.keys()[0] == b.keys()[0];
97 }
98
99 pub fn hash(ctx: @This(), key: ModuleList) u32 {
100 _ = ctx;
101 return std.hash.int(@intFromEnum(key.keys()[0]));
102 }
103
104 const Adapter = struct {
105 pub fn eql(ctx: @This(), a: Configuration.Module.Index, b: ModuleList, b_index: usize) bool {
106 _ = ctx;
107 _ = b_index;
108 return a == b.keys()[0];
109 }
110
111 pub fn hash(ctx: @This(), key: Configuration.Module.Index) u32 {
112 _ = ctx;
113 return std.hash.int(@intFromEnum(key));
114 }
115 };
116};
117
84118fn lowerZigArgs(
85 compile: *Compile,
86 step_index: Configuration.Step.Index,
87 maker: *Maker,
119 compile: *const Compile,
120 compile_index: Configuration.Step.Index,
121 maker: *const Maker,
88122 zig_args: *std.ArrayList([]const u8),
89123 fuzz: bool,
90) Allocator.Error!void {
91 const step = maker.stepByIndex(step_index);
124) error{ OutOfMemory, MakeFailed }!void {
125 const step = maker.stepByIndex(compile_index);
92126 const graph = maker.graph;
93127 const arena = graph.arena; // TODO don't leak into the process arena
94128 const gpa = maker.gpa;
95129 const conf = &maker.scanned_config.configuration;
96 const conf_step = step_index.ptr(conf);
130 const conf_step = compile_index.ptr(conf);
97131 const conf_comp = conf_step.extended.get(conf.extra).compile;
98132
99133 try zig_args.append(gpa, graph.zig_exe);
......@@ -144,21 +178,21 @@ fn lowerZigArgs(
144178
145179 try addBool(gpa, zig_args, "-ffuzz", fuzz);
146180
147 if (true) @panic("TODO");
148
149 var is_linking_libc = conf_comp.flags3.is_linking_libc;
150 var is_linking_libcpp = conf_comp.flags3.is_linking_libcpp;
151
152181 {
182 var is_linking_libc = conf_comp.flags3.is_linking_libc;
183 var is_linking_libcpp = conf_comp.flags3.is_linking_libcpp;
184
153185 // Stores system libraries that have already been seen for at least one
154 // module, along with any arguments that need to be passed to the
155 // compiler for each module individually.
156 var seen_system_libs: std.StringHashMapUnmanaged([]const []const u8) = .empty;
157 var frameworks: std.StringArrayHashMapUnmanaged(Module.FrameworkFlags) = .empty;
186 // module, along with any C compiler arguments that need to be passed
187 // to the compiler for each module individually as reported by
188 // pkg-config.
189 var seen_system_libs: std.AutoArrayHashMapUnmanaged(Configuration.String, []const []const u8) = .empty;
190 var frameworks: std.AutoArrayHashMapUnmanaged(Configuration.String, Configuration.Module.Framework.Flags) = .empty;
191 var module_graph: ModuleGraph = .empty;
158192
159193 var prev_has_cflags = false;
160194 var prev_has_rcflags = false;
161 var prev_search_strategy: Module.SystemLib.SearchStrategy = .paths_first;
195 var prev_search_strategy: Configuration.SystemLib.SearchStrategy = .paths_first;
162196 var prev_preferred_link_mode: std.builtin.LinkMode = .dynamic;
163197 // Track the number of positional arguments so that a nice error can be
164198 // emitted if there is nothing to link.
......@@ -166,250 +200,256 @@ fn lowerZigArgs(
166200
167201 // Fully recursive iteration including dynamic libraries to detect
168202 // libc and libc++ linkage.
169 for (getCompileDependencies(true)) |some_compile| {
170 for (some_compile.root_module.getGraph().modules) |mod| {
171 if (mod.link_libc == true) is_linking_libc = true;
172 if (mod.link_libcpp == true) is_linking_libcpp = true;
203 for (try getCompileDependencies(arena, &module_graph, conf, compile_index, true)) |some_compile_index| {
204 const some_compile = some_compile_index.ptr(conf).extended.get(conf.extra).compile;
205 const modules = try getModuleList(arena, &module_graph, some_compile.root_module, conf);
206 for (modules.keys()) |mod_index| {
207 const mod = mod_index.get(conf);
208 is_linking_libc = is_linking_libc or mod.flags2.link_libc == .true;
209 is_linking_libcpp = is_linking_libcpp or mod.flags2.link_libcpp == .true;
173210 }
174211 }
175212
176 var cli_named_modules = try CliNamedModules.init(arena, compile.root_module);
213 var cli_named_modules = try CliNamedModules.init(arena, &module_graph, compile_index, maker);
177214
178215 // For this loop, don't chase dynamic libraries because their link
179216 // objects are already linked.
180 for (getCompileDependencies(false)) |dep_compile| {
181 for (dep_compile.root_module.getGraph().modules) |mod| {
217 for (try getCompileDependencies(arena, &module_graph, conf, compile_index, false)) |dep_compile_index| {
218 const dep_compile = dep_compile_index.ptr(conf).extended.get(conf.extra).compile;
219 const modules = try getModuleList(arena, &module_graph, dep_compile.root_module, conf);
220 for (modules.keys()) |mod_index| {
221 const mod = mod_index.get(conf);
182222 // While walking transitive dependencies, if a given link object is
183223 // already included in a library, it should not redundantly be
184224 // placed on the linker line of the dependee.
185 const my_responsibility = dep_compile == compile;
225 const my_responsibility = dep_compile_index == compile_index;
186226 const already_linked = !my_responsibility and dep_compile.isDynamicLibrary();
187227
188228 // Inherit dependencies on darwin frameworks.
189229 if (!already_linked) {
190 for (mod.frameworks.keys(), mod.frameworks.values()) |name, info| {
191 try frameworks.put(arena, name, info);
230 for (mod.frameworks.slice) |framework| {
231 try frameworks.put(arena, framework.name, framework.flags);
192232 }
193233 }
194234
235 if (true) @panic("TODO");
236
195237 // Inherit dependencies on system libraries and static libraries.
196 for (mod.link_objects.items) |link_object| {
197 switch (link_object) {
198 .static_path => |static_path| {
199 if (my_responsibility) {
200 try zig_args.append(gpa, static_path.getPath2(step));
201 total_linker_objects += 1;
202 }
203 },
204 .system_lib => |system_lib| {
205 const system_lib_gop = try seen_system_libs.getOrPut(arena, system_lib.name);
206 if (system_lib_gop.found_existing) {
207 try zig_args.appendSlice(gpa, system_lib_gop.value_ptr.*);
208 continue;
209 } else {
210 system_lib_gop.value_ptr.* = &.{};
211 }
238 for (0..mod.link_objects.len) |lo_i| switch (mod.link_objects.get(conf.extra, lo_i)) {
239 .static_path => |static_path| {
240 if (my_responsibility) {
241 try zig_args.append(gpa, static_path.getPath2(step));
242 total_linker_objects += 1;
243 }
244 },
245 .system_lib => |system_lib| {
246 const system_lib_gop = try seen_system_libs.getOrPut(arena, system_lib.name);
247 if (system_lib_gop.found_existing) {
248 try zig_args.appendSlice(gpa, system_lib_gop.value_ptr.*);
249 continue;
250 } else {
251 system_lib_gop.value_ptr.* = &.{};
252 }
212253
213 if (already_linked)
214 continue;
215
216 if ((system_lib.search_strategy != prev_search_strategy or
217 system_lib.preferred_link_mode != prev_preferred_link_mode) and
218 compile.linkage != .static)
219 {
220 switch (system_lib.search_strategy) {
221 .no_fallback => switch (system_lib.preferred_link_mode) {
222 .dynamic => try zig_args.append(gpa, "-search_dylibs_only"),
223 .static => try zig_args.append(gpa, "-search_static_only"),
224 },
225 .paths_first => switch (system_lib.preferred_link_mode) {
226 .dynamic => try zig_args.append(gpa, "-search_paths_first"),
227 .static => try zig_args.append(gpa, "-search_paths_first_static"),
228 },
229 .mode_first => switch (system_lib.preferred_link_mode) {
230 .dynamic => try zig_args.append(gpa, "-search_dylibs_first"),
231 .static => try zig_args.append(gpa, "-search_static_first"),
232 },
233 }
234 prev_search_strategy = system_lib.search_strategy;
235 prev_preferred_link_mode = system_lib.preferred_link_mode;
254 if (already_linked)
255 continue;
256
257 if ((system_lib.search_strategy != prev_search_strategy or
258 system_lib.preferred_link_mode != prev_preferred_link_mode) and
259 compile.linkage != .static)
260 {
261 switch (system_lib.search_strategy) {
262 .no_fallback => switch (system_lib.preferred_link_mode) {
263 .dynamic => try zig_args.append(gpa, "-search_dylibs_only"),
264 .static => try zig_args.append(gpa, "-search_static_only"),
265 },
266 .paths_first => switch (system_lib.preferred_link_mode) {
267 .dynamic => try zig_args.append(gpa, "-search_paths_first"),
268 .static => try zig_args.append(gpa, "-search_paths_first_static"),
269 },
270 .mode_first => switch (system_lib.preferred_link_mode) {
271 .dynamic => try zig_args.append(gpa, "-search_dylibs_first"),
272 .static => try zig_args.append(gpa, "-search_static_first"),
273 },
236274 }
275 prev_search_strategy = system_lib.search_strategy;
276 prev_preferred_link_mode = system_lib.preferred_link_mode;
277 }
237278
238 const prefix: []const u8 = prefix: {
239 if (system_lib.needed) break :prefix "-needed-l";
240 if (system_lib.weak) break :prefix "-weak-l";
241 break :prefix "-l";
242 };
243 switch (system_lib.use_pkg_config) {
244 .no => try zig_args.append(gpa, try allocPrint(arena, "{s}{s}", .{ prefix, system_lib.name })),
245 .yes, .force => {
246 if (compile.runPkgConfig(maker, system_lib.name)) |result| {
247 try zig_args.appendSlice(gpa, result.cflags);
248 try zig_args.appendSlice(gpa, result.libs);
249 try seen_system_libs.put(arena, system_lib.name, result.cflags);
250 } else |err| switch (err) {
251 error.PkgConfigInvalidOutput,
252 error.PkgConfigCrashed,
253 error.PkgConfigFailed,
254 error.PkgConfigNotInstalled,
255 error.PackageNotFound,
256 => switch (system_lib.use_pkg_config) {
257 .yes => {
258 // pkg-config failed, so fall back to linking the library
259 // by name directly.
260 try zig_args.append(gpa, try allocPrint(arena, "{s}{s}", .{
261 prefix,
262 system_lib.name,
263 }));
264 },
265 .force => {
266 return step.fail("pkg-config failed for library {s}", .{system_lib.name});
267 },
268 .no => unreachable,
279 const prefix: []const u8 = prefix: {
280 if (system_lib.needed) break :prefix "-needed-l";
281 if (system_lib.weak) break :prefix "-weak-l";
282 break :prefix "-l";
283 };
284 switch (system_lib.use_pkg_config) {
285 .no => try zig_args.append(gpa, try allocPrint(arena, "{s}{s}", .{ prefix, system_lib.name })),
286 .yes, .force => {
287 if (compile.runPkgConfig(maker, system_lib.name)) |result| {
288 try zig_args.appendSlice(gpa, result.cflags);
289 try zig_args.appendSlice(gpa, result.libs);
290 try seen_system_libs.put(arena, system_lib.name, result.cflags);
291 } else |err| switch (err) {
292 error.PkgConfigInvalidOutput,
293 error.PkgConfigCrashed,
294 error.PkgConfigFailed,
295 error.PkgConfigNotInstalled,
296 error.PackageNotFound,
297 => switch (system_lib.use_pkg_config) {
298 .yes => {
299 // pkg-config failed, so fall back to linking the library
300 // by name directly.
301 try zig_args.append(gpa, try allocPrint(arena, "{s}{s}", .{
302 prefix,
303 system_lib.name,
304 }));
269305 },
306 .force => {
307 return step.fail(maker, "pkg-config failed for library {s}", .{system_lib.name});
308 },
309 .no => unreachable,
310 },
270311
271 else => |e| return e,
272 }
273 },
274 }
275 },
276 .other_step => |other| {
277 switch (other.kind) {
278 .exe => return step.fail("cannot link with an executable build artifact", .{}),
279 .@"test" => return step.fail("cannot link with a test", .{}),
280 .obj, .test_obj => {
281 const included_in_lib_or_obj = !my_responsibility and
282 (dep_compile.kind == .lib or dep_compile.kind == .obj or dep_compile.kind == .test_obj);
283 if (!already_linked and !included_in_lib_or_obj) {
284 try zig_args.append(gpa, other.getEmittedBin().getPath2(step));
285 total_linker_objects += 1;
286 }
287 },
288 .lib => l: {
289 const other_produces_implib = other.producesImplib();
290 const other_is_static = other_produces_implib or other.isStaticLibrary();
291
292 if (compile.isStaticLibrary() and other_is_static) {
293 // Avoid putting a static library inside a static library.
294 break :l;
295 }
312 else => |e| return e,
313 }
314 },
315 }
316 },
317 .other_step => |other| {
318 switch (other.kind) {
319 .exe => return step.fail(maker, "cannot link with an executable build artifact", .{}),
320 .@"test" => return step.fail(maker, "cannot link with a test", .{}),
321 .obj, .test_obj => {
322 const included_in_lib_or_obj = !my_responsibility and
323 (dep_compile.kind == .lib or dep_compile.kind == .obj or dep_compile.kind == .test_obj);
324 if (!already_linked and !included_in_lib_or_obj) {
325 try zig_args.append(gpa, other.getEmittedBin().getPath2(step));
326 total_linker_objects += 1;
327 }
328 },
329 .lib => l: {
330 const other_produces_implib = other.producesImplib();
331 const other_is_static = other_produces_implib or other.isStaticLibrary();
332
333 if (compile.isStaticLibrary() and other_is_static) {
334 // Avoid putting a static library inside a static library.
335 break :l;
336 }
296337
297 // For DLLs, we must link against the implib.
298 // For everything else, we directly link
299 // against the library file.
300 const full_path_lib = if (other_produces_implib)
301 try other.getGeneratedFilePath("generated_implib", &compile.step)
302 else
303 try other.getGeneratedFilePath("generated_bin", &compile.step);
338 // For DLLs, we must link against the implib.
339 // For everything else, we directly link
340 // against the library file.
341 const full_path_lib = if (other_produces_implib)
342 try other.getGeneratedFilePath("generated_implib", &compile.step)
343 else
344 try other.getGeneratedFilePath("generated_bin", &compile.step);
304345
305 try zig_args.append(gpa, full_path_lib);
306 total_linker_objects += 1;
346 try zig_args.append(gpa, full_path_lib);
347 total_linker_objects += 1;
307348
308 if (other.linkage == .dynamic and
309 compile.rootModuleTarget().os.tag != .windows)
310 {
311 if (Dir.path.dirname(full_path_lib)) |dirname| {
312 try zig_args.append(gpa, "-rpath");
313 try zig_args.append(gpa, dirname);
314 }
349 if (other.linkage == .dynamic and
350 compile.rootModuleTarget().os.tag != .windows)
351 {
352 if (Dir.path.dirname(full_path_lib)) |dirname| {
353 try zig_args.append(gpa, "-rpath");
354 try zig_args.append(gpa, dirname);
315355 }
316 },
317 }
318 },
319 .assembly_file => |asm_file| l: {
320 if (!my_responsibility) break :l;
356 }
357 },
358 }
359 },
360 .assembly_file => |asm_file| l: {
361 if (!my_responsibility) break :l;
321362
322 if (prev_has_cflags) {
323 try zig_args.append(gpa, "-cflags");
324 try zig_args.append(gpa, "--");
325 prev_has_cflags = false;
326 }
327 try zig_args.append(gpa, asm_file.getPath2(mod.owner, step));
328 total_linker_objects += 1;
329 },
363 if (prev_has_cflags) {
364 try zig_args.append(gpa, "-cflags");
365 try zig_args.append(gpa, "--");
366 prev_has_cflags = false;
367 }
368 try zig_args.append(gpa, asm_file.getPath2(mod.owner, step));
369 total_linker_objects += 1;
370 },
330371
331 .c_source_file => |c_source_file| l: {
332 if (!my_responsibility) break :l;
372 .c_source_file => |c_source_file| l: {
373 if (!my_responsibility) break :l;
333374
334 if (prev_has_cflags or c_source_file.flags.len != 0) {
335 try zig_args.append(gpa, "-cflags");
336 for (c_source_file.flags) |arg| {
337 try zig_args.append(gpa, arg);
338 }
339 try zig_args.append(gpa, "--");
375 if (prev_has_cflags or c_source_file.flags.len != 0) {
376 try zig_args.append(gpa, "-cflags");
377 for (c_source_file.flags) |arg| {
378 try zig_args.append(gpa, arg);
340379 }
341 prev_has_cflags = (c_source_file.flags.len != 0);
380 try zig_args.append(gpa, "--");
381 }
382 prev_has_cflags = (c_source_file.flags.len != 0);
342383
343 if (c_source_file.language) |lang| {
344 try zig_args.append(gpa, "-x");
345 try zig_args.append(gpa, lang.internalIdentifier());
346 }
384 if (c_source_file.language) |lang| {
385 try zig_args.append(gpa, "-x");
386 try zig_args.append(gpa, lang.internalIdentifier());
387 }
347388
348 try zig_args.append(gpa, c_source_file.file.getPath2(mod.owner, step));
389 try zig_args.append(gpa, c_source_file.file.getPath2(mod.owner, step));
349390
350 if (c_source_file.language != null) {
351 try zig_args.append(gpa, "-x");
352 try zig_args.append(gpa, "none");
353 }
354 total_linker_objects += 1;
355 },
391 if (c_source_file.language != null) {
392 try zig_args.append(gpa, "-x");
393 try zig_args.append(gpa, "none");
394 }
395 total_linker_objects += 1;
396 },
356397
357 .c_source_files => |c_source_files| l: {
358 if (!my_responsibility) break :l;
398 .c_source_files => |c_source_files| l: {
399 if (!my_responsibility) break :l;
359400
360 if (prev_has_cflags or c_source_files.flags.len != 0) {
361 try zig_args.append(gpa, "-cflags");
362 for (c_source_files.flags) |arg| {
363 try zig_args.append(gpa, arg);
364 }
365 try zig_args.append(gpa, "--");
401 if (prev_has_cflags or c_source_files.flags.len != 0) {
402 try zig_args.append(gpa, "-cflags");
403 for (c_source_files.flags) |arg| {
404 try zig_args.append(gpa, arg);
366405 }
367 prev_has_cflags = (c_source_files.flags.len != 0);
406 try zig_args.append(gpa, "--");
407 }
408 prev_has_cflags = (c_source_files.flags.len != 0);
368409
369 if (c_source_files.language) |lang| {
370 try zig_args.append(gpa, "-x");
371 try zig_args.append(gpa, lang.internalIdentifier());
372 }
410 if (c_source_files.language) |lang| {
411 try zig_args.append(gpa, "-x");
412 try zig_args.append(gpa, lang.internalIdentifier());
413 }
373414
374 const root_path = c_source_files.root.getPath2(mod.owner, step);
375 for (c_source_files.files) |file| {
376 try zig_args.append(gpa, try Dir.path.join(arena, &.{ root_path, file }));
377 }
415 const root_path = c_source_files.root.getPath2(mod.owner, step);
416 for (c_source_files.files) |file| {
417 try zig_args.append(gpa, try Dir.path.join(arena, &.{ root_path, file }));
418 }
378419
379 if (c_source_files.language != null) {
380 try zig_args.append(gpa, "-x");
381 try zig_args.append(gpa, "none");
382 }
420 if (c_source_files.language != null) {
421 try zig_args.append(gpa, "-x");
422 try zig_args.append(gpa, "none");
423 }
383424
384 total_linker_objects += c_source_files.files.len;
385 },
425 total_linker_objects += c_source_files.files.len;
426 },
386427
387 .win32_resource_file => |rc_source_file| l: {
388 if (!my_responsibility) break :l;
428 .win32_resource_file => |rc_source_file| l: {
429 if (!my_responsibility) break :l;
389430
390 if (rc_source_file.flags.len == 0 and rc_source_file.include_paths.len == 0) {
391 if (prev_has_rcflags) {
392 try zig_args.append(gpa, "-rcflags");
393 try zig_args.append(gpa, "--");
394 prev_has_rcflags = false;
395 }
396 } else {
431 if (rc_source_file.flags.len == 0 and rc_source_file.include_paths.len == 0) {
432 if (prev_has_rcflags) {
397433 try zig_args.append(gpa, "-rcflags");
398 for (rc_source_file.flags) |arg| {
399 try zig_args.append(gpa, arg);
400 }
401 for (rc_source_file.include_paths) |include_path| {
402 try zig_args.append(gpa, "/I");
403 try zig_args.append(gpa, include_path.getPath2(mod.owner, step));
404 }
405434 try zig_args.append(gpa, "--");
406 prev_has_rcflags = true;
435 prev_has_rcflags = false;
407436 }
408 try zig_args.append(gpa, rc_source_file.file.getPath2(mod.owner, step));
409 total_linker_objects += 1;
410 },
411 }
412 }
437 } else {
438 try zig_args.append(gpa, "-rcflags");
439 for (rc_source_file.flags) |arg| {
440 try zig_args.append(gpa, arg);
441 }
442 for (rc_source_file.include_paths) |include_path| {
443 try zig_args.append(gpa, "/I");
444 try zig_args.append(gpa, include_path.getPath2(mod.owner, step));
445 }
446 try zig_args.append(gpa, "--");
447 prev_has_rcflags = true;
448 }
449 try zig_args.append(gpa, rc_source_file.file.getPath2(mod.owner, step));
450 total_linker_objects += 1;
451 },
452 };
413453
414454 // We need to emit the --mod argument here so that the above link objects
415455 // have the correct parent module, but only if the module is part of
......@@ -450,48 +490,47 @@ fn lowerZigArgs(
450490 }
451491
452492 if (total_linker_objects == 0) {
453 return step.fail("the linker needs one or more objects to link", .{});
493 return step.fail(maker, "the linker needs one or more objects to link", .{});
454494 }
455495
456496 for (frameworks.keys(), frameworks.values()) |name, info| {
497 try zig_args.ensureUnusedCapacity(gpa, 2);
457498 if (info.needed) {
458 try zig_args.append(gpa, "-needed_framework");
499 zig_args.appendAssumeCapacity("-needed_framework");
459500 } else if (info.weak) {
460 try zig_args.append(gpa, "-weak_framework");
501 zig_args.appendAssumeCapacity("-weak_framework");
461502 } else {
462 try zig_args.append(gpa, "-framework");
503 zig_args.appendAssumeCapacity("-framework");
463504 }
464 try zig_args.append(gpa, name);
505 zig_args.appendAssumeCapacity(name.slice(conf));
465506 }
466507
467 if (is_linking_libcpp) {
468 try zig_args.append(gpa, "-lc++");
469 }
470
471 if (is_linking_libc) {
472 try zig_args.append(gpa, "-lc");
473 }
508 try zig_args.ensureUnusedCapacity(gpa, 2);
509 if (is_linking_libcpp) zig_args.appendAssumeCapacity("-lc++");
510 if (is_linking_libc) zig_args.appendAssumeCapacity("-lc");
474511 }
475512
476 if (compile.win32_manifest) |manifest_file| {
513 if (true) @panic("TODO");
514
515 if (conf_comp.win32_manifest) |manifest_file| {
477516 try zig_args.append(gpa, manifest_file.getPath2(step));
478517 }
479518
480 if (compile.win32_module_definition) |module_file| {
519 if (conf_comp.win32_module_definition) |module_file| {
481520 try zig_args.append(gpa, module_file.getPath2(step));
482521 }
483522
484 if (compile.image_base) |image_base| {
523 if (conf_comp.image_base) |image_base| {
485524 try zig_args.appendSlice(gpa, &.{
486525 "--image-base", try allocPrint(arena, "0x{x}", .{image_base}),
487526 });
488527 }
489528
490 for (compile.filters) |filter| {
529 for (conf_comp.filters) |filter| {
491530 try zig_args.appendSlice(gpa, &.{ "--test-filter", filter });
492531 }
493532
494 if (compile.test_runner) |test_runner| {
533 if (conf_comp.test_runner) |test_runner| {
495534 try zig_args.appendSlice(gpa, &.{ "--test-runner", test_runner.path.getPath2(step) });
496535 }
497536
......@@ -503,8 +542,8 @@ fn lowerZigArgs(
503542 try addBool(gpa, zig_args, "--debug-incremental", graph.debug_incremental);
504543 try addBool(gpa, zig_args, "--verbose-air", graph.verbose_air);
505544 try addBool(gpa, zig_args, "--verbose-llvm-ir", graph.verbose_llvm_ir);
506 try addBool(gpa, zig_args, "--verbose-link", graph.verbose_link or compile.verbose_link);
507 try addBool(gpa, zig_args, "--verbose-cc", graph.verbose_cc or compile.verbose_cc);
545 try addBool(gpa, zig_args, "--verbose-link", graph.verbose_link or conf_comp.flags.verbose_link);
546 try addBool(gpa, zig_args, "--verbose-cc", graph.verbose_cc or conf_comp.flags.verbose_cc);
508547 try addBool(gpa, zig_args, "--verbose-llvm-cpu-features", graph.verbose_llvm_cpu_features);
509548 try addBool(gpa, zig_args, "--time-report", graph.time_report);
510549
......@@ -516,49 +555,49 @@ fn lowerZigArgs(
516555 if (compile.generated_llvm_ir != null) try zig_args.append(gpa, "-femit-llvm-ir");
517556 if (compile.generated_h != null) try zig_args.append(gpa, "-femit-h");
518557
519 try addFlag(gpa, zig_args, "formatted-panics", compile.formatted_panics);
558 try addFlag(gpa, zig_args, "formatted-panics", conf_comp.flags.formatted_panics);
520559
521 switch (compile.compress_debug_sections) {
560 switch (conf_comp.compress_debug_sections) {
522561 .none => {},
523562 .zlib => try zig_args.append(gpa, "--compress-debug-sections=zlib"),
524563 .zstd => try zig_args.append(gpa, "--compress-debug-sections=zstd"),
525564 }
526565
527 if (compile.link_eh_frame_hdr) {
566 if (conf_comp.flags.link_eh_frame_hdr) {
528567 try zig_args.append(gpa, "--eh-frame-hdr");
529568 }
530 if (compile.link_emit_relocs) {
569 if (conf_comp.flags.link_emit_relocs) {
531570 try zig_args.append(gpa, "--emit-relocs");
532571 }
533 if (compile.link_function_sections) {
572 if (conf_comp.flags.link_function_sections) {
534573 try zig_args.append(gpa, "-ffunction-sections");
535574 }
536 if (compile.link_data_sections) {
575 if (conf_comp.flags.link_data_sections) {
537576 try zig_args.append(gpa, "-fdata-sections");
538577 }
539 if (compile.link_gc_sections) |x| {
578 if (conf_comp.flags.link_gc_sections) |x| {
540579 try zig_args.append(gpa, if (x) "--gc-sections" else "--no-gc-sections");
541580 }
542 if (!compile.linker_dynamicbase) {
581 if (!conf_comp.flags.linker_dynamicbase) {
543582 try zig_args.append(gpa, "--no-dynamicbase");
544583 }
545 if (compile.linker_allow_shlib_undefined) |x| {
584 if (conf_comp.flags.linker_allow_shlib_undefined) |x| {
546585 try zig_args.append(gpa, if (x) "-fallow-shlib-undefined" else "-fno-allow-shlib-undefined");
547586 }
548 if (compile.link_z_notext) try zig_args.appendSlice(gpa, &.{ "-z", "notext" });
549 if (!compile.link_z_relro) try zig_args.appendSlice(gpa, &.{ "-z", "norelro" });
550 if (compile.link_z_lazy) try zig_args.appendSlice(gpa, &.{ "-z", "lazy" });
551 if (compile.link_z_common_page_size) |size| try zig_args.appendSlice(gpa, &.{
587 if (conf_comp.flags.link_z_notext) try zig_args.appendSlice(gpa, &.{ "-z", "notext" });
588 if (!conf_comp.flags.link_z_relro) try zig_args.appendSlice(gpa, &.{ "-z", "norelro" });
589 if (conf_comp.flags.link_z_lazy) try zig_args.appendSlice(gpa, &.{ "-z", "lazy" });
590 if (conf_comp.flags.link_z_common_page_size) |size| try zig_args.appendSlice(gpa, &.{
552591 "-z",
553592 try allocPrint(arena, "common-page-size={d}", .{size}),
554593 });
555 if (compile.link_z_max_page_size) |size| try zig_args.appendSlice(gpa, &.{
594 if (conf_comp.flags.link_z_max_page_size) |size| try zig_args.appendSlice(gpa, &.{
556595 "-z",
557596 try allocPrint(arena, "max-page-size={d}", .{size}),
558597 });
559 if (compile.link_z_defs) try zig_args.appendSlice(gpa, &.{ "-z", "defs" });
598 if (conf_comp.flags.link_z_defs) try zig_args.appendSlice(gpa, &.{ "-z", "defs" });
560599
561 if (compile.libc_file) |libc_file| {
600 if (conf_comp.flags.libc_file) |libc_file| {
562601 try zig_args.appendSlice(gpa, &.{ "--libc", libc_file.getPath2(step) });
563602 } else if (graph.libc_file) |libc_file| {
564603 try zig_args.appendSlice(gpa, &.{ "--libc", libc_file });
......@@ -573,18 +612,16 @@ fn lowerZigArgs(
573612 if (graph.debug_compiler_runtime_libs) |mode|
574613 try zig_args.append(gpa, try allocPrint(arena, "--debug-rt={t}", .{mode}));
575614
576 try zig_args.append(gpa, "--name");
577 try zig_args.append(gpa, compile.name);
615 try zig_args.appendSlice(gpa, &.{ "--name", conf_comp.root_name.slice(conf) });
578616
579617 if (compile.linkage) |some| switch (some) {
580618 .dynamic => try zig_args.append(gpa, "-dynamic"),
581619 .static => try zig_args.append(gpa, "-static"),
582620 };
583621 if (compile.kind == .lib and compile.linkage != null and compile.linkage.? == .dynamic) {
584 if (compile.version) |version| {
585 try zig_args.append(gpa, "--version");
586 try zig_args.append(gpa, try allocPrint(arena, "{f}", .{version}));
587 }
622 if (compile.version) |version| try zig_args.appendSlice(gpa, &.{
623 "--version", try allocPrint(arena, "{f}", .{version}),
624 });
588625
589626 if (compile.rootModuleTarget().os.tag.isDarwin()) {
590627 const install_name = compile.install_name orelse try allocPrint(arena, "@rpath/{s}{s}{s}", .{
......@@ -696,7 +733,7 @@ fn lowerZigArgs(
696733
697734 for (graph.search_prefixes.items) |search_prefix| {
698735 var prefix_dir = cwd.openDir(io, search_prefix, .{}) catch |err| {
699 return step.fail("unable to open prefix directory '{s}': {t}", .{ search_prefix, err });
736 return step.fail(maker, "unable to open prefix directory '{s}': {t}", .{ search_prefix, err });
700737 };
701738 defer prefix_dir.close(io);
702739
......@@ -710,7 +747,7 @@ fn lowerZigArgs(
710747 });
711748 } else |err| switch (err) {
712749 error.FileNotFound => {},
713 else => |e| return step.fail("unable to access '{s}/lib' directory: {t}", .{ search_prefix, e }),
750 else => |e| return step.fail(maker, "unable to access '{s}/lib' directory: {t}", .{ search_prefix, e }),
714751 }
715752
716753 if (prefix_dir.access(io, "include", .{})) |_| {
......@@ -719,7 +756,7 @@ fn lowerZigArgs(
719756 });
720757 } else |err| switch (err) {
721758 error.FileNotFound => {},
722 else => |e| return step.fail("unable to access '{s}/include' directory: {t}", .{ search_prefix, e }),
759 else => |e| return step.fail(maker, "unable to access '{s}/include' directory: {t}", .{ search_prefix, e }),
723760 }
724761 }
725762
......@@ -825,13 +862,13 @@ fn lowerZigArgs(
825862 var af = graph.cache_root.handle.createFileAtomic(io, args_file, .{
826863 .replace = false,
827864 .make_path = true,
828 }) catch |e| return step.fail("failed creating tmp args file {f}{s}: {t}", .{
865 }) catch |e| return step.fail(maker, "failed creating tmp args file {f}{s}: {t}", .{
829866 graph.cache_root, args_file, e,
830867 });
831868 defer af.deinit(io);
832869
833870 af.file.writeStreamingAll(io, args) catch |e| {
834 return step.fail("failed writing args data to tmp file {f}{s}: {t}", .{
871 return step.fail(maker, "failed writing args data to tmp file {f}{s}: {t}", .{
835872 graph.cache_root, args_file, e,
836873 });
837874 };
......@@ -842,7 +879,7 @@ fn lowerZigArgs(
842879 error.PathAlreadyExists => {
843880 // The args file was created by another concurrent build process.
844881 },
845 else => |other_err| return step.fail("failed linking tmp file {f}{s}: {t}", .{
882 else => |other_err| return step.fail(maker, "failed linking tmp file {f}{s}: {t}", .{
846883 graph.cache_root, args_file, other_err,
847884 }),
848885 };
......@@ -899,14 +936,14 @@ pub fn doAtomicSymLinks(
899936 const major_only_path = try Dir.path.join(arena, &.{ out_dir, filename_major_only });
900937 const cwd: Io.Dir = .cwd();
901938 cwd.symLinkAtomic(io, out_basename, major_only_path, .{}) catch |err| {
902 return step.fail("unable to symlink {s} -> {s}: {t}", .{
939 return step.fail(maker, "unable to symlink {s} -> {s}: {t}", .{
903940 major_only_path, out_basename, err,
904941 });
905942 };
906943 // sym link for libfoo.so to libfoo.so.1
907944 const name_only_path = try Dir.path.join(arena, &.{ out_dir, filename_name_only });
908945 cwd.symLinkAtomic(io, filename_major_only, name_only_path, .{}) catch |err| {
909 return step.fail("unable to symlink {s} -> {s}: {t}", .{
946 return step.fail(maker, "unable to symlink {s} -> {s}: {t}", .{
910947 name_only_path, filename_major_only, err,
911948 });
912949 };
......@@ -1080,7 +1117,7 @@ fn runPkgConfig(compile: *Compile, maker: *Maker, lib_name: []const u8) !PkgConf
10801117 } else if (mem.startsWith(u8, arg, wl_rpath_prefix)) {
10811118 try zig_cflags.appendSlice(arena, &.{ "-rpath", arg[wl_rpath_prefix.len..] });
10821119 } else if (b.debug_pkg_config) {
1083 return compile.step.fail("unknown pkg-config flag '{s}'", .{arg});
1120 return compile.step.fail(maker, "unknown pkg-config flag '{s}'", .{arg});
10841121 }
10851122 }
10861123
......@@ -1093,7 +1130,7 @@ fn runPkgConfig(compile: *Compile, maker: *Maker, lib_name: []const u8) !PkgConf
10931130 };
10941131}
10951132
1096fn checkCompileErrors(compile: *Compile) !void {
1133fn checkCompileErrors(compile: *Compile, maker: *Maker) !void {
10971134 // Clear this field so that it does not get printed by the build runner.
10981135 const actual_eb = compile.step.result_error_bundle;
10991136 compile.step.result_error_bundle = .empty;
......@@ -1120,7 +1157,7 @@ fn checkCompileErrors(compile: *Compile) !void {
11201157 switch (expect_errors) {
11211158 .starts_with => |expect_starts_with| {
11221159 if (std.mem.startsWith(u8, actual_errors, expect_starts_with)) return;
1123 return compile.step.fail(
1160 return compile.step.fail(maker,
11241161 \\
11251162 \\========= should start with: ============
11261163 \\{s}
......@@ -1135,7 +1172,7 @@ fn checkCompileErrors(compile: *Compile) !void {
11351172 return;
11361173 }
11371174
1138 return compile.step.fail(
1175 return compile.step.fail(maker,
11391176 \\
11401177 \\========= should contain: ===============
11411178 \\{s}
......@@ -1158,7 +1195,7 @@ fn checkCompileErrors(compile: *Compile) !void {
11581195 return;
11591196 }
11601197
1161 return compile.step.fail(
1198 return compile.step.fail(maker,
11621199 \\
11631200 \\========= should contain: ===============
11641201 \\{s}
......@@ -1185,7 +1222,7 @@ fn checkCompileErrors(compile: *Compile) !void {
11851222
11861223 if (mem.eql(u8, expected_generated.items, actual_errors)) return;
11871224
1188 return compile.step.fail(
1225 return compile.step.fail(maker,
11891226 \\
11901227 \\========= expected: =====================
11911228 \\{s}
......@@ -1222,42 +1259,109 @@ fn moduleNeedsCliArg(mod: *const Module) bool {
12221259}
12231260
12241261const CliNamedModules = struct {
1225 modules: std.AutoArrayHashMapUnmanaged(*Module, void),
1262 modules: std.AutoArrayHashMapUnmanaged(Configuration.Module.Index, void),
12261263 names: std.StringArrayHashMapUnmanaged(void),
12271264
12281265 /// Traverse the whole dependency graph and give every module a unique
12291266 /// name, ideally one named after what it's called somewhere in the graph.
12301267 /// It will help here to have both a mapping from module to name and a set
12311268 /// of all the currently-used names.
1232 fn init(arena: Allocator, root_module: *Module) Allocator.Error!CliNamedModules {
1233 var compile: CliNamedModules = .{
1269 fn init(
1270 arena: Allocator,
1271 module_graph: *ModuleGraph,
1272 compile_index: Configuration.Step.Index,
1273 maker: *const Maker,
1274 ) Allocator.Error!CliNamedModules {
1275 const conf = &maker.scanned_config.configuration;
1276 const conf_compile = compile_index.ptr(conf).extended.get(conf.extra).compile;
1277
1278 var result: CliNamedModules = .{
12341279 .modules = .{},
12351280 .names = .{},
12361281 };
1237 const graph = root_module.getGraph();
1282 const modules = try getModuleList(arena, module_graph, conf_compile.root_module, conf);
12381283 {
1239 assert(graph.modules[0] == root_module);
1240 try compile.modules.put(arena, root_module, {});
1241 try compile.names.put(arena, "root", {});
1284 assert(conf_compile.root_module == modules.keys()[0]);
1285 try result.modules.put(arena, conf_compile.root_module, {});
1286 try result.names.put(arena, "root", {});
12421287 }
1243 for (graph.modules[1..], graph.names[1..]) |mod, orig_name| {
1244 var name = orig_name;
1288 for (modules.keys()[1..], modules.values()[1..]) |mod, orig_name| {
1289 const orig_name_slice = orig_name.slice(conf);
1290 var name: []const u8 = orig_name_slice;
12451291 var n: usize = 0;
12461292 while (true) {
1247 const gop = try compile.names.getOrPut(arena, name);
1293 const gop = try result.names.getOrPut(arena, name);
12481294 if (!gop.found_existing) {
1249 try compile.modules.putNoClobber(arena, mod, {});
1295 try result.modules.putNoClobber(arena, mod, {});
12501296 break;
12511297 }
1252 name = try allocPrint(arena, "{s}{d}", .{ orig_name, n });
1298 name = try allocPrint(arena, "{s}{d}", .{ orig_name_slice, n });
12531299 n += 1;
12541300 }
12551301 }
1256 return compile;
1302 return result;
12571303 }
12581304};
12591305
1260fn getCompileDependencies(chase_dynamic: bool) void {
1261 _ = chase_dynamic;
1262 @panic("TODO");
1306fn getCompileDependencies(
1307 arena: Allocator,
1308 module_graph: *ModuleGraph,
1309 conf: *const Configuration,
1310 start: Configuration.Step.Index,
1311 chase_dynamic: bool,
1312) ![]const Configuration.Step.Index {
1313 var compiles: std.AutoArrayHashMapUnmanaged(Configuration.Step.Index, void) = .empty;
1314 var compiles_i: usize = 0;
1315
1316 try compiles.putNoClobber(arena, start, {});
1317
1318 while (compiles_i < compiles.count()) : (compiles_i += 1) {
1319 const step = compiles.keys()[compiles_i].ptr(conf);
1320 const compile = step.extended.get(conf.extra).compile;
1321 const modules = try getModuleList(arena, module_graph, compile.root_module, conf);
1322
1323 for (modules.keys()) |mod_index| {
1324 const mod = mod_index.get(conf);
1325 for (0..mod.link_objects.len) |i| {
1326 switch (mod.link_objects.get(conf.extra, i)) {
1327 .other_step => |other_compile_index| {
1328 const other_compile = other_compile_index.ptr(conf).extended.get(conf.extra).compile;
1329 if (!chase_dynamic and other_compile.isDynamicLibrary()) continue;
1330 try compiles.put(arena, other_compile_index, {});
1331 },
1332 else => {},
1333 }
1334 }
1335 }
1336 }
1337
1338 return compiles.keys();
1339}
1340
1341/// Returned pointer expires upon next call to `getModuleList`.
1342fn getModuleList(
1343 arena: Allocator,
1344 module_graph: *ModuleGraph,
1345 root_module: Configuration.Module.Index,
1346 conf: *const Configuration,
1347) !*ModuleList {
1348 const gop = try module_graph.getOrPutAdapted(arena, root_module, @as(ModuleListContext.Adapter, .{}));
1349 const modules = gop.key_ptr;
1350
1351 if (gop.found_existing) return modules;
1352 modules.* = .empty;
1353 try modules.putNoClobber(arena, root_module, .root);
1354
1355 var i: usize = 0;
1356
1357 while (i < modules.entries.len) : (i += 1) {
1358 const dep_index = modules.keys()[i];
1359 const dep = dep_index.get(conf);
1360 const imports = dep.import_table.get(conf).imports;
1361 try modules.ensureUnusedCapacity(arena, imports.mal.len);
1362 for (imports.mal.items(.name), imports.mal.items(.module)) |import_name, other_mod|
1363 modules.putAssumeCapacity(other_mod, import_name);
1364 }
1365
1366 return modules;
12631367}
lib/compiler/configurer.zig+1
......@@ -202,6 +202,7 @@ pub fn main(init: process.Init.Minimal) !void {
202202 var wc: Configuration.Wip = .init(gpa);
203203 defer wc.deinit();
204204 assert(try wc.addString("") == .empty);
205 assert(try wc.addString("root") == .root);
205206
206207 try serializeSystemIntegrationOptions(&graph, &wc);
207208
lib/std/Build/Module.zig+3-5
......@@ -668,11 +668,9 @@ pub const Graph = struct {
668668 names: []const []const u8,
669669};
670670
671/// Intended to be used during the make phase only.
672///
673/// Given that `root` is the root `Module` of a compilation, return all `Module`s
674/// in the module graph, including `root` itself. `root` is guaranteed to be the
675/// first module in the returned slice.
671/// Given that `root` is the root `Module` of a compilation, return all
672/// `Module` in the module graph, including `root` itself. `root` is guaranteed
673/// to be the first module in the returned slice.
676674pub fn getGraph(root: *Module) Graph {
677675 if (root.cached_graph.modules.len != 0) {
678676 return root.cached_graph;
lib/std/zig/Configuration.zig+27-4
......@@ -859,6 +859,10 @@ pub const Step = extern struct {
859859 version_script: bool,
860860 _: u18 = 0,
861861 };
862
863 pub fn isDynamicLibrary(compile: *const Compile) bool {
864 return compile.flags3.kind == .lib and compile.flags2.linkage == .dynamic;
865 }
862866 };
863867
864868 pub const CheckFile = struct {
......@@ -1243,6 +1247,13 @@ pub const ImportTable = struct {
12431247 pub const Index = enum(u32) {
12441248 invalid = maxInt(u32),
12451249 _,
1250
1251 pub fn get(this: @This(), c: *const Configuration) ImportTable {
1252 return switch (this) {
1253 .invalid => unreachable,
1254 _ => extraData(c, ImportTable, @intFromEnum(this)),
1255 };
1256 }
12461257 };
12471258};
12481259
......@@ -1313,6 +1324,8 @@ pub const InstallDestDir = enum(u32) {
13131324/// Points into `string_bytes`, null-terminated.
13141325pub const OptionalString = enum(u32) {
13151326 empty = 0,
1327 /// The string "root".
1328 root = 1,
13161329 none = maxInt(u32),
13171330 _,
13181331
......@@ -1326,6 +1339,8 @@ pub const OptionalString = enum(u32) {
13261339/// Points into `string_bytes`, null-terminated.
13271340pub const String = enum(u32) {
13281341 empty = 0,
1342 /// The string "root".
1343 root = 1,
13291344 _,
13301345
13311346 pub fn slice(index: String, c: *const Configuration) [:0]const u8 {
......@@ -1954,15 +1969,23 @@ pub const Storage = enum {
19541969 };
19551970
19561971 /// Valid to call only when serializing.
1957 pub fn init(slice: []const Union) @This() {
1958 return .{ .data = slice.ptr, .len = slice.len };
1972 pub fn init(s: []const Union) @This() {
1973 return .{ .data = s.ptr, .len = s.len };
19591974 }
19601975
19611976 /// Valid to call only when deserializing.
1962 pub fn get(this: *const @This(), extra: []const u32) []const u32 {
1977 pub fn slice(this: *const @This(), extra: []const u32) []const u32 {
19631978 return extra[@intFromPtr(this.data)..][0..this.len];
19641979 }
19651980
1981 /// Valid to call only when deserializing.
1982 pub fn get(this: *const @This(), extra: []const u32, i: usize) Union {
1983 const elem = slice(this, extra)[i];
1984 return switch (this.tag(extra, i)) {
1985 inline else => |comptime_tag| @unionInit(Union, @tagName(comptime_tag), @enumFromInt(elem)),
1986 };
1987 }
1988
19661989 /// Valid to call only when deserializing.
19671990 pub fn tag(this: *const @This(), extra: []const u32, i: usize) Tag {
19681991 _ = this;
......@@ -2093,7 +2116,7 @@ pub const Storage = enum {
20932116 const len = buffer[data_start - 1];
20942117 defer i.* = data_start + len * @typeInfo(Field.Elem).@"struct".fields.len;
20952118 return .{ .mal = .{
2096 .bytes = @ptrCast(buffer[data_start..][0..len]),
2119 .bytes = @ptrCast(@constCast(buffer[data_start..][0..len])),
20972120 .len = len,
20982121 .capacity = len,
20992122 } };