authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-03-09 22:09:12-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-05-25 18:54:34-07:00
log71ac3f15b3740974e1bac091f32fc56933134ca2
treeddf8ea622f1cbb1b3945d5efa54a6b190054f1f5
parenteaffd5551349be6132ab33827e307f28ca8ac051

build system: implement LazyPath

Number of generated files is recorded in serialized Configuration. Maker preallocates array of generated files so that loads and stores can be synchronization-free (protected by the dependency tree ordering). More progress on Compile Step Zig CLI lowering.

15 files changed, 726 insertions(+), 458 deletions(-)

BRANCH_TODO created+12
...@@ -0,0 +1,12 @@
1* rename std.zig.Configuration to std.Build.Configuration
2* replace union(@This().Tag)
3* replace b.dupe() with string internment
4* don't forget to add -listen arg back
5* get zig init template working
6* finish migrating the rest of the build steps
7* make zig-pkg path root configurable in maker (make sure --system still works)
8* eliminate calls to getPath, getPath2, getPath3
9* solve the TODOs added in this branch
10* get zig tests passing
11* test a bunch of third party projects / help people migrate
12* refactor with DefaultingEnum
lib/compiler/Maker.zig+104
...@@ -33,6 +33,7 @@ graph: *Graph,...@@ -33,6 +33,7 @@ graph: *Graph,
33install_paths: InstallPaths,33install_paths: InstallPaths,
34scanned_config: *const ScannedConfig,34scanned_config: *const ScannedConfig,
35steps: []Step,35steps: []Step,
36generated_files: []Path,
3637
37available_rss: usize,38available_rss: usize,
38max_rss_is_default: bool,39max_rss_is_default: bool,
...@@ -115,7 +116,13 @@ pub fn main(init: process.Init.Minimal) !void {...@@ -115,7 +116,13 @@ pub fn main(init: process.Init.Minimal) !void {
115 .zig_exe = zig_exe,116 .zig_exe = zig_exe,
116 .environ_map = try init.environ.createMap(arena),117 .environ_map = try init.environ.createMap(arena),
117 .global_cache_root = global_cache_directory,118 .global_cache_root = global_cache_directory,
119 .local_cache_root = local_cache_directory,
118 .zig_lib_directory = zig_lib_directory,120 .zig_lib_directory = zig_lib_directory,
121 .build_root_directory = build_root_directory,
122 .pkg_root = .{
123 .root_dir = build_root_directory,
124 .sub_path = "zig-pkg",
125 },
119 };126 };
120127
121 graph.cache.addPrefix(.{ .path = null, .handle = cwd });128 graph.cache.addPrefix(.{ .path = null, .handle = cwd });
...@@ -525,6 +532,7 @@ pub fn main(init: process.Init.Minimal) !void {...@@ -525,6 +532,7 @@ pub fn main(init: process.Init.Minimal) !void {
525 .include = install_include_path,532 .include = install_include_path,
526 },533 },
527 .steps = try arena.alloc(Step, scanned_config.configuration.steps.len),534 .steps = try arena.alloc(Step, scanned_config.configuration.steps.len),
535 .generated_files = try arena.alloc(Path, scanned_config.configuration.generated_files_len),
528536
529 .available_rss = max_rss,537 .available_rss = max_rss,
530 .max_rss_is_default = false,538 .max_rss_is_default = false,
...@@ -1679,3 +1687,99 @@ fn initStdoutWriter(io: Io) *Writer {...@@ -1679,3 +1687,99 @@ fn initStdoutWriter(io: Io) *Writer {
1679 stdout_writer_allocation = Io.File.stdout().writerStreaming(io, &stdio_buffer_allocation);1687 stdout_writer_allocation = Io.File.stdout().writerStreaming(io, &stdio_buffer_allocation);
1680 return &stdout_writer_allocation.interface;1688 return &stdout_writer_allocation.interface;
1681}1689}
1690
1691/// `asking_step` is only used for debugging purposes; it's the step being run
1692/// that is asking for the path.
1693pub fn resolveLazyPath(
1694 maker: *const Maker,
1695 arena: Allocator,
1696 lazy_path: Configuration.LazyPath,
1697 asking_step_index: Configuration.Step.Index,
1698) Allocator.Error!Path {
1699 _ = asking_step_index; // TODO use this to enhance debugability when this function fails
1700 const c = &maker.scanned_config.configuration;
1701 const graph = maker.graph;
1702 return switch (lazy_path) {
1703 .source_path => |sp| try packagePath(maker, arena, sp.owner, sp.sub_path.slice(c)),
1704 .relative => |relative| switch (relative.flags.base) {
1705 .cwd => .{
1706 .root_dir = .cwd(),
1707 .sub_path = relative.sub_path.slice(c),
1708 },
1709 .local_cache => .{
1710 .root_dir = graph.local_cache_root,
1711 },
1712 .global_cache => .{
1713 .root_dir = graph.global_cache_root,
1714 },
1715 .build_root => .{
1716 .root_dir = graph.build_root_directory,
1717 },
1718 },
1719 .generated => |gen| {
1720 const base = maker.generated_files[@intFromEnum(gen.index)];
1721 var file_path = base;
1722 for (0..gen.flags.up) |_| {
1723 file_path.sub_path = Io.Dir.path.dirname(file_path.sub_path) orelse
1724 fatal("invalid LazyPath traversal: up {d} times from {f}", .{ gen.flags.up, base });
1725 }
1726 return file_path.join(arena, gen.sub_path.slice(c));
1727 },
1728 };
1729}
1730
1731pub fn resolveLazyPathIndex(
1732 maker: *const Maker,
1733 arena: Allocator,
1734 lazy_path_index: Configuration.LazyPath.Index,
1735 asking_step_index: Configuration.Step.Index,
1736) Allocator.Error!Path {
1737 const c = &maker.scanned_config.configuration;
1738 return resolveLazyPath(maker, arena, lazy_path_index.get(c), asking_step_index);
1739}
1740
1741/// `resolveLazyPath` is preferred, but this can be necessary when passing Path
1742/// objects to child processes.
1743pub fn resolveLazyPathAbs(
1744 maker: *const Maker,
1745 arena: Allocator,
1746 lazy_path: Configuration.LazyPath,
1747 asking_step_index: Configuration.Step.Index,
1748) Allocator.Error![]const u8 {
1749 const p = try resolveLazyPath(maker, arena, lazy_path, asking_step_index);
1750 const root_dir_path = p.root_dir.path orelse return p.subPathOrDot();
1751 if (p.sub_path.len == 0) return root_dir_path;
1752 return Io.Dir.path.join(arena, &.{ root_dir_path, p.sub_path });
1753}
1754
1755/// `resolveLazyPath` is preferred, but this can be necessary when passing Path
1756/// objects to child processes.
1757pub fn resolveLazyPathIndexAbs(
1758 maker: *const Maker,
1759 arena: Allocator,
1760 lazy_path_index: Configuration.LazyPath.Index,
1761 asking_step_index: Configuration.Step.Index,
1762) Allocator.Error![]const u8 {
1763 const c = &maker.scanned_config.configuration;
1764 return resolveLazyPathAbs(maker, arena, lazy_path_index.get(c), asking_step_index);
1765}
1766
1767fn packagePath(
1768 maker: *const Maker,
1769 arena: Allocator,
1770 package_index: Configuration.Package.Index,
1771 sub_path: []const u8,
1772) Allocator.Error!Path {
1773 const c = &maker.scanned_config.configuration;
1774 const graph = maker.graph;
1775 const package = package_index.get(c) orelse return .{
1776 .root_dir = graph.build_root_directory,
1777 .sub_path = sub_path,
1778 };
1779 const hash = package.hash.slice(c);
1780 const pkg_root = graph.pkg_root;
1781 return .{
1782 .root_dir = pkg_root.root_dir,
1783 .sub_path = try Io.Dir.path.join(arena, &.{ pkg_root.sub_path, hash, sub_path }),
1784 };
1785}
lib/compiler/Maker/Graph.zig+3
...@@ -13,7 +13,10 @@ cache: std.Build.Cache,...@@ -13,7 +13,10 @@ cache: std.Build.Cache,
13zig_exe: []const u8,13zig_exe: []const u8,
14environ_map: std.process.Environ.Map,14environ_map: std.process.Environ.Map,
15global_cache_root: std.Build.Cache.Directory,15global_cache_root: std.Build.Cache.Directory,
16local_cache_root: std.Build.Cache.Directory,
16zig_lib_directory: std.Build.Cache.Directory,17zig_lib_directory: std.Build.Cache.Directory,
18build_root_directory: std.Build.Cache.Directory,
19pkg_root: std.Build.Cache.Path,
1720
18debug_compiler_runtime_libs: ?std.builtin.OptimizeMode = null,21debug_compiler_runtime_libs: ?std.builtin.OptimizeMode = null,
19incremental: ?bool = null,22incremental: ?bool = null,
lib/compiler/Maker/Step/Compile.zig+253-103
...@@ -129,6 +129,7 @@ fn lowerZigArgs(...@@ -129,6 +129,7 @@ fn lowerZigArgs(
129 const conf = &maker.scanned_config.configuration;129 const conf = &maker.scanned_config.configuration;
130 const conf_step = compile_index.ptr(conf);130 const conf_step = compile_index.ptr(conf);
131 const conf_comp = conf_step.extended.get(conf.extra).compile;131 const conf_comp = conf_step.extended.get(conf.extra).compile;
132 const root_module_target = conf_comp.rootModuleTarget(conf);
132133
133 try zig_args.append(gpa, graph.zig_exe);134 try zig_args.append(gpa, graph.zig_exe);
134135
...@@ -232,17 +233,17 @@ fn lowerZigArgs(...@@ -232,17 +233,17 @@ fn lowerZigArgs(
232 }233 }
233 }234 }
234235
235 if (true) @panic("TODO");
236
237 // Inherit dependencies on system libraries and static libraries.236 // Inherit dependencies on system libraries and static libraries.
238 for (0..mod.link_objects.len) |lo_i| switch (mod.link_objects.get(conf.extra, lo_i)) {237 for (0..mod.link_objects.len) |lo_i| switch (mod.link_objects.get(conf.extra, lo_i)) {
239 .static_path => |static_path| {238 .static_path => |static_path| {
240 if (my_responsibility) {239 if (my_responsibility) {
241 try zig_args.append(gpa, static_path.getPath2(step));240 try zig_args.append(gpa, try maker.resolveLazyPathIndexAbs(arena, static_path, compile_index));
242 total_linker_objects += 1;241 total_linker_objects += 1;
243 }242 }
244 },243 },
245 .system_lib => |system_lib| {244 .system_lib => |system_lib_index| {
245 const system_lib = system_lib_index.get(conf);
246 const system_lib_name = system_lib.name.slice(conf);
246 const system_lib_gop = try seen_system_libs.getOrPut(arena, system_lib.name);247 const system_lib_gop = try seen_system_libs.getOrPut(arena, system_lib.name);
247 if (system_lib_gop.found_existing) {248 if (system_lib_gop.found_existing) {
248 try zig_args.appendSlice(gpa, system_lib_gop.value_ptr.*);249 try zig_args.appendSlice(gpa, system_lib_gop.value_ptr.*);
...@@ -254,37 +255,39 @@ fn lowerZigArgs(...@@ -254,37 +255,39 @@ fn lowerZigArgs(
254 if (already_linked)255 if (already_linked)
255 continue;256 continue;
256257
257 if ((system_lib.search_strategy != prev_search_strategy or258 if ((system_lib.flags.search_strategy != prev_search_strategy or
258 system_lib.preferred_link_mode != prev_preferred_link_mode) and259 system_lib.flags.preferred_link_mode != prev_preferred_link_mode) and
259 compile.linkage != .static)260 conf_comp.flags2.linkage != .static)
260 {261 {
261 switch (system_lib.search_strategy) {262 switch (system_lib.flags.search_strategy) {
262 .no_fallback => switch (system_lib.preferred_link_mode) {263 .no_fallback => switch (system_lib.flags.preferred_link_mode) {
263 .dynamic => try zig_args.append(gpa, "-search_dylibs_only"),264 .dynamic => try zig_args.append(gpa, "-search_dylibs_only"),
264 .static => try zig_args.append(gpa, "-search_static_only"),265 .static => try zig_args.append(gpa, "-search_static_only"),
265 },266 },
266 .paths_first => switch (system_lib.preferred_link_mode) {267 .paths_first => switch (system_lib.flags.preferred_link_mode) {
267 .dynamic => try zig_args.append(gpa, "-search_paths_first"),268 .dynamic => try zig_args.append(gpa, "-search_paths_first"),
268 .static => try zig_args.append(gpa, "-search_paths_first_static"),269 .static => try zig_args.append(gpa, "-search_paths_first_static"),
269 },270 },
270 .mode_first => switch (system_lib.preferred_link_mode) {271 .mode_first => switch (system_lib.flags.preferred_link_mode) {
271 .dynamic => try zig_args.append(gpa, "-search_dylibs_first"),272 .dynamic => try zig_args.append(gpa, "-search_dylibs_first"),
272 .static => try zig_args.append(gpa, "-search_static_first"),273 .static => try zig_args.append(gpa, "-search_static_first"),
273 },274 },
274 }275 }
275 prev_search_strategy = system_lib.search_strategy;276 prev_search_strategy = system_lib.flags.search_strategy;
276 prev_preferred_link_mode = system_lib.preferred_link_mode;277 prev_preferred_link_mode = system_lib.flags.preferred_link_mode;
277 }278 }
278279
279 const prefix: []const u8 = prefix: {280 const prefix: []const u8 = prefix: {
280 if (system_lib.needed) break :prefix "-needed-l";281 if (system_lib.flags.needed) break :prefix "-needed-l";
281 if (system_lib.weak) break :prefix "-weak-l";282 if (system_lib.flags.weak) break :prefix "-weak-l";
282 break :prefix "-l";283 break :prefix "-l";
283 };284 };
284 switch (system_lib.use_pkg_config) {285 switch (system_lib.flags.use_pkg_config) {
285 .no => try zig_args.append(gpa, try allocPrint(arena, "{s}{s}", .{ prefix, system_lib.name })),286 .no => try zig_args.append(gpa, try allocPrint(arena, "{s}{s}", .{
287 prefix, system_lib_name,
288 })),
286 .yes, .force => {289 .yes, .force => {
287 if (compile.runPkgConfig(maker, system_lib.name)) |result| {290 if (compile.runPkgConfig(maker, system_lib_name)) |result| {
288 try zig_args.appendSlice(gpa, result.cflags);291 try zig_args.appendSlice(gpa, result.cflags);
289 try zig_args.appendSlice(gpa, result.libs);292 try zig_args.appendSlice(gpa, result.libs);
290 try seen_system_libs.put(arena, system_lib.name, result.cflags);293 try seen_system_libs.put(arena, system_lib.name, result.cflags);
...@@ -294,17 +297,18 @@ fn lowerZigArgs(...@@ -294,17 +297,18 @@ fn lowerZigArgs(
294 error.PkgConfigFailed,297 error.PkgConfigFailed,
295 error.PkgConfigNotInstalled,298 error.PkgConfigNotInstalled,
296 error.PackageNotFound,299 error.PackageNotFound,
297 => switch (system_lib.use_pkg_config) {300 => switch (system_lib.flags.use_pkg_config) {
298 .yes => {301 .yes => {
299 // pkg-config failed, so fall back to linking the library302 // pkg-config failed, so fall back to linking the library
300 // by name directly.303 // by name directly.
301 try zig_args.append(gpa, try allocPrint(arena, "{s}{s}", .{304 try zig_args.append(gpa, try allocPrint(arena, "{s}{s}", .{
302 prefix,305 prefix, system_lib_name,
303 system_lib.name,
304 }));306 }));
305 },307 },
306 .force => {308 .force => {
307 return step.fail(maker, "pkg-config failed for library {s}", .{system_lib.name});309 return step.fail(maker, "pkg-config failed for library {s}", .{
310 system_lib_name,
311 });
308 },312 },
309 .no => unreachable,313 .no => unreachable,
310 },314 },
...@@ -314,23 +318,31 @@ fn lowerZigArgs(...@@ -314,23 +318,31 @@ fn lowerZigArgs(
314 },318 },
315 }319 }
316 },320 },
317 .other_step => |other| {321 .other_step => |other_step_index| {
318 switch (other.kind) {322 const other = other_step_index.ptr(conf);
323 const other_compile = other.extended.get(conf.extra).compile;
324 switch (other_compile.flags3.kind) {
319 .exe => return step.fail(maker, "cannot link with an executable build artifact", .{}),325 .exe => return step.fail(maker, "cannot link with an executable build artifact", .{}),
320 .@"test" => return step.fail(maker, "cannot link with a test", .{}),326 .@"test" => return step.fail(maker, "cannot link with a test", .{}),
321 .obj, .test_obj => {327 .obj, .test_obj => {
322 const included_in_lib_or_obj = !my_responsibility and328 const included_in_lib_or_obj = switch (dep_compile.flags3.kind) {
323 (dep_compile.kind == .lib or dep_compile.kind == .obj or dep_compile.kind == .test_obj);329 .lib, .obj, .test_obj => !my_responsibility,
330 else => false,
331 };
324 if (!already_linked and !included_in_lib_or_obj) {332 if (!already_linked and !included_in_lib_or_obj) {
325 try zig_args.append(gpa, other.getEmittedBin().getPath2(step));333 try zig_args.append(gpa, try maker.resolveLazyPathAbs(
334 arena,
335 .{ .generated = .{ .index = other_compile.generated_bin.value.? } },
336 compile_index,
337 ));
326 total_linker_objects += 1;338 total_linker_objects += 1;
327 }339 }
328 },340 },
329 .lib => l: {341 .lib => l: {
330 const other_produces_implib = other.producesImplib();342 const other_produces_implib = other_compile.producesImplib(conf);
331 const other_is_static = other_produces_implib or other.isStaticLibrary();343 const other_is_static = other_produces_implib or other_compile.isStaticLibrary();
332344
333 if (compile.isStaticLibrary() and other_is_static) {345 if (conf_comp.isStaticLibrary() and other_is_static) {
334 // Avoid putting a static library inside a static library.346 // Avoid putting a static library inside a static library.
335 break :l;347 break :l;
336 }348 }
...@@ -338,20 +350,25 @@ fn lowerZigArgs(...@@ -338,20 +350,25 @@ fn lowerZigArgs(
338 // For DLLs, we must link against the implib.350 // For DLLs, we must link against the implib.
339 // For everything else, we directly link351 // For everything else, we directly link
340 // against the library file.352 // against the library file.
341 const full_path_lib = if (other_produces_implib)353 const full_path_lib = try maker.resolveLazyPathAbs(
342 try other.getGeneratedFilePath("generated_implib", &compile.step)354 arena,
343 else355 .{ .generated = .{
344 try other.getGeneratedFilePath("generated_bin", &compile.step);356 .index = if (other_produces_implib)
357 other_compile.generated_implib.value.?
358 else
359 other_compile.generated_bin.value.?,
360 } },
361 compile_index,
362 );
345363
346 try zig_args.append(gpa, full_path_lib);364 try zig_args.append(gpa, full_path_lib);
347 total_linker_objects += 1;365 total_linker_objects += 1;
348366
349 if (other.linkage == .dynamic and367 if (other_compile.flags2.linkage == .dynamic and
350 compile.rootModuleTarget().os.tag != .windows)368 root_module_target.flags.os_tag != .windows)
351 {369 {
352 if (Dir.path.dirname(full_path_lib)) |dirname| {370 if (Dir.path.dirname(full_path_lib)) |dirname| {
353 try zig_args.append(gpa, "-rpath");371 try zig_args.appendSlice(gpa, &.{ "-rpath", dirname });
354 try zig_args.append(gpa, dirname);
355 }372 }
356 }373 }
357 },374 },
...@@ -361,92 +378,96 @@ fn lowerZigArgs(...@@ -361,92 +378,96 @@ fn lowerZigArgs(
361 if (!my_responsibility) break :l;378 if (!my_responsibility) break :l;
362379
363 if (prev_has_cflags) {380 if (prev_has_cflags) {
364 try zig_args.append(gpa, "-cflags");381 try zig_args.appendSlice(gpa, &.{ "-cflags", "--" });
365 try zig_args.append(gpa, "--");
366 prev_has_cflags = false;382 prev_has_cflags = false;
367 }383 }
368 try zig_args.append(gpa, asm_file.getPath2(mod.owner, step));384 try zig_args.append(gpa, try maker.resolveLazyPathIndexAbs(arena, asm_file, compile_index));
369 total_linker_objects += 1;385 total_linker_objects += 1;
370 },386 },
371387
372 .c_source_file => |c_source_file| l: {388 .c_source_file => |c_source_file_index| l: {
373 if (!my_responsibility) break :l;389 if (!my_responsibility) break :l;
374390
375 if (prev_has_cflags or c_source_file.flags.len != 0) {391 const c_source_file = c_source_file_index.get(conf);
376 try zig_args.append(gpa, "-cflags");392
377 for (c_source_file.flags) |arg| {393 if (prev_has_cflags or c_source_file.args.slice.len != 0) {
378 try zig_args.append(gpa, arg);394 try zig_args.ensureUnusedCapacity(gpa, 2 + c_source_file.args.slice.len);
395 zig_args.appendAssumeCapacity("-cflags");
396 for (c_source_file.args.slice) |arg| {
397 zig_args.appendAssumeCapacity(arg.slice(conf));
379 }398 }
380 try zig_args.append(gpa, "--");399 zig_args.appendAssumeCapacity("--");
381 }400 }
382 prev_has_cflags = (c_source_file.flags.len != 0);401 prev_has_cflags = (c_source_file.args.slice.len != 0);
383402
384 if (c_source_file.language) |lang| {403 if (c_source_file.flags.lang.get()) |lang|
385 try zig_args.append(gpa, "-x");404 (try zig_args.addManyAsArray(gpa, 2)).* = .{ "-x", lang.clangIdentifier() };
386 try zig_args.append(gpa, lang.internalIdentifier());
387 }
388405
389 try zig_args.append(gpa, c_source_file.file.getPath2(mod.owner, step));406 try zig_args.append(gpa, try maker.resolveLazyPathIndexAbs(arena, c_source_file.file, compile_index));
407
408 if (c_source_file.flags.lang != .default)
409 (try zig_args.addManyAsArray(gpa, 2)).* = .{ "-x", "none" };
390410
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;411 total_linker_objects += 1;
396 },412 },
397413
398 .c_source_files => |c_source_files| l: {414 .c_source_files => |c_source_files_index| l: {
399 if (!my_responsibility) break :l;415 if (!my_responsibility) break :l;
400416
401 if (prev_has_cflags or c_source_files.flags.len != 0) {417 const c_source_files = c_source_files_index.get(conf);
402 try zig_args.append(gpa, "-cflags");418
403 for (c_source_files.flags) |arg| {419 if (prev_has_cflags or c_source_files.args.slice.len != 0) {
404 try zig_args.append(gpa, arg);420 try zig_args.ensureUnusedCapacity(gpa, 2 + c_source_files.args.slice.len);
421 zig_args.appendAssumeCapacity("-cflags");
422 for (c_source_files.args.slice) |arg| {
423 zig_args.appendAssumeCapacity(arg.slice(conf));
405 }424 }
406 try zig_args.append(gpa, "--");425 zig_args.appendAssumeCapacity("--");
407 }426 }
408 prev_has_cflags = (c_source_files.flags.len != 0);427 prev_has_cflags = (c_source_files.args.slice.len != 0);
409428
410 if (c_source_files.language) |lang| {429 if (c_source_files.flags.lang.get()) |lang|
411 try zig_args.append(gpa, "-x");430 (try zig_args.addManyAsArray(gpa, 2)).* = .{ "-x", lang.clangIdentifier() };
412 try zig_args.append(gpa, lang.internalIdentifier());
413 }
414431
415 const root_path = c_source_files.root.getPath2(mod.owner, step);432 const root_path = try maker.resolveLazyPathIndexAbs(arena, c_source_files.root, compile_index);
416 for (c_source_files.files) |file| {433 try zig_args.ensureUnusedCapacity(gpa, c_source_files.sub_paths.slice.len);
417 try zig_args.append(gpa, try Dir.path.join(arena, &.{ root_path, file }));434 for (c_source_files.sub_paths.slice) |sub_path| {
435 zig_args.appendAssumeCapacity(try Dir.path.join(arena, &.{
436 root_path, sub_path.slice(conf),
437 }));
418 }438 }
419439
420 if (c_source_files.language != null) {440 if (c_source_files.flags.lang != .default)
421 try zig_args.append(gpa, "-x");441 (try zig_args.addManyAsArray(gpa, 2)).* = .{ "-x", "none" };
422 try zig_args.append(gpa, "none");
423 }
424442
425 total_linker_objects += c_source_files.files.len;443 total_linker_objects += c_source_files.sub_paths.slice.len;
426 },444 },
427445
428 .win32_resource_file => |rc_source_file| l: {446 .win32_resource_file => |rc_source_file_index| l: {
429 if (!my_responsibility) break :l;447 if (!my_responsibility) break :l;
430448
431 if (rc_source_file.flags.len == 0 and rc_source_file.include_paths.len == 0) {449 const rc_source_file = rc_source_file_index.get(conf);
450
451 if (rc_source_file.args.slice.len == 0 and rc_source_file.include_paths.slice.len == 0) {
432 if (prev_has_rcflags) {452 if (prev_has_rcflags) {
433 try zig_args.append(gpa, "-rcflags");453 (try zig_args.addManyAsArray(gpa, 2)).* = .{ "-rcflags", "--" };
434 try zig_args.append(gpa, "--");
435 prev_has_rcflags = false;454 prev_has_rcflags = false;
436 }455 }
437 } else {456 } else {
438 try zig_args.append(gpa, "-rcflags");457 try zig_args.ensureUnusedCapacity(gpa, 1 + rc_source_file.args.slice.len);
439 for (rc_source_file.flags) |arg| {458 zig_args.appendAssumeCapacity("-rcflags");
440 try zig_args.append(gpa, arg);459 for (rc_source_file.args.slice) |arg| {
460 zig_args.appendAssumeCapacity(arg.slice(conf));
441 }461 }
442 for (rc_source_file.include_paths) |include_path| {462 try zig_args.ensureUnusedCapacity(gpa, 1 + 2 * rc_source_file.include_paths.slice.len);
443 try zig_args.append(gpa, "/I");463 for (rc_source_file.include_paths.slice) |include_path| {
444 try zig_args.append(gpa, include_path.getPath2(mod.owner, step));464 zig_args.appendAssumeCapacity("/I");
465 zig_args.appendAssumeCapacity(try maker.resolveLazyPathIndexAbs(arena, include_path, compile_index));
445 }466 }
446 try zig_args.append(gpa, "--");467 zig_args.appendAssumeCapacity("--");
447 prev_has_rcflags = true;468 prev_has_rcflags = true;
448 }469 }
449 try zig_args.append(gpa, rc_source_file.file.getPath2(mod.owner, step));470 try zig_args.append(gpa, try maker.resolveLazyPathIndexAbs(arena, rc_source_file.file, compile_index));
450 total_linker_objects += 1;471 total_linker_objects += 1;
451 },472 },
452 };473 };
...@@ -455,9 +476,10 @@ fn lowerZigArgs(...@@ -455,9 +476,10 @@ fn lowerZigArgs(
455 // have the correct parent module, but only if the module is part of476 // have the correct parent module, but only if the module is part of
456 // this compilation.477 // this compilation.
457 if (!my_responsibility) continue;478 if (!my_responsibility) continue;
458 if (cli_named_modules.modules.getIndex(mod)) |module_cli_index| {479 if (cli_named_modules.modules.getIndex(mod_index)) |module_cli_index| {
459 const module_cli_name = cli_named_modules.names.keys()[module_cli_index];480 const module_cli_name = cli_named_modules.names.keys()[module_cli_index];
460 try mod.appendZigProcessFlags(zig_args, step);481 if (true) @panic("TODO");
482 try appendModuleFlags(zig_args, step);
461483
462 // --dep arguments484 // --dep arguments
463 try zig_args.ensureUnusedCapacity(mod.import_table.count() * 2);485 try zig_args.ensureUnusedCapacity(mod.import_table.count() * 2);
...@@ -510,12 +532,12 @@ fn lowerZigArgs(...@@ -510,12 +532,12 @@ fn lowerZigArgs(
510 if (is_linking_libc) zig_args.appendAssumeCapacity("-lc");532 if (is_linking_libc) zig_args.appendAssumeCapacity("-lc");
511 }533 }
512534
513 if (true) @panic("TODO");535 if (conf_comp.win32_manifest.value) |manifest_file| {
514536 try zig_args.append(gpa, try maker.resolveLazyPathIndexAbs(arena, manifest_file, compile_index));
515 if (conf_comp.win32_manifest) |manifest_file| {
516 try zig_args.append(gpa, manifest_file.getPath2(step));
517 }537 }
518538
539 if (true) @panic("TODO");
540
519 if (conf_comp.win32_module_definition) |module_file| {541 if (conf_comp.win32_module_definition) |module_file| {
520 try zig_args.append(gpa, module_file.getPath2(step));542 try zig_args.append(gpa, module_file.getPath2(step));
521 }543 }
...@@ -623,27 +645,26 @@ fn lowerZigArgs(...@@ -623,27 +645,26 @@ fn lowerZigArgs(
623 "--version", try allocPrint(arena, "{f}", .{version}),645 "--version", try allocPrint(arena, "{f}", .{version}),
624 });646 });
625647
626 if (compile.rootModuleTarget().os.tag.isDarwin()) {648 if (root_module_target.flags.os_tag.isDarwin()) {
627 const install_name = compile.install_name orelse try allocPrint(arena, "@rpath/{s}{s}{s}", .{649 const install_name = compile.install_name orelse try allocPrint(arena, "@rpath/{s}{s}{s}", .{
628 compile.rootModuleTarget().libPrefix(),650 root_module_target.libPrefix(),
629 compile.name,651 compile.name,
630 compile.rootModuleTarget().dynamicLibSuffix(),652 root_module_target.dynamicLibSuffix(),
631 });653 });
632 try zig_args.append(gpa, "-install_name");654 try zig_args.appendSlice(gpa, &.{ "-install_name", install_name });
633 try zig_args.append(gpa, install_name);
634 }655 }
635 }656 }
636657
637 if (compile.entitlements) |entitlements| {658 if (compile.entitlements) |entitlements| {
638 try zig_args.appendSlice(gpa, &[_][]const u8{ "--entitlements", entitlements });659 try zig_args.appendSlice(gpa, &.{ "--entitlements", entitlements });
639 }660 }
640 if (compile.pagezero_size) |pagezero_size| {661 if (compile.pagezero_size) |pagezero_size| {
641 const size = try allocPrint(arena, "{x}", .{pagezero_size});662 const size = try allocPrint(arena, "{x}", .{pagezero_size});
642 try zig_args.appendSlice(gpa, &[_][]const u8{ "-pagezero_size", size });663 try zig_args.appendSlice(gpa, &.{ "-pagezero_size", size });
643 }664 }
644 if (compile.headerpad_size) |headerpad_size| {665 if (compile.headerpad_size) |headerpad_size| {
645 const size = try allocPrint(arena, "{x}", .{headerpad_size});666 const size = try allocPrint(arena, "{x}", .{headerpad_size});
646 try zig_args.appendSlice(gpa, &[_][]const u8{ "-headerpad", size });667 try zig_args.appendSlice(gpa, &.{ "-headerpad", size });
647 }668 }
648 if (compile.headerpad_max_install_names) {669 if (compile.headerpad_max_install_names) {
649 try zig_args.append(gpa, "-headerpad_max_install_names");670 try zig_args.append(gpa, "-headerpad_max_install_names");
...@@ -1019,7 +1040,8 @@ const PkgConfigResult = struct {...@@ -1019,7 +1040,8 @@ const PkgConfigResult = struct {
10191040
1020/// Run pkg-config for the given library name and parse the output, returning the arguments1041/// Run pkg-config for the given library name and parse the output, returning the arguments
1021/// that should be passed to zig to link the given library.1042/// that should be passed to zig to link the given library.
1022fn runPkgConfig(compile: *Compile, maker: *Maker, lib_name: []const u8) !PkgConfigResult {1043fn runPkgConfig(compile: *const Compile, maker: *const Maker, lib_name: []const u8) !PkgConfigResult {
1044 if (true) @panic("TODO");
1023 const graph = maker.graph;1045 const graph = maker.graph;
1024 const wl_rpath_prefix = "-Wl,-rpath,";1046 const wl_rpath_prefix = "-Wl,-rpath,";
10251047
...@@ -1365,3 +1387,131 @@ fn getModuleList(...@@ -1365,3 +1387,131 @@ fn getModuleList(
13651387
1366 return modules;1388 return modules;
1367}1389}
1390
1391fn appendModuleFlags(
1392 m: *Module,
1393 zig_args: *std.array_list.Managed([]const u8),
1394 asking_step: ?*Step,
1395) !void {
1396 const b = m.owner;
1397
1398 try addFlag(zig_args, m.strip, "-fstrip", "-fno-strip");
1399 try addFlag(zig_args, m.single_threaded, "-fsingle-threaded", "-fno-single-threaded");
1400 try addFlag(zig_args, m.stack_check, "-fstack-check", "-fno-stack-check");
1401 try addFlag(zig_args, m.stack_protector, "-fstack-protector", "-fno-stack-protector");
1402 try addFlag(zig_args, m.omit_frame_pointer, "-fomit-frame-pointer", "-fno-omit-frame-pointer");
1403 try addFlag(zig_args, m.error_tracing, "-ferror-tracing", "-fno-error-tracing");
1404 try addFlag(zig_args, m.sanitize_thread, "-fsanitize-thread", "-fno-sanitize-thread");
1405 try addFlag(zig_args, m.fuzz, "-ffuzz", "-fno-fuzz");
1406 try addFlag(zig_args, m.valgrind, "-fvalgrind", "-fno-valgrind");
1407 try addFlag(zig_args, m.pic, "-fPIC", "-fno-PIC");
1408 try addFlag(zig_args, m.red_zone, "-mred-zone", "-mno-red-zone");
1409 try addFlag(zig_args, m.no_builtin, "-fno-builtin", "-fbuiltin");
1410
1411 if (m.sanitize_c) |sc| switch (sc) {
1412 .off => try zig_args.append("-fno-sanitize-c"),
1413 .trap => try zig_args.append("-fsanitize-c=trap"),
1414 .full => try zig_args.append("-fsanitize-c=full"),
1415 };
1416
1417 if (m.dwarf_format) |dwarf_format| {
1418 try zig_args.append(switch (dwarf_format) {
1419 .@"32" => "-gdwarf32",
1420 .@"64" => "-gdwarf64",
1421 });
1422 }
1423
1424 if (m.unwind_tables) |unwind_tables| {
1425 try zig_args.append(switch (unwind_tables) {
1426 .none => "-fno-unwind-tables",
1427 .sync => "-funwind-tables",
1428 .async => "-fasync-unwind-tables",
1429 });
1430 }
1431
1432 try zig_args.ensureUnusedCapacity(1);
1433 if (m.optimize) |optimize| switch (optimize) {
1434 .Debug => zig_args.appendAssumeCapacity("-ODebug"),
1435 .ReleaseSmall => zig_args.appendAssumeCapacity("-OReleaseSmall"),
1436 .ReleaseFast => zig_args.appendAssumeCapacity("-OReleaseFast"),
1437 .ReleaseSafe => zig_args.appendAssumeCapacity("-OReleaseSafe"),
1438 };
1439
1440 if (m.code_model != .default) {
1441 try zig_args.append("-mcmodel");
1442 try zig_args.append(@tagName(m.code_model));
1443 }
1444
1445 if (m.resolved_target) |*target| {
1446 // Communicate the query via CLI since it's more compact.
1447 if (!target.query.isNative()) {
1448 try zig_args.appendSlice(&.{
1449 "-target", try target.query.zigTriple(b.allocator),
1450 "-mcpu", try target.query.serializeCpuAlloc(b.allocator),
1451 });
1452 if (target.query.dynamic_linker) |*dynamic_linker| {
1453 if (dynamic_linker.get()) |dynamic_linker_path| {
1454 try zig_args.append("--dynamic-linker");
1455 try zig_args.append(dynamic_linker_path);
1456 } else {
1457 try zig_args.append("--no-dynamic-linker");
1458 }
1459 }
1460 }
1461 }
1462
1463 for (m.export_symbol_names) |symbol_name| {
1464 try zig_args.append(b.fmt("--export={s}", .{symbol_name}));
1465 }
1466
1467 for (m.include_dirs.items) |include_dir| {
1468 try appendIncludeDirFlags(include_dir, b, zig_args, asking_step);
1469 }
1470
1471 try zig_args.appendSlice(m.c_macros.items);
1472
1473 try zig_args.ensureUnusedCapacity(2 * m.lib_paths.items.len);
1474 for (m.lib_paths.items) |lib_path| {
1475 zig_args.appendAssumeCapacity("-L");
1476 zig_args.appendAssumeCapacity(lib_path.getPath2(b, asking_step));
1477 }
1478
1479 try zig_args.ensureUnusedCapacity(2 * m.rpaths.items.len);
1480 for (m.rpaths.items) |rpath| switch (rpath) {
1481 .lazy_path => |lp| {
1482 zig_args.appendAssumeCapacity("-rpath");
1483 zig_args.appendAssumeCapacity(lp.getPath2(b, asking_step));
1484 },
1485 .special => |bytes| {
1486 zig_args.appendAssumeCapacity("-rpath");
1487 zig_args.appendAssumeCapacity(bytes);
1488 },
1489 };
1490}
1491
1492fn appendIncludeDirFlags(
1493 include_dir: Configuration.Module.IncludeDir,
1494 b: *std.Build,
1495 zig_args: *std.array_list.Managed([]const u8),
1496 asking_step: ?*Step,
1497) !void {
1498 const flag: []const u8, const lazy_path: Configuration.LazyPath = switch (include_dir) {
1499 // zig fmt: off
1500 .path => |lp| .{ "-I", lp },
1501 .path_system => |lp| .{ "-isystem", lp },
1502 .path_after => |lp| .{ "-idirafter", lp },
1503 .framework_path => |lp| .{ "-F", lp },
1504 .framework_path_system => |lp| .{ "-iframework", lp },
1505 .config_header_step => |ch| .{ "-I", ch.getOutputDir() },
1506 .other_step => |comp| .{ "-I", comp.installed_headers_include_tree.?.getDirectory() },
1507 // zig fmt: on
1508 .embed_path => |lazy_path| {
1509 // Special case: this is a single arg.
1510 const resolved = lazy_path.getPath3(b, asking_step);
1511 const arg = b.fmt("--embed-dir={f}", .{resolved});
1512 return zig_args.append(arg);
1513 },
1514 };
1515 const resolved_str = try lazy_path.getPath3(b, asking_step).toString(b.graph.arena);
1516 return zig_args.appendSlice(&.{ flag, resolved_str });
1517}
lib/compiler/configurer.zig+27-5
...@@ -96,6 +96,7 @@ pub fn main(init: process.Init.Minimal) !void {...@@ -96,6 +96,7 @@ pub fn main(init: process.Init.Minimal) !void {
96 .query = .{},96 .query = .{},
97 .result = try std.zig.system.resolveTargetQuery(io, .{}),97 .result = try std.zig.system.resolveTargetQuery(io, .{}),
98 },98 },
99 .generated_files = .empty,
99 };100 };
100101
101 graph.cache.addPrefix(.{ .path = null, .handle = cwd });102 graph.cache.addPrefix(.{ .path = null, .handle = cwd });
...@@ -242,7 +243,7 @@ const Serialize = struct {...@@ -242,7 +243,7 @@ const Serialize = struct {
242 return gop.value_ptr.*;243 return gop.value_ptr.*;
243 }244 }
244245
245 fn addOptionalLazyPathEnum(s: *Serialize, lp: ?std.Build.LazyPath) !Configuration.OptionalLazyPath {246 fn addOptionalLazyPathEnum(s: *Serialize, lp: ?std.Build.LazyPath) !Configuration.LazyPath.OptionalIndex {
246 const wc = s.wc;247 const wc = s.wc;
247 return @enumFromInt(switch (lp orelse return .none) {248 return @enumFromInt(switch (lp orelse return .none) {
248 .src_path => |src_path| i: {249 .src_path => |src_path| i: {
...@@ -257,6 +258,7 @@ const Serialize = struct {...@@ -257,6 +258,7 @@ const Serialize = struct {
257 const sub_path = try wc.addString(generated.sub_path);258 const sub_path = try wc.addString(generated.sub_path);
258 break :i try wc.addExtra(@as(Configuration.LazyPath.Generated, .{259 break :i try wc.addExtra(@as(Configuration.LazyPath.Generated, .{
259 .flags = .{ .up = @intCast(generated.up) },260 .flags = .{ .up = @intCast(generated.up) },
261 .index = generated.index,
260 .sub_path = sub_path,262 .sub_path = sub_path,
261 }));263 }));
262 },264 },
...@@ -278,11 +280,11 @@ const Serialize = struct {...@@ -278,11 +280,11 @@ const Serialize = struct {
278 });280 });
279 }281 }
280282
281 fn addOptionalLazyPath(s: *Serialize, lp: ?std.Build.LazyPath) !?Configuration.LazyPath {283 fn addOptionalLazyPath(s: *Serialize, lp: ?std.Build.LazyPath) !?Configuration.LazyPath.Index {
282 return (try addOptionalLazyPathEnum(s, lp)).unwrap();284 return (try addOptionalLazyPathEnum(s, lp)).unwrap();
283 }285 }
284286
285 fn addLazyPath(s: *Serialize, lp: std.Build.LazyPath) !Configuration.LazyPath {287 fn addLazyPath(s: *Serialize, lp: std.Build.LazyPath) !Configuration.LazyPath.Index {
286 return @enumFromInt(@intFromEnum(try addOptionalLazyPathEnum(s, lp)));288 return @enumFromInt(@intFromEnum(try addOptionalLazyPathEnum(s, lp)));
287 }289 }
288290
...@@ -351,8 +353,8 @@ const Serialize = struct {...@@ -351,8 +353,8 @@ const Serialize = struct {
351 })));353 })));
352 }354 }
353355
354 fn initLazyPathList(s: *Serialize, list: []const std.Build.LazyPath) ![]const Configuration.LazyPath {356 fn initLazyPathList(s: *Serialize, list: []const std.Build.LazyPath) ![]const Configuration.LazyPath.Index {
355 const result = try s.arena.alloc(Configuration.LazyPath, list.len);357 const result = try s.arena.alloc(Configuration.LazyPath.Index, list.len);
356 for (result, list) |*dest, src| dest.* = try addLazyPath(s, src);358 for (result, list) |*dest, src| dest.* = try addLazyPath(s, src);
357 return result;359 return result;
358 }360 }
...@@ -665,6 +667,15 @@ fn serialize(b: *std.Build, wc: *Configuration.Wip, writer: *Io.Writer) !void {...@@ -665,6 +667,15 @@ fn serialize(b: *std.Build, wc: *Configuration.Wip, writer: *Io.Writer) !void {
665 } else .none,667 } else .none,
666 .linker_script = c.linker_script != null,668 .linker_script = c.linker_script != null,
667 .version_script = c.version_script != null,669 .version_script = c.version_script != null,
670 .emit_directory = c.emit_directory != .none,
671 .generated_docs = c.generated_docs != .none,
672 .generated_asm = c.generated_asm != .none,
673 .generated_bin = c.generated_bin != .none,
674 .generated_pdb = c.generated_pdb != .none,
675 .generated_implib = c.generated_implib != .none,
676 .generated_llvm_bc = c.generated_llvm_bc != .none,
677 .generated_llvm_ir = c.generated_llvm_ir != .none,
678 .generated_h = c.generated_h != .none,
668 },679 },
669 .root_module = try s.addModule(c.root_module),680 .root_module = try s.addModule(c.root_module),
670 .root_name = try wc.addString(c.name),681 .root_name = try wc.addString(c.name),
...@@ -709,6 +720,16 @@ fn serialize(b: *std.Build, wc: *Configuration.Wip, writer: *Io.Writer) !void {...@@ -709,6 +720,16 @@ fn serialize(b: *std.Build, wc: *Configuration.Wip, writer: *Io.Writer) !void {
709 .simple => .{ .simple = try s.addLazyPath(tr.path) },720 .simple => .{ .simple = try s.addLazyPath(tr.path) },
710 .server => .{ .server = try s.addLazyPath(tr.path) },721 .server => .{ .server = try s.addLazyPath(tr.path) },
711 } else .default },722 } else .default },
723
724 .emit_directory = .{ .value = c.emit_directory.unwrap() },
725 .generated_docs = .{ .value = c.generated_docs.unwrap() },
726 .generated_asm = .{ .value = c.generated_asm.unwrap() },
727 .generated_bin = .{ .value = c.generated_bin.unwrap() },
728 .generated_pdb = .{ .value = c.generated_pdb.unwrap() },
729 .generated_implib = .{ .value = c.generated_implib.unwrap() },
730 .generated_llvm_bc = .{ .value = c.generated_llvm_bc.unwrap() },
731 .generated_llvm_ir = .{ .value = c.generated_llvm_ir.unwrap() },
732 .generated_h = .{ .value = c.generated_h.unwrap() },
712 }));733 }));
713734
714 break :e @enumFromInt(extra_index);735 break :e @enumFromInt(extra_index);
...@@ -804,6 +825,7 @@ fn serialize(b: *std.Build, wc: *Configuration.Wip, writer: *Io.Writer) !void {...@@ -804,6 +825,7 @@ fn serialize(b: *std.Build, wc: *Configuration.Wip, writer: *Io.Writer) !void {
804825
805 try wc.write(writer, .{826 try wc.write(writer, .{
806 .default_step = s.stepIndex(b.default_step),827 .default_step = s.stepIndex(b.default_step),
828 .generated_files_len = @intCast(graph.generated_files.items.len),
807 });829 });
808}830}
809831
lib/std/Build.zig+19-13
...@@ -1,4 +1,5 @@...@@ -1,4 +1,5 @@
1const Build = @This();1const Build = @This();
2
2const builtin = @import("builtin");3const builtin = @import("builtin");
34
4const std = @import("std.zig");5const std = @import("std.zig");
...@@ -111,6 +112,14 @@ pub const Graph = struct {...@@ -111,6 +112,14 @@ pub const Graph = struct {
111 /// process via `Step.Run` API but cannot be observed in the configure112 /// process via `Step.Run` API but cannot be observed in the configure
112 /// phase.113 /// phase.
113 have_run_args: bool = false,114 have_run_args: bool = false,
115
116 /// Indexes correspond to `Configuration.GeneratedFileIndex`.
117 generated_files: std.ArrayList(*Step),
118
119 pub fn addGeneratedFile(graph: *Graph, owner: *Step) Configuration.GeneratedFileIndex {
120 graph.generated_files.append(graph.arena, owner) catch @panic("OOM");
121 return @enumFromInt(graph.generated_files.items.len - 1);
122 }
114};123};
115124
116const AvailableDeps = []const struct { []const u8, []const u8 };125const AvailableDeps = []const struct { []const u8, []const u8 };
...@@ -865,7 +874,7 @@ pub fn dupe(b: *Build, bytes: []const u8) []u8 {...@@ -865,7 +874,7 @@ pub fn dupe(b: *Build, bytes: []const u8) []u8 {
865 return dupeInner(b.allocator, bytes);874 return dupeInner(b.allocator, bytes);
866}875}
867876
868pub fn dupeInner(allocator: std.mem.Allocator, bytes: []const u8) []u8 {877pub fn dupeInner(allocator: Allocator, bytes: []const u8) []u8 {
869 return allocator.dupe(u8, bytes) catch @panic("OOM");878 return allocator.dupe(u8, bytes) catch @panic("OOM");
870}879}
871880
...@@ -881,7 +890,7 @@ pub fn dupePath(b: *Build, bytes: []const u8) []u8 {...@@ -881,7 +890,7 @@ pub fn dupePath(b: *Build, bytes: []const u8) []u8 {
881 return dupePathInner(b.allocator, bytes);890 return dupePathInner(b.allocator, bytes);
882}891}
883892
884fn dupePathInner(allocator: std.mem.Allocator, bytes: []const u8) []u8 {893fn dupePathInner(allocator: Allocator, bytes: []const u8) []u8 {
885 const the_copy = dupeInner(allocator, bytes);894 const the_copy = dupeInner(allocator, bytes);
886 for (the_copy) |*byte| {895 for (the_copy) |*byte| {
887 switch (byte.*) {896 switch (byte.*) {
...@@ -2068,13 +2077,6 @@ pub fn runBuild(b: *Build, build_zig: anytype) anyerror!void {...@@ -2068,13 +2077,6 @@ pub fn runBuild(b: *Build, build_zig: anytype) anyerror!void {
2068 }2077 }
2069}2078}
20702079
2071/// A file that is generated by a build step.
2072/// This struct is an interface that is meant to be used with `@fieldParentPtr` to implement the actual path logic.
2073pub const GeneratedFile = struct {
2074 /// The step that generates the file.
2075 step: *Step,
2076};
2077
2078// dirnameAllowEmpty is a variant of fs.path.dirname2080// dirnameAllowEmpty is a variant of fs.path.dirname
2079// that allows "" to refer to the root for relative paths.2081// that allows "" to refer to the root for relative paths.
2080//2082//
...@@ -2114,7 +2116,7 @@ pub const LazyPath = union(enum) {...@@ -2114,7 +2116,7 @@ pub const LazyPath = union(enum) {
2114 },2116 },
21152117
2116 generated: struct {2118 generated: struct {
2117 file: *const GeneratedFile,2119 index: Configuration.GeneratedFileIndex,
21182120
2119 /// The number of parent directories to go up.2121 /// The number of parent directories to go up.
2120 /// 0 means the generated file itself.2122 /// 0 means the generated file itself.
...@@ -2242,7 +2244,11 @@ pub const LazyPath = union(enum) {...@@ -2242,7 +2244,11 @@ pub const LazyPath = union(enum) {
2242 pub fn addStepDependencies(lazy_path: LazyPath, other_step: *Step) void {2244 pub fn addStepDependencies(lazy_path: LazyPath, other_step: *Step) void {
2243 switch (lazy_path) {2245 switch (lazy_path) {
2244 .src_path, .cwd_relative, .dependency => {},2246 .src_path, .cwd_relative, .dependency => {},
2245 .generated => |gen| other_step.dependOn(gen.file.step),2247 .generated => |gen| {
2248 const graph = other_step.owner.graph;
2249 const generated_owner_step = graph.generated_files.items[@intFromEnum(gen.index)];
2250 other_step.dependOn(generated_owner_step);
2251 },
2246 }2252 }
2247 }2253 }
22482254
...@@ -2266,7 +2272,7 @@ pub const LazyPath = union(enum) {...@@ -2266,7 +2272,7 @@ pub const LazyPath = union(enum) {
2266 return lazy_path.dupeInner(b.allocator);2272 return lazy_path.dupeInner(b.allocator);
2267 }2273 }
22682274
2269 fn dupeInner(lazy_path: LazyPath, allocator: std.mem.Allocator) LazyPath {2275 fn dupeInner(lazy_path: LazyPath, allocator: Allocator) LazyPath {
2270 return switch (lazy_path) {2276 return switch (lazy_path) {
2271 .src_path => |sp| .{ .src_path = .{2277 .src_path => |sp| .{ .src_path = .{
2272 .owner = sp.owner,2278 .owner = sp.owner,
...@@ -2274,7 +2280,7 @@ pub const LazyPath = union(enum) {...@@ -2274,7 +2280,7 @@ pub const LazyPath = union(enum) {
2274 } },2280 } },
2275 .cwd_relative => |p| .{ .cwd_relative = dupePathInner(allocator, p) },2281 .cwd_relative => |p| .{ .cwd_relative = dupePathInner(allocator, p) },
2276 .generated => |gen| .{ .generated = .{2282 .generated => |gen| .{ .generated = .{
2277 .file = gen.file,2283 .index = gen.index,
2278 .up = gen.up,2284 .up = gen.up,
2279 .sub_path = dupePathInner(allocator, gen.sub_path),2285 .sub_path = dupePathInner(allocator, gen.sub_path),
2280 } },2286 } },
lib/std/Build/Module.zig+2-139
...@@ -89,7 +89,8 @@ pub const CSourceLanguage = enum {...@@ -89,7 +89,8 @@ pub const CSourceLanguage = enum {
89 /// Assembly with the C preprocessor89 /// Assembly with the C preprocessor
90 assembly_with_preprocessor,90 assembly_with_preprocessor,
9191
92 pub fn internalIdentifier(self: CSourceLanguage) []const u8 {92 /// The value passed to "-x" CLI flag of Clang.
93 pub fn clangIdentifier(self: CSourceLanguage) [:0]const u8 {
93 return switch (self) {94 return switch (self) {
94 .c => "c",95 .c => "c",
95 .cpp => "c++",96 .cpp => "c++",
...@@ -164,33 +165,6 @@ pub const IncludeDir = union(enum) {...@@ -164,33 +165,6 @@ pub const IncludeDir = union(enum) {
164 other_step: *Step.Compile,165 other_step: *Step.Compile,
165 config_header_step: *Step.ConfigHeader,166 config_header_step: *Step.ConfigHeader,
166 embed_path: LazyPath,167 embed_path: LazyPath,
167
168 pub fn appendZigProcessFlags(
169 include_dir: IncludeDir,
170 b: *std.Build,
171 zig_args: *std.array_list.Managed([]const u8),
172 asking_step: ?*Step,
173 ) !void {
174 const flag: []const u8, const lazy_path: LazyPath = switch (include_dir) {
175 // zig fmt: off
176 .path => |lp| .{ "-I", lp },
177 .path_system => |lp| .{ "-isystem", lp },
178 .path_after => |lp| .{ "-idirafter", lp },
179 .framework_path => |lp| .{ "-F", lp },
180 .framework_path_system => |lp| .{ "-iframework", lp },
181 .config_header_step => |ch| .{ "-I", ch.getOutputDir() },
182 .other_step => |comp| .{ "-I", comp.installed_headers_include_tree.?.getDirectory() },
183 // zig fmt: on
184 .embed_path => |lazy_path| {
185 // Special case: this is a single arg.
186 const resolved = lazy_path.getPath3(b, asking_step);
187 const arg = b.fmt("--embed-dir={f}", .{resolved});
188 return zig_args.append(arg);
189 },
190 };
191 const resolved_str = try lazy_path.getPath3(b, asking_step).toString(b.graph.arena);
192 return zig_args.appendSlice(&.{ flag, resolved_str });
193 }
194};168};
195169
196pub const LinkFrameworkOptions = struct {170pub const LinkFrameworkOptions = struct {
...@@ -533,117 +507,6 @@ pub fn addCMacro(m: *Module, name: []const u8, value: []const u8) void {...@@ -533,117 +507,6 @@ pub fn addCMacro(m: *Module, name: []const u8, value: []const u8) void {
533 m.c_macros.append(b.allocator, b.fmt("-D{s}={s}", .{ name, value })) catch @panic("OOM");507 m.c_macros.append(b.allocator, b.fmt("-D{s}={s}", .{ name, value })) catch @panic("OOM");
534}508}
535509
536pub fn appendZigProcessFlags(
537 m: *Module,
538 zig_args: *std.array_list.Managed([]const u8),
539 asking_step: ?*Step,
540) !void {
541 const b = m.owner;
542
543 try addFlag(zig_args, m.strip, "-fstrip", "-fno-strip");
544 try addFlag(zig_args, m.single_threaded, "-fsingle-threaded", "-fno-single-threaded");
545 try addFlag(zig_args, m.stack_check, "-fstack-check", "-fno-stack-check");
546 try addFlag(zig_args, m.stack_protector, "-fstack-protector", "-fno-stack-protector");
547 try addFlag(zig_args, m.omit_frame_pointer, "-fomit-frame-pointer", "-fno-omit-frame-pointer");
548 try addFlag(zig_args, m.error_tracing, "-ferror-tracing", "-fno-error-tracing");
549 try addFlag(zig_args, m.sanitize_thread, "-fsanitize-thread", "-fno-sanitize-thread");
550 try addFlag(zig_args, m.fuzz, "-ffuzz", "-fno-fuzz");
551 try addFlag(zig_args, m.valgrind, "-fvalgrind", "-fno-valgrind");
552 try addFlag(zig_args, m.pic, "-fPIC", "-fno-PIC");
553 try addFlag(zig_args, m.red_zone, "-mred-zone", "-mno-red-zone");
554 try addFlag(zig_args, m.no_builtin, "-fno-builtin", "-fbuiltin");
555
556 if (m.sanitize_c) |sc| switch (sc) {
557 .off => try zig_args.append("-fno-sanitize-c"),
558 .trap => try zig_args.append("-fsanitize-c=trap"),
559 .full => try zig_args.append("-fsanitize-c=full"),
560 };
561
562 if (m.dwarf_format) |dwarf_format| {
563 try zig_args.append(switch (dwarf_format) {
564 .@"32" => "-gdwarf32",
565 .@"64" => "-gdwarf64",
566 });
567 }
568
569 if (m.unwind_tables) |unwind_tables| {
570 try zig_args.append(switch (unwind_tables) {
571 .none => "-fno-unwind-tables",
572 .sync => "-funwind-tables",
573 .async => "-fasync-unwind-tables",
574 });
575 }
576
577 try zig_args.ensureUnusedCapacity(1);
578 if (m.optimize) |optimize| switch (optimize) {
579 .Debug => zig_args.appendAssumeCapacity("-ODebug"),
580 .ReleaseSmall => zig_args.appendAssumeCapacity("-OReleaseSmall"),
581 .ReleaseFast => zig_args.appendAssumeCapacity("-OReleaseFast"),
582 .ReleaseSafe => zig_args.appendAssumeCapacity("-OReleaseSafe"),
583 };
584
585 if (m.code_model != .default) {
586 try zig_args.append("-mcmodel");
587 try zig_args.append(@tagName(m.code_model));
588 }
589
590 if (m.resolved_target) |*target| {
591 // Communicate the query via CLI since it's more compact.
592 if (!target.query.isNative()) {
593 try zig_args.appendSlice(&.{
594 "-target", try target.query.zigTriple(b.allocator),
595 "-mcpu", try target.query.serializeCpuAlloc(b.allocator),
596 });
597 if (target.query.dynamic_linker) |*dynamic_linker| {
598 if (dynamic_linker.get()) |dynamic_linker_path| {
599 try zig_args.append("--dynamic-linker");
600 try zig_args.append(dynamic_linker_path);
601 } else {
602 try zig_args.append("--no-dynamic-linker");
603 }
604 }
605 }
606 }
607
608 for (m.export_symbol_names) |symbol_name| {
609 try zig_args.append(b.fmt("--export={s}", .{symbol_name}));
610 }
611
612 for (m.include_dirs.items) |include_dir| {
613 try include_dir.appendZigProcessFlags(b, zig_args, asking_step);
614 }
615
616 try zig_args.appendSlice(m.c_macros.items);
617
618 try zig_args.ensureUnusedCapacity(2 * m.lib_paths.items.len);
619 for (m.lib_paths.items) |lib_path| {
620 zig_args.appendAssumeCapacity("-L");
621 zig_args.appendAssumeCapacity(lib_path.getPath2(b, asking_step));
622 }
623
624 try zig_args.ensureUnusedCapacity(2 * m.rpaths.items.len);
625 for (m.rpaths.items) |rpath| switch (rpath) {
626 .lazy_path => |lp| {
627 zig_args.appendAssumeCapacity("-rpath");
628 zig_args.appendAssumeCapacity(lp.getPath2(b, asking_step));
629 },
630 .special => |bytes| {
631 zig_args.appendAssumeCapacity("-rpath");
632 zig_args.appendAssumeCapacity(bytes);
633 },
634 };
635}
636
637fn addFlag(
638 args: *std.array_list.Managed([]const u8),
639 opt: ?bool,
640 then_name: []const u8,
641 else_name: []const u8,
642) !void {
643 const cond = opt orelse return;
644 return args.append(if (cond) then_name else else_name);
645}
646
647fn linkLibraryOrObject(m: *Module, other: *Step.Compile) void {510fn linkLibraryOrObject(m: *Module, other: *Step.Compile) void {
648 const allocator = m.owner.allocator;511 const allocator = m.owner.allocator;
649 _ = other.getEmittedBin(); // Indicate there is a dependency on the outputted binary.512 _ = other.getEmittedBin(); // Indicate there is a dependency on the outputted binary.
lib/std/Build/Step/Compile.zig+26-77
...@@ -1,4 +1,5 @@...@@ -1,4 +1,5 @@
1const Compile = @This();1const Compile = @This();
2
2const builtin = @import("builtin");3const builtin = @import("builtin");
34
4const std = @import("std");5const std = @import("std");
...@@ -13,8 +14,8 @@ const Step = std.Build.Step;...@@ -13,8 +14,8 @@ const Step = std.Build.Step;
13const LazyPath = std.Build.LazyPath;14const LazyPath = std.Build.LazyPath;
14const Module = std.Build.Module;15const Module = std.Build.Module;
15const InstallDir = std.Build.InstallDir;16const InstallDir = std.Build.InstallDir;
16const GeneratedFile = std.Build.GeneratedFile;
17const Path = std.Build.Cache.Path;17const Path = std.Build.Cache.Path;
18const Configuration = std.Build.Configuration;
1819
19pub const base_tag: Step.Tag = .compile;20pub const base_tag: Step.Tag = .compile;
2021
...@@ -212,19 +213,6 @@ allow_so_scripts: ?bool = null,...@@ -212,19 +213,6 @@ allow_so_scripts: ?bool = null,
212/// otherwise.213/// otherwise.
213expect_errors: ?ExpectedCompileErrors = null,214expect_errors: ?ExpectedCompileErrors = null,
214215
215emit_directory: ?*GeneratedFile,
216
217generated_docs: ?*GeneratedFile,
218generated_asm: ?*GeneratedFile,
219generated_bin: ?*GeneratedFile,
220generated_pdb: ?*GeneratedFile,
221// hack for stage2_x86_64 + coff
222generated_compiler_rt_dyn_lib: ?*GeneratedFile,
223generated_implib: ?*GeneratedFile,
224generated_llvm_bc: ?*GeneratedFile,
225generated_llvm_ir: ?*GeneratedFile,
226generated_h: ?*GeneratedFile,
227
228/// The maximum number of distinct errors within a compilation step Defaults to216/// The maximum number of distinct errors within a compilation step Defaults to
229/// `std.math.maxInt(u16)`. Overrides the argument passed to `zig build`.217/// `std.math.maxInt(u16)`. Overrides the argument passed to `zig build`.
230error_limit: ?u32 = null,218error_limit: ?u32 = null,
...@@ -248,6 +236,16 @@ is_linking_libcpp: bool = false,...@@ -248,6 +236,16 @@ is_linking_libcpp: bool = false,
248/// builtin fuzzer, see the `fuzz` flag in `Module`.236/// builtin fuzzer, see the `fuzz` flag in `Module`.
249sanitize_coverage_trace_pc_guard: ?bool = null,237sanitize_coverage_trace_pc_guard: ?bool = null,
250238
239emit_directory: Configuration.OptionalGeneratedFileIndex = .none,
240generated_docs: Configuration.OptionalGeneratedFileIndex = .none,
241generated_asm: Configuration.OptionalGeneratedFileIndex = .none,
242generated_bin: Configuration.OptionalGeneratedFileIndex = .none,
243generated_pdb: Configuration.OptionalGeneratedFileIndex = .none,
244generated_implib: Configuration.OptionalGeneratedFileIndex = .none,
245generated_llvm_bc: Configuration.OptionalGeneratedFileIndex = .none,
246generated_llvm_ir: Configuration.OptionalGeneratedFileIndex = .none,
247generated_h: Configuration.OptionalGeneratedFileIndex = .none,
248
251pub const ExpectedCompileErrors = union(enum) {249pub const ExpectedCompileErrors = union(enum) {
252 contains: []const u8,250 contains: []const u8,
253 exact: []const []const u8,251 exact: []const []const u8,
...@@ -291,7 +289,7 @@ pub const Options = struct {...@@ -291,7 +289,7 @@ pub const Options = struct {
291 entitlements: ?LazyPath = null,289 entitlements: ?LazyPath = null,
292};290};
293291
294pub const Kind = std.Build.Configuration.Step.Compile.Kind;292pub const Kind = Configuration.Step.Compile.Kind;
295293
296pub const HeaderInstallation = union(enum) {294pub const HeaderInstallation = union(enum) {
297 file: File,295 file: File,
...@@ -362,6 +360,9 @@ pub const TestRunner = struct {...@@ -362,6 +360,9 @@ pub const TestRunner = struct {
362};360};
363361
364pub fn create(owner: *std.Build, options: Options) *Compile {362pub fn create(owner: *std.Build, options: Options) *Compile {
363 const graph = owner.graph;
364 const arena = graph.arena;
365
365 const name = owner.dupe(options.name);366 const name = owner.dupe(options.name);
366 if (mem.find(u8, name, "/") != null or mem.find(u8, name, "\\") != null) {367 if (mem.find(u8, name, "/") != null or mem.find(u8, name, "\\") != null) {
367 panic("invalid name: '{s}'. It looks like a file path, but it is supposed to be the library or application name.", .{name});368 panic("invalid name: '{s}'. It looks like a file path, but it is supposed to be the library or application name.", .{name});
...@@ -376,12 +377,12 @@ pub fn create(owner: *std.Build, options: Options) *Compile {...@@ -376,12 +377,12 @@ pub fn create(owner: *std.Build, options: Options) *Compile {
376 if (options.kind.isTest() and mem.eql(u8, name, "test"))377 if (options.kind.isTest() and mem.eql(u8, name, "test"))
377 @tagName(options.kind)378 @tagName(options.kind)
378 else379 else
379 owner.fmt("{s} {s}", .{ @tagName(options.kind), name }),380 owner.fmt("{t} {s}", .{ options.kind, name }),
380 @tagName(options.root_module.optimize orelse .Debug),381 @tagName(options.root_module.optimize orelse .Debug),
381 resolved_target.query.zigTriple(owner.allocator) catch @panic("OOM"),382 resolved_target.query.zigTriple(arena) catch @panic("OOM"),
382 });383 });
383384
384 const out_filename = std.zig.binNameAlloc(owner.allocator, .{385 const out_filename = std.zig.binNameAlloc(arena, .{
385 .root_name = name,386 .root_name = name,
386 .target = target,387 .target = target,
387 .output_mode = switch (options.kind) {388 .output_mode = switch (options.kind) {
...@@ -393,7 +394,7 @@ pub fn create(owner: *std.Build, options: Options) *Compile {...@@ -393,7 +394,7 @@ pub fn create(owner: *std.Build, options: Options) *Compile {
393 .version = options.version,394 .version = options.version,
394 }) catch @panic("OOM");395 }) catch @panic("OOM");
395396
396 const compile = owner.allocator.create(Compile) catch @panic("OOM");397 const compile = arena.create(Compile) catch @panic("OOM");
397 compile.* = .{398 compile.* = .{
398 .root_module = options.root_module,399 .root_module = options.root_module,
399 .verbose_link = false,400 .verbose_link = false,
...@@ -420,17 +421,6 @@ pub fn create(owner: *std.Build, options: Options) *Compile {...@@ -420,17 +421,6 @@ pub fn create(owner: *std.Build, options: Options) *Compile {
420 .rdynamic = false,421 .rdynamic = false,
421 .force_undefined_symbols = .empty,422 .force_undefined_symbols = .empty,
422423
423 .emit_directory = null,
424 .generated_docs = null,
425 .generated_asm = null,
426 .generated_bin = null,
427 .generated_pdb = null,
428 .generated_compiler_rt_dyn_lib = null,
429 .generated_implib = null,
430 .generated_llvm_bc = null,
431 .generated_llvm_ir = null,
432 .generated_h = null,
433
434 .use_llvm = options.use_llvm,424 .use_llvm = options.use_llvm,
435 .use_lld = options.use_lld,425 .use_lld = options.use_lld,
436 .use_new_linker = null,426 .use_new_linker = null,
...@@ -706,13 +696,12 @@ pub fn setLibCFile(compile: *Compile, libc_file: ?LazyPath) void {...@@ -706,13 +696,12 @@ pub fn setLibCFile(compile: *Compile, libc_file: ?LazyPath) void {
706 }696 }
707}697}
708698
709fn getEmittedFileGeneric(compile: *Compile, output_file: *?*GeneratedFile) LazyPath {699fn getEmittedFileGeneric(compile: *Compile, output_file: *Configuration.OptionalGeneratedFileIndex) LazyPath {
710 if (output_file.*) |file| return .{ .generated = .{ .file = file } };700 if (output_file.unwrap()) |index| return .{ .generated = .{ .index = index } };
711 const arena = compile.step.owner.allocator;701 const graph = compile.step.owner.graph;
712 const generated_file = arena.create(GeneratedFile) catch @panic("OOM");702 const index = graph.addGeneratedFile(&compile.step);
713 generated_file.* = .{ .step = &compile.step };703 output_file.* = .init(index);
714 output_file.* = generated_file;704 return .{ .generated = .{ .index = index } };
715 return .{ .generated = .{ .file = generated_file } };
716}705}
717706
718/// Returns the path to the directory that contains the emitted binary file.707/// Returns the path to the directory that contains the emitted binary file.
...@@ -785,46 +774,6 @@ pub fn setExecCmd(compile: *Compile, args: []const ?[]const u8) void {...@@ -785,46 +774,6 @@ pub fn setExecCmd(compile: *Compile, args: []const ?[]const u8) void {
785 compile.exec_cmd_args = duped_args;774 compile.exec_cmd_args = duped_args;
786}775}
787776
788fn getGeneratedFilePath(compile: *Compile, comptime tag_name: []const u8, asking_step: ?*Step) ![]const u8 {
789 const step = &compile.step;
790 const b = step.owner;
791 const graph = b.graph;
792 const io = graph.io;
793 const maybe_path: ?*GeneratedFile = @field(compile, tag_name);
794
795 const generated_file = maybe_path orelse {
796 const stderr = try io.lockStderr(&.{}, graph.stderr_mode);
797 std.Build.dumpBadGetPathHelp(&compile.step, stderr.terminal(), compile.step.owner, asking_step) catch {};
798 io.unlockStderr();
799 @panic("missing emit option for " ++ tag_name);
800 };
801
802 const path = generated_file.path orelse {
803 const stderr = try io.lockStderr(&.{}, graph.stderr_mode);
804 std.Build.dumpBadGetPathHelp(&compile.step, stderr.terminal(), compile.step.owner, asking_step) catch {};
805 io.unlockStderr();
806 @panic(tag_name ++ " is null. Is there a missing step dependency?");
807 };
808
809 return path;
810}
811
812fn outputPath(c: *Compile, out_dir: std.Build.Cache.Path, ea: std.zig.EmitArtifact) []const u8 {
813 const arena = c.step.owner.graph.arena;
814 const name = ea.cacheName(arena, .{
815 .root_name = c.name,
816 .target = &c.root_module.resolved_target.?.result,
817 .output_mode = switch (c.kind) {
818 .lib => .Lib,
819 .obj, .test_obj => .Obj,
820 .exe, .@"test" => .Exe,
821 },
822 .link_mode = c.linkage,
823 .version = c.version,
824 }) catch @panic("OOM");
825 return out_dir.joinString(arena, name) catch @panic("OOM");
826}
827
828pub fn rootModuleTarget(c: *Compile) std.Target {777pub fn rootModuleTarget(c: *Compile) std.Target {
829 // The root module is always given a target, so we know this to be non-null.778 // The root module is always given a target, so we know this to be non-null.
830 return c.root_module.resolved_target.?.result;779 return c.root_module.resolved_target.?.result;
lib/std/Build/Step/ConfigHeader.zig+9-8
...@@ -5,6 +5,7 @@ const Io = std.Io;...@@ -5,6 +5,7 @@ const Io = std.Io;
5const Step = std.Build.Step;5const Step = std.Build.Step;
6const Allocator = std.mem.Allocator;6const Allocator = std.mem.Allocator;
7const Writer = std.Io.Writer;7const Writer = std.Io.Writer;
8const Configuration = std.Build.Configuration;
89
9pub const Style = union(enum) {10pub const Style = union(enum) {
10 /// A configure format supported by autotools that uses `#undef foo` to11 /// A configure format supported by autotools that uses `#undef foo` to
...@@ -40,7 +41,7 @@ pub const Value = union(enum) {...@@ -40,7 +41,7 @@ pub const Value = union(enum) {
40step: Step,41step: Step,
41values: std.array_hash_map.String(Value),42values: std.array_hash_map.String(Value),
42/// This directory contains the generated file under the name `include_path`.43/// This directory contains the generated file under the name `include_path`.
43generated_dir: std.Build.GeneratedFile,44generated_dir: Configuration.GeneratedFileIndex,
4445
45style: Style,46style: Style,
46max_bytes: usize,47max_bytes: usize,
...@@ -58,7 +59,9 @@ pub const Options = struct {...@@ -58,7 +59,9 @@ pub const Options = struct {
58};59};
5960
60pub fn create(owner: *std.Build, options: Options) *ConfigHeader {61pub fn create(owner: *std.Build, options: Options) *ConfigHeader {
61 const config_header = owner.allocator.create(ConfigHeader) catch @panic("OOM");62 const graph = owner.graph;
63 const arena = graph.arena;
64 const config_header = arena.create(ConfigHeader) catch @panic("OOM");
6265
63 var include_path: []const u8 = "config.h";66 var include_path: []const u8 = "config.h";
6467
...@@ -80,11 +83,9 @@ pub fn create(owner: *std.Build, options: Options) *ConfigHeader {...@@ -80,11 +83,9 @@ pub fn create(owner: *std.Build, options: Options) *ConfigHeader {
80 }83 }
8184
82 const name = if (options.style.getPath()) |s|85 const name = if (options.style.getPath()) |s|
83 owner.fmt("configure {s} header {s} to {s}", .{86 owner.fmt("configure {t} header {s} to {s}", .{ options.style, s.getDisplayName(), include_path })
84 @tagName(options.style), s.getDisplayName(), include_path,
85 })
86 else87 else
87 owner.fmt("configure {s} header to {s}", .{ @tagName(options.style), include_path });88 owner.fmt("configure {t} header to {s}", .{ options.style, include_path });
8889
89 config_header.* = .{90 config_header.* = .{
90 .step = .init(.{91 .step = .init(.{
...@@ -100,7 +101,7 @@ pub fn create(owner: *std.Build, options: Options) *ConfigHeader {...@@ -100,7 +101,7 @@ pub fn create(owner: *std.Build, options: Options) *ConfigHeader {
100 .max_bytes = options.max_bytes,101 .max_bytes = options.max_bytes,
101 .include_path = include_path,102 .include_path = include_path,
102 .include_guard_override = options.include_guard_override,103 .include_guard_override = options.include_guard_override,
103 .generated_dir = .{ .step = &config_header.step },104 .generated_dir = graph.addGeneratedFile(&config_header.step),
104 };105 };
105106
106 if (options.style.getPath()) |s| {107 if (options.style.getPath()) |s| {
...@@ -125,7 +126,7 @@ pub fn addValues(config_header: *ConfigHeader, values: anytype) void {...@@ -125,7 +126,7 @@ pub fn addValues(config_header: *ConfigHeader, values: anytype) void {
125}126}
126127
127pub fn getOutputDir(ch: *ConfigHeader) std.Build.LazyPath {128pub fn getOutputDir(ch: *ConfigHeader) std.Build.LazyPath {
128 return .{ .generated = .{ .file = &ch.generated_dir } };129 return .{ .generated = .{ .index = &ch.generated_dir } };
129}130}
130pub fn getOutputFile(ch: *ConfigHeader) std.Build.LazyPath {131pub fn getOutputFile(ch: *ConfigHeader) std.Build.LazyPath {
131 return ch.getOutputDir().path(ch.step.owner, ch.include_path);132 return ch.getOutputDir().path(ch.step.owner, ch.include_path);
lib/std/Build/Step/ObjCopy.zig+14-7
...@@ -9,6 +9,7 @@ const Step = std.Build.Step;...@@ -9,6 +9,7 @@ const Step = std.Build.Step;
9const elf = std.elf;9const elf = std.elf;
10const fs = std.fs;10const fs = std.fs;
11const sort = std.sort;11const sort = std.sort;
12const Configuration = std.Build.Configuration;
1213
13pub const base_tag: Step.Tag = .objcopy;14pub const base_tag: Step.Tag = .objcopy;
1415
...@@ -71,8 +72,8 @@ pub const SetSectionFlags = struct {...@@ -71,8 +72,8 @@ pub const SetSectionFlags = struct {
71step: Step,72step: Step,
72input_file: std.Build.LazyPath,73input_file: std.Build.LazyPath,
73basename: []const u8,74basename: []const u8,
74output_file: std.Build.GeneratedFile,75output_file: Configuration.GeneratedFileIndex,
75output_file_debug: ?std.Build.GeneratedFile,76output_file_debug: Configuration.OptionalGeneratedFileIndex,
7677
77format: ?RawFormat,78format: ?RawFormat,
78only_section: ?[]const u8,79only_section: ?[]const u8,
...@@ -108,7 +109,10 @@ pub fn create(...@@ -108,7 +109,10 @@ pub fn create(
108 input_file: std.Build.LazyPath,109 input_file: std.Build.LazyPath,
109 options: Options,110 options: Options,
110) *ObjCopy {111) *ObjCopy {
111 const objcopy = owner.allocator.create(ObjCopy) catch @panic("OOM");112 const graph = owner.graph;
113 const arena = graph.arena;
114
115 const objcopy = arena.create(ObjCopy) catch @panic("OOM");
112 objcopy.* = ObjCopy{116 objcopy.* = ObjCopy{
113 .step = Step.init(.{117 .step = Step.init(.{
114 .tag = base_tag,118 .tag = base_tag,
...@@ -118,8 +122,11 @@ pub fn create(...@@ -118,8 +122,11 @@ pub fn create(
118 }),122 }),
119 .input_file = input_file,123 .input_file = input_file,
120 .basename = options.basename orelse input_file.getDisplayName(),124 .basename = options.basename orelse input_file.getDisplayName(),
121 .output_file = std.Build.GeneratedFile{ .step = &objcopy.step },125 .output_file = graph.addGeneratedFile(&objcopy.step),
122 .output_file_debug = if (options.strip != .none and options.extract_to_separate_file) std.Build.GeneratedFile{ .step = &objcopy.step } else null,126 .output_file_debug = if (options.strip != .none and options.extract_to_separate_file)
127 .init(graph.addGeneratedFile(&objcopy.step))
128 else
129 .none,
123 .format = options.format,130 .format = options.format,
124 .only_section = options.only_section,131 .only_section = options.only_section,
125 .pad_to = options.pad_to,132 .pad_to = options.pad_to,
...@@ -134,10 +141,10 @@ pub fn create(...@@ -134,10 +141,10 @@ pub fn create(
134}141}
135142
136pub fn getOutput(objcopy: *const ObjCopy) std.Build.LazyPath {143pub fn getOutput(objcopy: *const ObjCopy) std.Build.LazyPath {
137 return .{ .generated = .{ .file = &objcopy.output_file } };144 return .{ .generated = .{ .index = objcopy.output_file } };
138}145}
139pub fn getOutputSeparatedDebug(objcopy: *const ObjCopy) ?std.Build.LazyPath {146pub fn getOutputSeparatedDebug(objcopy: *const ObjCopy) ?std.Build.LazyPath {
140 return if (objcopy.output_file_debug) |*file| .{ .generated = .{ .file = file } } else null;147 return if (objcopy.output_file_debug.unwrap()) |index| .{ .generated = .{ .index = index } } else null;
141}148}
142149
143fn make(step: *Step, options: Step.MakeOptions) !void {150fn make(step: *Step, options: Step.MakeOptions) !void {
lib/std/Build/Step/Options.zig+9-6
...@@ -1,24 +1,28 @@...@@ -1,24 +1,28 @@
1const Options = @This();1const Options = @This();
2
2const builtin = @import("builtin");3const builtin = @import("builtin");
34
4const std = @import("std");5const std = @import("std");
5const Io = std.Io;6const Io = std.Io;
6const fs = std.fs;7const fs = std.fs;
7const Step = std.Build.Step;8const Step = std.Build.Step;
8const GeneratedFile = std.Build.GeneratedFile;
9const LazyPath = std.Build.LazyPath;9const LazyPath = std.Build.LazyPath;
10const Configuration = std.Build.Configuration;
1011
11pub const base_tag: Step.Tag = .options;12pub const base_tag: Step.Tag = .options;
1213
13step: Step,14step: Step,
14generated_file: GeneratedFile,15generated_file: Configuration.GeneratedFileIndex,
1516
16contents: std.ArrayList(u8),17contents: std.ArrayList(u8),
17args: std.ArrayList(Arg),18args: std.ArrayList(Arg),
18encountered_types: std.StringHashMapUnmanaged(void),19encountered_types: std.StringHashMapUnmanaged(void),
1920
20pub fn create(owner: *std.Build) *Options {21pub fn create(owner: *std.Build) *Options {
21 const options = owner.allocator.create(Options) catch @panic("OOM");22 const graph = owner.graph;
23 const arena = graph.arena;
24
25 const options = arena.create(Options) catch @panic("OOM");
22 options.* = .{26 options.* = .{
23 .step = .init(.{27 .step = .init(.{
24 .tag = base_tag,28 .tag = base_tag,
...@@ -26,12 +30,11 @@ pub fn create(owner: *std.Build) *Options {...@@ -26,12 +30,11 @@ pub fn create(owner: *std.Build) *Options {
26 .owner = owner,30 .owner = owner,
27 .makeFn = make,31 .makeFn = make,
28 }),32 }),
29 .generated_file = undefined,33 .generated_file = graph.addGeneratedFile(&options.step),
30 .contents = .empty,34 .contents = .empty,
31 .args = .empty,35 .args = .empty,
32 .encountered_types = .empty,36 .encountered_types = .empty,
33 };37 };
34 options.generated_file = .{ .step = &options.step };
3538
36 return options;39 return options;
37}40}
...@@ -434,7 +437,7 @@ pub fn createModule(options: *Options) *std.Build.Module {...@@ -434,7 +437,7 @@ pub fn createModule(options: *Options) *std.Build.Module {
434/// Returns the main artifact of this Build Step which is a Zig source file437/// Returns the main artifact of this Build Step which is a Zig source file
435/// generated from the key-value pairs of the Options.438/// generated from the key-value pairs of the Options.
436pub fn getOutput(options: *Options) LazyPath {439pub fn getOutput(options: *Options) LazyPath {
437 return .{ .generated = .{ .file = &options.generated_file } };440 return .{ .generated = .{ .index = options.generated_file } };
438}441}
439442
440fn make(step: *Step, make_options: Step.MakeOptions) !void {443fn make(step: *Step, make_options: Step.MakeOptions) !void {
lib/std/Build/Step/Run.zig+26-17
...@@ -11,6 +11,7 @@ const process = std.process;...@@ -11,6 +11,7 @@ const process = std.process;
11const EnvMap = std.process.Environ.Map;11const EnvMap = std.process.Environ.Map;
12const assert = std.debug.assert;12const assert = std.debug.assert;
13const Path = std.Build.Cache.Path;13const Path = std.Build.Cache.Path;
14const Configuration = std.Build.Configuration;
1415
15pub const base_tag: Step.Tag = .run;16pub const base_tag: Step.Tag = .run;
1617
...@@ -162,7 +163,7 @@ pub const DecoratedLazyPath = struct {...@@ -162,7 +163,7 @@ pub const DecoratedLazyPath = struct {
162};163};
163164
164pub const Output = struct {165pub const Output = struct {
165 generated_file: std.Build.GeneratedFile,166 generated_file: Configuration.GeneratedFileIndex,
166 prefix: []const u8,167 prefix: []const u8,
167 basename: []const u8,168 basename: []const u8,
168};169};
...@@ -272,21 +273,23 @@ pub fn addPrefixedOutputFileArg(...@@ -272,21 +273,23 @@ pub fn addPrefixedOutputFileArg(
272 basename: []const u8,273 basename: []const u8,
273) std.Build.LazyPath {274) std.Build.LazyPath {
274 const b = run.step.owner;275 const b = run.step.owner;
276 const graph = b.graph;
277 const arena = graph.arena;
275 if (basename.len == 0) @panic("basename must not be empty");278 if (basename.len == 0) @panic("basename must not be empty");
276279
277 const output = b.allocator.create(Output) catch @panic("OOM");280 const output = arena.create(Output) catch @panic("OOM");
278 output.* = .{281 output.* = .{
279 .prefix = b.dupe(prefix),282 .prefix = b.dupe(prefix),
280 .basename = b.dupe(basename),283 .basename = b.dupe(basename),
281 .generated_file = .{ .step = &run.step },284 .generated_file = graph.addGeneratedFile(&run.step),
282 };285 };
283 run.argv.append(b.allocator, .{ .output_file = output }) catch @panic("OOM");286 run.argv.append(arena, .{ .output_file = output }) catch @panic("OOM");
284287
285 if (run.rename_step_with_output_arg) {288 if (run.rename_step_with_output_arg) {
286 run.setName(b.fmt("{s} ({s})", .{ run.step.name, basename }));289 run.setName(b.fmt("{s} ({s})", .{ run.step.name, basename }));
287 }290 }
288291
289 return .{ .generated = .{ .file = &output.generated_file } };292 return .{ .generated = .{ .index = output.generated_file } };
290}293}
291294
292/// Appends an input file to the command line arguments.295/// Appends an input file to the command line arguments.
...@@ -470,20 +473,22 @@ pub fn addDepFileOutputArg(run: *Run, basename: []const u8) std.Build.LazyPath {...@@ -470,20 +473,22 @@ pub fn addDepFileOutputArg(run: *Run, basename: []const u8) std.Build.LazyPath {
470/// Only one dep file argument is allowed by instance.473/// Only one dep file argument is allowed by instance.
471pub fn addPrefixedDepFileOutputArg(run: *Run, prefix: []const u8, basename: []const u8) std.Build.LazyPath {474pub fn addPrefixedDepFileOutputArg(run: *Run, prefix: []const u8, basename: []const u8) std.Build.LazyPath {
472 const b = run.step.owner;475 const b = run.step.owner;
476 const graph = b.graph;
477 const arena = graph.arena;
473 assert(run.dep_output_file == null);478 assert(run.dep_output_file == null);
474479
475 const dep_file = b.allocator.create(Output) catch @panic("OOM");480 const dep_file = arena.create(Output) catch @panic("OOM");
476 dep_file.* = .{481 dep_file.* = .{
477 .prefix = b.dupe(prefix),482 .prefix = b.dupe(prefix),
478 .basename = b.dupe(basename),483 .basename = b.dupe(basename),
479 .generated_file = .{ .step = &run.step },484 .generated_file = graph.addGeneratedFile(&run.step),
480 };485 };
481486
482 run.dep_output_file = dep_file;487 run.dep_output_file = dep_file;
483488
484 run.argv.append(b.allocator, .{ .output_file = dep_file }) catch @panic("OOM");489 run.argv.append(arena, .{ .output_file = dep_file }) catch @panic("OOM");
485490
486 return .{ .generated = .{ .file = &dep_file.generated_file } };491 return .{ .generated = .{ .index = dep_file.generated_file } };
487}492}
488493
489pub fn addArg(run: *Run, arg: []const u8) void {494pub fn addArg(run: *Run, arg: []const u8) void {
...@@ -627,20 +632,22 @@ pub fn captureStdErr(run: *Run, options: CapturedStdIo.Options) std.Build.LazyPa...@@ -627,20 +632,22 @@ pub fn captureStdErr(run: *Run, options: CapturedStdIo.Options) std.Build.LazyPa
627 assert(run.stdio != .zig_test);632 assert(run.stdio != .zig_test);
628633
629 const b = run.step.owner;634 const b = run.step.owner;
635 const graph = b.graph;
636 const arena = graph.arena;
630637
631 if (run.captured_stderr) |captured| return .{ .generated = .{ .file = &captured.output.generated_file } };638 if (run.captured_stderr) |captured| return .{ .generated = .{ .index = captured.output.generated_file } };
632639
633 const captured = b.allocator.create(CapturedStdIo) catch @panic("OOM");640 const captured = arena.create(CapturedStdIo) catch @panic("OOM");
634 captured.* = .{641 captured.* = .{
635 .output = .{642 .output = .{
636 .prefix = "",643 .prefix = "",
637 .basename = if (options.basename) |basename| b.dupe(basename) else "stderr",644 .basename = if (options.basename) |basename| b.dupe(basename) else "stderr",
638 .generated_file = .{ .step = &run.step },645 .generated_file = graph.addGeneratedFile(&run.step),
639 },646 },
640 .trim_whitespace = options.trim_whitespace,647 .trim_whitespace = options.trim_whitespace,
641 };648 };
642 run.captured_stderr = captured;649 run.captured_stderr = captured;
643 return .{ .generated = .{ .file = &captured.output.generated_file } };650 return .{ .generated = .{ .index = captured.output.generated_file } };
644}651}
645652
646pub fn captureStdOut(run: *Run, options: CapturedStdIo.Options) std.Build.LazyPath {653pub fn captureStdOut(run: *Run, options: CapturedStdIo.Options) std.Build.LazyPath {
...@@ -648,20 +655,22 @@ pub fn captureStdOut(run: *Run, options: CapturedStdIo.Options) std.Build.LazyPa...@@ -648,20 +655,22 @@ pub fn captureStdOut(run: *Run, options: CapturedStdIo.Options) std.Build.LazyPa
648 assert(run.stdio != .zig_test);655 assert(run.stdio != .zig_test);
649656
650 const b = run.step.owner;657 const b = run.step.owner;
658 const graph = b.graph;
659 const arena = graph.arena;
651660
652 if (run.captured_stdout) |captured| return .{ .generated = .{ .file = &captured.output.generated_file } };661 if (run.captured_stdout) |captured| return .{ .generated = .{ .index = captured.output.generated_file } };
653662
654 const captured = b.allocator.create(CapturedStdIo) catch @panic("OOM");663 const captured = arena.create(CapturedStdIo) catch @panic("OOM");
655 captured.* = .{664 captured.* = .{
656 .output = .{665 .output = .{
657 .prefix = "",666 .prefix = "",
658 .basename = if (options.basename) |basename| b.dupe(basename) else "stdout",667 .basename = if (options.basename) |basename| b.dupe(basename) else "stdout",
659 .generated_file = .{ .step = &run.step },668 .generated_file = graph.addGeneratedFile(&run.step),
660 },669 },
661 .trim_whitespace = options.trim_whitespace,670 .trim_whitespace = options.trim_whitespace,
662 };671 };
663 run.captured_stdout = captured;672 run.captured_stdout = captured;
664 return .{ .generated = .{ .file = &captured.output.generated_file } };673 return .{ .generated = .{ .index = captured.output.generated_file } };
665}674}
666675
667/// Adds an additional input files that, when modified, indicates that this Run676/// Adds an additional input files that, when modified, indicates that this Run
lib/std/Build/Step/TranslateC.zig+11-8
...@@ -1,10 +1,11 @@...@@ -1,10 +1,11 @@
1const TranslateC = @This();
2
1const std = @import("std");3const std = @import("std");
2const Step = std.Build.Step;4const Step = std.Build.Step;
3const LazyPath = std.Build.LazyPath;5const LazyPath = std.Build.LazyPath;
4const fs = std.fs;6const fs = std.fs;
5const mem = std.mem;7const mem = std.mem;
68const Configuration = std.Build.Configuration;
7const TranslateC = @This();
89
9pub const base_tag: Step.Tag = .translate_c;10pub const base_tag: Step.Tag = .translate_c;
1011
...@@ -16,7 +17,7 @@ c_macros: std.array_list.Managed([]const u8),...@@ -16,7 +17,7 @@ c_macros: std.array_list.Managed([]const u8),
16out_basename: []const u8,17out_basename: []const u8,
17target: std.Build.ResolvedTarget,18target: std.Build.ResolvedTarget,
18optimize: std.builtin.OptimizeMode,19optimize: std.builtin.OptimizeMode,
19output_file: std.Build.GeneratedFile,20output_file: Configuration.GeneratedFileIndex,
20link_libc: bool,21link_libc: bool,
2122
22pub const Options = struct {23pub const Options = struct {
...@@ -27,7 +28,9 @@ pub const Options = struct {...@@ -27,7 +28,9 @@ pub const Options = struct {
27};28};
2829
29pub fn create(owner: *std.Build, options: Options) *TranslateC {30pub fn create(owner: *std.Build, options: Options) *TranslateC {
30 const translate_c = owner.allocator.create(TranslateC) catch @panic("OOM");31 const graph = owner.graph;
32 const arena = graph.arena;
33 const translate_c = arena.create(TranslateC) catch @panic("OOM");
31 const source = options.root_source_file.dupe(owner);34 const source = options.root_source_file.dupe(owner);
32 translate_c.* = .{35 translate_c.* = .{
33 .step = Step.init(.{36 .step = Step.init(.{
...@@ -37,12 +40,12 @@ pub fn create(owner: *std.Build, options: Options) *TranslateC {...@@ -37,12 +40,12 @@ pub fn create(owner: *std.Build, options: Options) *TranslateC {
37 .makeFn = make,40 .makeFn = make,
38 }),41 }),
39 .source = source,42 .source = source,
40 .include_dirs = std.array_list.Managed(std.Build.Module.IncludeDir).init(owner.allocator),43 .include_dirs = std.array_list.Managed(std.Build.Module.IncludeDir).init(arena),
41 .c_macros = std.array_list.Managed([]const u8).init(owner.allocator),44 .c_macros = std.array_list.Managed([]const u8).init(arena),
42 .out_basename = undefined,45 .out_basename = undefined,
43 .target = options.target,46 .target = options.target,
44 .optimize = options.optimize,47 .optimize = options.optimize,
45 .output_file = .{ .step = &translate_c.step },48 .output_file = graph.addGeneratedFile(&translate_c.step),
46 .link_libc = options.link_libc,49 .link_libc = options.link_libc,
47 .system_libs = .empty,50 .system_libs = .empty,
48 };51 };
...@@ -59,7 +62,7 @@ pub const AddExecutableOptions = struct {...@@ -59,7 +62,7 @@ pub const AddExecutableOptions = struct {
59};62};
6063
61pub fn getOutput(translate_c: *TranslateC) std.Build.LazyPath {64pub fn getOutput(translate_c: *TranslateC) std.Build.LazyPath {
62 return .{ .generated = .{ .file = &translate_c.output_file } };65 return .{ .generated = .{ .index = translate_c.output_file } };
63}66}
6467
65/// Creates a module from the translated source and adds it to the package's68/// Creates a module from the translated source and adds it to the package's
lib/std/Build/Step/WriteFile.zig+10-8
...@@ -9,13 +9,13 @@ const Dir = std.Io.Dir;...@@ -9,13 +9,13 @@ const Dir = std.Io.Dir;
9const Step = std.Build.Step;9const Step = std.Build.Step;
10const ArrayList = std.ArrayList;10const ArrayList = std.ArrayList;
11const assert = std.debug.assert;11const assert = std.debug.assert;
12const Configuration = std.Build.Configuration;
1213
13step: Step,14step: Step,
1415
15/// The elements here are pointers because we need stable pointers for the GeneratedFile field.
16files: std.ArrayList(File),16files: std.ArrayList(File),
17directories: std.ArrayList(Directory),17directories: std.ArrayList(Directory),
18generated_directory: std.Build.GeneratedFile,18generated_directory: Configuration.GeneratedFileIndex,
19mode: Mode = .whole_cached,19mode: Mode = .whole_cached,
2020
21pub const base_tag: Step.Tag = .write_file;21pub const base_tag: Step.Tag = .write_file;
...@@ -86,7 +86,9 @@ pub const Contents = union(enum) {...@@ -86,7 +86,9 @@ pub const Contents = union(enum) {
86};86};
8787
88pub fn create(owner: *std.Build) *WriteFile {88pub fn create(owner: *std.Build) *WriteFile {
89 const write_file = owner.allocator.create(WriteFile) catch @panic("OOM");89 const graph = owner.graph;
90 const arena = graph.arena;
91 const write_file = arena.create(WriteFile) catch @panic("OOM");
90 write_file.* = .{92 write_file.* = .{
91 .step = Step.init(.{93 .step = Step.init(.{
92 .tag = base_tag,94 .tag = base_tag,
...@@ -95,7 +97,7 @@ pub fn create(owner: *std.Build) *WriteFile {...@@ -95,7 +97,7 @@ pub fn create(owner: *std.Build) *WriteFile {
95 }),97 }),
96 .files = .empty,98 .files = .empty,
97 .directories = .empty,99 .directories = .empty,
98 .generated_directory = .{ .step = &write_file.step },100 .generated_directory = graph.addGeneratedFile(&write_file.step),
99 };101 };
100 return write_file;102 return write_file;
101}103}
...@@ -111,7 +113,7 @@ pub fn add(write_file: *WriteFile, sub_path: []const u8, bytes: []const u8) std....@@ -111,7 +113,7 @@ pub fn add(write_file: *WriteFile, sub_path: []const u8, bytes: []const u8) std.
111 write_file.maybeUpdateName();113 write_file.maybeUpdateName();
112 return .{114 return .{
113 .generated = .{115 .generated = .{
114 .file = &write_file.generated_directory,116 .index = write_file.generated_directory,
115 .sub_path = file.sub_path,117 .sub_path = file.sub_path,
116 },118 },
117 };119 };
...@@ -137,7 +139,7 @@ pub fn addCopyFile(write_file: *WriteFile, source: std.Build.LazyPath, sub_path:...@@ -137,7 +139,7 @@ pub fn addCopyFile(write_file: *WriteFile, source: std.Build.LazyPath, sub_path:
137 source.addStepDependencies(&write_file.step);139 source.addStepDependencies(&write_file.step);
138 return .{140 return .{
139 .generated = .{141 .generated = .{
140 .file = &write_file.generated_directory,142 .index = write_file.generated_directory,
141 .sub_path = file.sub_path,143 .sub_path = file.sub_path,
142 },144 },
143 };145 };
...@@ -165,7 +167,7 @@ pub fn addCopyDirectory(...@@ -165,7 +167,7 @@ pub fn addCopyDirectory(
165 source.addStepDependencies(&write_file.step);167 source.addStepDependencies(&write_file.step);
166 return .{168 return .{
167 .generated = .{169 .generated = .{
168 .file = &write_file.generated_directory,170 .index = write_file.generated_directory,
169 .sub_path = dir.sub_path,171 .sub_path = dir.sub_path,
170 },172 },
171 };173 };
...@@ -174,7 +176,7 @@ pub fn addCopyDirectory(...@@ -174,7 +176,7 @@ pub fn addCopyDirectory(
174/// Returns a `LazyPath` representing the base directory that contains all the176/// Returns a `LazyPath` representing the base directory that contains all the
175/// files from this `WriteFile`.177/// files from this `WriteFile`.
176pub fn getDirectory(write_file: *WriteFile) std.Build.LazyPath {178pub fn getDirectory(write_file: *WriteFile) std.Build.LazyPath {
177 return .{ .generated = .{ .file = &write_file.generated_directory } };179 return .{ .generated = .{ .index = write_file.generated_directory } };
178}180}
179181
180fn maybeUpdateName(write_file: *WriteFile) void {182fn maybeUpdateName(write_file: *WriteFile) void {
lib/std/zig/Configuration.zig+201-67
...@@ -15,6 +15,7 @@ system_integrations: []SystemIntegration,...@@ -15,6 +15,7 @@ system_integrations: []SystemIntegration,
15available_options: []AvailableOption,15available_options: []AvailableOption,
16extra: []u32,16extra: []u32,
17default_step: Step.Index,17default_step: Step.Index,
18generated_files_len: u32,
1819
19/// The field order here matches `Configuration` which documents the order in20/// The field order here matches `Configuration` which documents the order in
20/// the serialized format.21/// the serialized format.
...@@ -28,6 +29,9 @@ pub const Header = extern struct {...@@ -28,6 +29,9 @@ pub const Header = extern struct {
28 extra_len: u32,29 extra_len: u32,
2930
30 default_step: Step.Index,31 default_step: Step.Index,
32 /// There is not actually any data stored for this - it just provides a way
33 /// for maker process to preallocate an array for these.
34 generated_files_len: u32,
31};35};
3236
33pub const Wip = struct {37pub const Wip = struct {
...@@ -44,6 +48,7 @@ pub const Wip = struct {...@@ -44,6 +48,7 @@ pub const Wip = struct {
44 steps: std.ArrayList(Step) = .empty,48 steps: std.ArrayList(Step) = .empty,
45 path_deps: std.MultiArrayList(Path) = .empty,49 path_deps: std.MultiArrayList(Path) = .empty,
46 extra: std.ArrayList(u32) = .empty,50 extra: std.ArrayList(u32) = .empty,
51 next_generated_file_index: u32 = 0,
4752
48 const DedupeTable = std.HashMapUnmanaged(ExtraSlice, void, ExtraSlice.Context, std.hash_map.default_max_load_percentage);53 const DedupeTable = std.HashMapUnmanaged(ExtraSlice, void, ExtraSlice.Context, std.hash_map.default_max_load_percentage);
49 const TargetsTable = std.HashMapUnmanaged(TargetQuery.Index, void, TargetsTableContext, std.hash_map.default_max_load_percentage);54 const TargetsTable = std.HashMapUnmanaged(TargetQuery.Index, void, TargetsTableContext, std.hash_map.default_max_load_percentage);
...@@ -127,6 +132,7 @@ pub const Wip = struct {...@@ -127,6 +132,7 @@ pub const Wip = struct {
127132
128 pub const Static = struct {133 pub const Static = struct {
129 default_step: Step.Index,134 default_step: Step.Index,
135 generated_files_len: u32,
130 };136 };
131137
132 pub fn write(wip: *Wip, w: *Io.Writer, static: Static) Io.Writer.Error!void {138 pub fn write(wip: *Wip, w: *Io.Writer, static: Static) Io.Writer.Error!void {
...@@ -140,6 +146,7 @@ pub const Wip = struct {...@@ -140,6 +146,7 @@ pub const Wip = struct {
140 .extra_len = @intCast(wip.extra.items.len),146 .extra_len = @intCast(wip.extra.items.len),
141147
142 .default_step = static.default_step,148 .default_step = static.default_step,
149 .generated_files_len = static.generated_files_len,
143 };150 };
144 var buffers = [_][]const u8{151 var buffers = [_][]const u8{
145 @ptrCast(&header),152 @ptrCast(&header),
...@@ -363,6 +370,11 @@ pub const Wip = struct {...@@ -363,6 +370,11 @@ pub const Wip = struct {
363 const string = optional_string orelse return;370 const string = optional_string orelse return;
364 wip.extra.appendAssumeCapacity(@intFromEnum(string));371 wip.extra.appendAssumeCapacity(@intFromEnum(string));
365 }372 }
373
374 pub fn addGeneratedFile(wip: *Wip) GeneratedFileIndex {
375 defer wip.next_generated_file_index += 1;
376 return @enumFromInt(wip.next_generated_file_index);
377 }
366};378};
367379
368pub const SystemIntegration = extern struct {380pub const SystemIntegration = extern struct {
...@@ -471,16 +483,16 @@ pub const Step = extern struct {...@@ -471,16 +483,16 @@ pub const Step = extern struct {
471483
472 dest_dir: InstallDestDir,484 dest_dir: InstallDestDir,
473 dest_sub_path: String,485 dest_sub_path: String,
474 emitted_bin: OptionalLazyPath,486 emitted_bin: LazyPath.OptionalIndex,
475487
476 implib_dir: InstallDestDir,488 implib_dir: InstallDestDir,
477 emitted_implib: OptionalLazyPath,489 emitted_implib: LazyPath.OptionalIndex,
478490
479 pdb_dir: InstallDestDir,491 pdb_dir: InstallDestDir,
480 emitted_pdb: OptionalLazyPath,492 emitted_pdb: LazyPath.OptionalIndex,
481493
482 h_dir: InstallDestDir,494 h_dir: InstallDestDir,
483 emitted_h: OptionalLazyPath,495 emitted_h: LazyPath.OptionalIndex,
484496
485 /// Always a compile step.497 /// Always a compile step.
486 artifact: Step.Index,498 artifact: Step.Index,
...@@ -493,11 +505,11 @@ pub const Step = extern struct {...@@ -493,11 +505,11 @@ pub const Step = extern struct {
493 };505 };
494506
495 /// Trailing:507 /// Trailing:
496 /// * LazyPath for each file_inputs_len508 /// * LazyPath.Index for each file_inputs_len
497 /// * Arg for each args_len509 /// * Arg for each args_len
498 /// * environ_map if corresponding flag is set510 /// * environ_map if corresponding flag is set
499 /// * stdin: Bytes, // if StdIn.bytes is chosen511 /// * stdin: Bytes, // if StdIn.bytes is chosen
500 /// * stdin: LazyPath, // if StdIn.lazy_path is chosen512 /// * stdin: LazyPath.Index, // if StdIn.lazy_path is chosen
501 /// * checks: Checks, // if StdIo.check is chosen513 /// * checks: Checks, // if StdIo.check is chosen
502 /// * stdio_limit: u64, // if stdio_limit is set514 /// * stdio_limit: u64, // if stdio_limit is set
503 /// * producer: Step.Index, // if producer is set. always compile step515 /// * producer: Step.Index, // if producer is set. always compile step
...@@ -505,7 +517,7 @@ pub const Step = extern struct {...@@ -505,7 +517,7 @@ pub const Step = extern struct {
505 flags: @This().Flags,517 flags: @This().Flags,
506 file_inputs_len: u32,518 file_inputs_len: u32,
507 args_len: u32,519 args_len: u32,
508 cwd: OptionalLazyPath,520 cwd: LazyPath.OptionalIndex,
509 captured_stdout: OptionalString, // basename521 captured_stdout: OptionalString, // basename
510 captured_stderr: OptionalString, // basename522 captured_stderr: OptionalString, // basename
511523
...@@ -514,7 +526,7 @@ pub const Step = extern struct {...@@ -514,7 +526,7 @@ pub const Step = extern struct {
514 /// * String if suffix set526 /// * String if suffix set
515 /// * String if basename set527 /// * String if basename set
516 /// * Step.Index which is always a compile step if tag is artifact528 /// * Step.Index which is always a compile step if tag is artifact
517 /// * LazyPath if tag is path_file, path_directory, or file_content529 /// * LazyPath.Index if tag is path_file, path_directory, or file_content
518 pub const Arg = struct {530 pub const Arg = struct {
519 flags: Arg.Flags,531 flags: Arg.Flags,
520532
...@@ -591,13 +603,13 @@ pub const Step = extern struct {...@@ -591,13 +603,13 @@ pub const Step = extern struct {
591 installed_headers: Storage.FlagLengthPrefixedList(.flags, .installed_headers_len, Storage.Extended(InstalledHeader.Flags, InstalledHeader)),603 installed_headers: Storage.FlagLengthPrefixedList(.flags, .installed_headers_len, Storage.Extended(InstalledHeader.Flags, InstalledHeader)),
592 force_undefined_symbols: Storage.FlagLengthPrefixedList(.flags, .force_undefined_symbols_len, String),604 force_undefined_symbols: Storage.FlagLengthPrefixedList(.flags, .force_undefined_symbols_len, String),
593 expect_errors: Storage.FlagUnion(.flags4, .expect_errors, ExpectErrors),605 expect_errors: Storage.FlagUnion(.flags4, .expect_errors, ExpectErrors),
594 linker_script: Storage.FlagOptional(.flags4, .linker_script, LazyPath),606 linker_script: Storage.FlagOptional(.flags4, .linker_script, LazyPath.Index),
595 version_script: Storage.FlagOptional(.flags4, .version_script, LazyPath),607 version_script: Storage.FlagOptional(.flags4, .version_script, LazyPath.Index),
596 zig_lib_dir: Storage.FlagOptional(.flags3, .zig_lib_dir, LazyPath),608 zig_lib_dir: Storage.FlagOptional(.flags3, .zig_lib_dir, LazyPath.Index),
597 libc_file: Storage.FlagOptional(.flags4, .libc_file, LazyPath),609 libc_file: Storage.FlagOptional(.flags4, .libc_file, LazyPath.Index),
598 win32_manifest: Storage.FlagOptional(.flags3, .win32_manifest, LazyPath),610 win32_manifest: Storage.FlagOptional(.flags3, .win32_manifest, LazyPath.Index),
599 win32_module_definition: Storage.FlagOptional(.flags3, .win32_module_definition, LazyPath),611 win32_module_definition: Storage.FlagOptional(.flags3, .win32_module_definition, LazyPath.Index),
600 entitlements: Storage.FlagOptional(.flags4, .entitlements, LazyPath),612 entitlements: Storage.FlagOptional(.flags4, .entitlements, LazyPath.Index),
601 version: Storage.FlagOptional(.flags3, .version, String), // semantic version string613 version: Storage.FlagOptional(.flags3, .version, String), // semantic version string
602 entry: Storage.EnumOptional(.flags3, .entry, .symbol_name, String),614 entry: Storage.EnumOptional(.flags3, .entry, .symbol_name, String),
603 install_name: Storage.FlagOptional(.flags4, .install_name, String),615 install_name: Storage.FlagOptional(.flags4, .install_name, String),
...@@ -614,6 +626,16 @@ pub const Step = extern struct {...@@ -614,6 +626,16 @@ pub const Step = extern struct {
614 build_id: Storage.EnumOptional(.flags3, .build_id, .hexstring, String),626 build_id: Storage.EnumOptional(.flags3, .build_id, .hexstring, String),
615 test_runner: Storage.FlagUnion(.flags3, .test_runner, TestRunner),627 test_runner: Storage.FlagUnion(.flags3, .test_runner, TestRunner),
616628
629 emit_directory: Storage.FlagOptional(.flags4, .emit_directory, GeneratedFileIndex),
630 generated_docs: Storage.FlagOptional(.flags4, .generated_docs, GeneratedFileIndex),
631 generated_asm: Storage.FlagOptional(.flags4, .generated_asm, GeneratedFileIndex),
632 generated_bin: Storage.FlagOptional(.flags4, .generated_bin, GeneratedFileIndex),
633 generated_pdb: Storage.FlagOptional(.flags4, .generated_pdb, GeneratedFileIndex),
634 generated_implib: Storage.FlagOptional(.flags4, .generated_implib, GeneratedFileIndex),
635 generated_llvm_bc: Storage.FlagOptional(.flags4, .generated_llvm_bc, GeneratedFileIndex),
636 generated_llvm_ir: Storage.FlagOptional(.flags4, .generated_llvm_ir, GeneratedFileIndex),
637 generated_h: Storage.FlagOptional(.flags4, .generated_h, GeneratedFileIndex),
638
617 pub const InstalledHeader = union(@This().Tag) {639 pub const InstalledHeader = union(@This().Tag) {
618 file: File,640 file: File,
619 directory: Directory,641 directory: Directory,
...@@ -630,7 +652,7 @@ pub const Step = extern struct {...@@ -630,7 +652,7 @@ pub const Step = extern struct {
630652
631 pub const File = struct {653 pub const File = struct {
632 flags: @This().Flags = .{},654 flags: @This().Flags = .{},
633 source: LazyPath,655 source: LazyPath.Index,
634 dest_sub_path: String,656 dest_sub_path: String,
635657
636 pub const Flags = packed struct(u32) {658 pub const Flags = packed struct(u32) {
...@@ -641,7 +663,7 @@ pub const Step = extern struct {...@@ -641,7 +663,7 @@ pub const Step = extern struct {
641663
642 pub const Directory = struct {664 pub const Directory = struct {
643 flags: @This().Flags,665 flags: @This().Flags,
644 source: LazyPath,666 source: LazyPath.Index,
645 dest_sub_path: String,667 dest_sub_path: String,
646 exclude_extensions: Storage.FlagLengthPrefixedList(.flags, .exclude_extensions, String),668 exclude_extensions: Storage.FlagLengthPrefixedList(.flags, .exclude_extensions, String),
647 include_extensions: Storage.FlagLengthPrefixedList(.flags, .include_extensions, String),669 include_extensions: Storage.FlagLengthPrefixedList(.flags, .include_extensions, String),
...@@ -667,8 +689,8 @@ pub const Step = extern struct {...@@ -667,8 +689,8 @@ pub const Step = extern struct {
667 pub const Tag = enum(u2) { default, simple, server };689 pub const Tag = enum(u2) { default, simple, server };
668690
669 default: void,691 default: void,
670 simple: LazyPath,692 simple: LazyPath.Index,
671 server: LazyPath,693 server: LazyPath.Index,
672 };694 };
673 pub const Entry = enum(u2) { default, disabled, enabled, symbol_name };695 pub const Entry = enum(u2) { default, disabled, enabled, symbol_name };
674696
...@@ -857,12 +879,37 @@ pub const Step = extern struct {...@@ -857,12 +879,37 @@ pub const Step = extern struct {
857 expect_errors: ExpectErrors.Tag,879 expect_errors: ExpectErrors.Tag,
858 linker_script: bool,880 linker_script: bool,
859 version_script: bool,881 version_script: bool,
860 _: u18 = 0,882 emit_directory: bool,
883 generated_docs: bool,
884 generated_asm: bool,
885 generated_bin: bool,
886 generated_pdb: bool,
887 generated_implib: bool,
888 generated_llvm_bc: bool,
889 generated_llvm_ir: bool,
890 generated_h: bool,
891 _: u9 = 0,
861 };892 };
862893
863 pub fn isDynamicLibrary(compile: *const Compile) bool {894 pub fn isDynamicLibrary(compile: *const Compile) bool {
864 return compile.flags3.kind == .lib and compile.flags2.linkage == .dynamic;895 return compile.flags3.kind == .lib and compile.flags2.linkage == .dynamic;
865 }896 }
897
898 pub fn isStaticLibrary(compile: *const Compile) bool {
899 return compile.flags3.kind == .lib and compile.flags2.linkage != .dynamic;
900 }
901
902 pub fn producesImplib(compile: *const Compile, c: *const Configuration) bool {
903 return isDll(compile, c);
904 }
905
906 pub fn isDll(compile: *const Compile, c: *const Configuration) bool {
907 return isDynamicLibrary(compile) and rootModuleTarget(compile, c).flags.os_tag == .windows;
908 }
909
910 pub fn rootModuleTarget(compile: *const Compile, c: *const Configuration) TargetQuery {
911 return compile.root_module.get(c).resolved_target.get(c).?.result.get(c);
912 }
866 };913 };
867914
868 pub const CheckFile = struct {915 pub const CheckFile = struct {
...@@ -1001,32 +1048,49 @@ pub const MaxRss = enum(u32) {...@@ -1001,32 +1048,49 @@ pub const MaxRss = enum(u32) {
1001 }1048 }
1002};1049};
10031050
1004/// An index into `extra`, or `null`.1051pub const LazyPath = union(@This().Tag) {
1005pub const OptionalLazyPath = enum(u32) {1052 source_path: SourcePath,
1006 none = maxInt(u32),1053 relative: Relative,
1007 _,1054 generated: Generated,
1008
1009 pub fn unwrap(this: @This()) ?LazyPath {
1010 return switch (this) {
1011 .none => null,
1012 else => @enumFromInt(@intFromEnum(this)),
1013 };
1014 }
1015};
1016
1017/// An index into `extra`.
1018pub const LazyPath = enum(u32) {
1019 _,
10201055
1021 pub const Tag = enum(u8) {1056 pub const Tag = enum(u8) {
1022 /// A source file path relative to build root.1057 /// A source file path relative to build root.
1023 source_path,1058 source_path,
1024 generated,1059 /// Relative to the directory indicated in flags.
1025 relative,1060 relative,
1061 /// Path is available only after it is populated by its owning step.
1062 generated,
1063 };
1064
1065 pub const Flags = packed struct(u32) {
1066 tag: Tag,
1067 _: u24 = 0,
1068 };
1069
1070 /// An index into `extra`.
1071 pub const Index = enum(u32) {
1072 _,
1073
1074 pub fn get(this: @This(), c: *const Configuration) LazyPath {
1075 return extraData(c, LazyPath, @intFromEnum(this));
1076 }
1077 };
1078
1079 /// An index into `extra`, or `null`.
1080 pub const OptionalIndex = enum(u32) {
1081 none = maxInt(u32),
1082 _,
1083
1084 pub fn unwrap(this: @This()) ?Index {
1085 return switch (this) {
1086 .none => null,
1087 else => @enumFromInt(@intFromEnum(this)),
1088 };
1089 }
1026 };1090 };
10271091
1028 pub const SourcePath = struct {1092 pub const SourcePath = struct {
1029 flags: Flags,1093 flags: @This().Flags,
1030 owner: Package.Index,1094 owner: Package.Index,
1031 sub_path: String,1095 sub_path: String,
10321096
...@@ -1037,9 +1101,10 @@ pub const LazyPath = enum(u32) {...@@ -1037,9 +1101,10 @@ pub const LazyPath = enum(u32) {
1037 };1101 };
10381102
1039 pub const Generated = struct {1103 pub const Generated = struct {
1040 flags: Flags,1104 flags: @This().Flags = .{},
1105 index: GeneratedFileIndex,
1041 /// Applied after `up`.1106 /// Applied after `up`.
1042 sub_path: String,1107 sub_path: String = .empty,
10431108
1044 pub const Flags = packed struct(u32) {1109 pub const Flags = packed struct(u32) {
1045 tag: Tag = .generated,1110 tag: Tag = .generated,
...@@ -1047,12 +1112,12 @@ pub const LazyPath = enum(u32) {...@@ -1047,12 +1112,12 @@ pub const LazyPath = enum(u32) {
1047 /// 0 means the generated file itself.1112 /// 0 means the generated file itself.
1048 /// 1 means the directory of the generated file.1113 /// 1 means the directory of the generated file.
1049 /// 2 means the parent of that directory, and so on.1114 /// 2 means the parent of that directory, and so on.
1050 up: u24,1115 up: u24 = 0,
1051 };1116 };
1052 };1117 };
10531118
1054 pub const Relative = struct {1119 pub const Relative = struct {
1055 flags: Flags,1120 flags: @This().Flags,
1056 sub_path: String,1121 sub_path: String,
10571122
1058 pub const Flags = packed struct(u32) {1123 pub const Flags = packed struct(u32) {
...@@ -1063,6 +1128,26 @@ pub const LazyPath = enum(u32) {...@@ -1063,6 +1128,26 @@ pub const LazyPath = enum(u32) {
1063 };1128 };
1064};1129};
10651130
1131pub const GeneratedFileIndex = enum(u32) {
1132 _,
1133};
1134
1135pub const OptionalGeneratedFileIndex = enum(u32) {
1136 none = maxInt(u32),
1137 _,
1138
1139 pub fn init(i: ?GeneratedFileIndex) OptionalGeneratedFileIndex {
1140 return @enumFromInt(@intFromEnum(i orelse return .none));
1141 }
1142
1143 pub fn unwrap(this: @This()) ?GeneratedFileIndex {
1144 return switch (this) {
1145 .none => null,
1146 else => @enumFromInt(@intFromEnum(this)),
1147 };
1148 }
1149};
1150
1066pub const Package = struct {1151pub const Package = struct {
1067 dep_prefix: String,1152 dep_prefix: String,
1068 hash: String,1153 hash: String,
...@@ -1071,9 +1156,15 @@ pub const Package = struct {...@@ -1071,9 +1156,15 @@ pub const Package = struct {
1071 root = maxInt(u32),1156 root = maxInt(u32),
1072 _,1157 _,
10731158
1074 pub fn depPrefixSlice(i: Index, c: *const Configuration) [:0]const u8 {1159 /// Returns `null` for root package.
1075 if (i == .root) return "";1160 pub fn get(i: @This(), c: *const Configuration) ?Package {
1076 return extraData(c, Package, @intFromEnum(i)).dep_prefix.slice(c);1161 if (i == .root) return null;
1162 return extraData(c, Package, @intFromEnum(i));
1163 }
1164
1165 pub fn depPrefixSlice(i: @This(), c: *const Configuration) [:0]const u8 {
1166 const package = get(i, c) orelse return "";
1167 return package.dep_prefix.slice(c);
1077 }1168 }
1078 };1169 };
1079};1170};
...@@ -1083,10 +1174,10 @@ pub const Module = struct {...@@ -1083,10 +1174,10 @@ pub const Module = struct {
1083 flags2: Flags2,1174 flags2: Flags2,
1084 import_table: ImportTable.Index,1175 import_table: ImportTable.Index,
1085 owner: Package.Index,1176 owner: Package.Index,
1086 root_source_file: OptionalLazyPath,1177 root_source_file: LazyPath.OptionalIndex,
1087 resolved_target: ResolvedTarget.OptionalIndex,1178 resolved_target: ResolvedTarget.OptionalIndex,
1088 c_macros: Storage.FlagLengthPrefixedList(.flags, .c_macros, String),1179 c_macros: Storage.FlagLengthPrefixedList(.flags, .c_macros, String),
1089 lib_paths: Storage.FlagLengthPrefixedList(.flags, .lib_paths, LazyPath),1180 lib_paths: Storage.FlagLengthPrefixedList(.flags, .lib_paths, LazyPath.Index),
1090 export_symbol_names: Storage.FlagLengthPrefixedList(.flags, .export_symbol_names, String),1181 export_symbol_names: Storage.FlagLengthPrefixedList(.flags, .export_symbol_names, String),
1091 include_dirs: Storage.UnionList(.flags, .include_dirs, IncludeDir),1182 include_dirs: Storage.UnionList(.flags, .include_dirs, IncludeDir),
1092 rpaths: Storage.UnionList(.flags, .rpaths, RPath),1183 rpaths: Storage.UnionList(.flags, .rpaths, RPath),
...@@ -1195,29 +1286,29 @@ pub const Module = struct {...@@ -1195,29 +1286,29 @@ pub const Module = struct {
1195 };1286 };
11961287
1197 pub const IncludeDir = union(enum(u3)) {1288 pub const IncludeDir = union(enum(u3)) {
1198 path: LazyPath,1289 path: LazyPath.Index,
1199 path_system: LazyPath,1290 path_system: LazyPath.Index,
1200 path_after: LazyPath,1291 path_after: LazyPath.Index,
1201 framework_path: LazyPath,1292 framework_path: LazyPath.Index,
1202 framework_path_system: LazyPath,1293 framework_path_system: LazyPath.Index,
1203 /// Always `Step.Tag.compile`.1294 /// Always `Step.Tag.compile`.
1204 other_step: Step.Index,1295 other_step: Step.Index,
1205 /// Always `Step.Tag.config_header`.1296 /// Always `Step.Tag.config_header`.
1206 config_header_step: Step.Index,1297 config_header_step: Step.Index,
1207 embed_path: LazyPath,1298 embed_path: LazyPath.Index,
1208 };1299 };
12091300
1210 pub const RPath = union(enum(u1)) {1301 pub const RPath = union(enum(u1)) {
1211 lazy_path: LazyPath,1302 lazy_path: LazyPath.Index,
1212 special: String,1303 special: String,
1213 };1304 };
12141305
1215 pub const LinkObject = union(enum(u3)) {1306 pub const LinkObject = union(enum(u3)) {
1216 static_path: LazyPath,1307 static_path: LazyPath.Index,
1217 /// Always `Step.Tag.compile`.1308 /// Always `Step.Tag.compile`.
1218 other_step: Step.Index,1309 other_step: Step.Index,
1219 system_lib: SystemLib.Index,1310 system_lib: SystemLib.Index,
1220 assembly_file: LazyPath,1311 assembly_file: LazyPath.Index,
1221 c_source_file: CSourceFile.Index,1312 c_source_file: CSourceFile.Index,
1222 c_source_files: CSourceFiles.Index,1313 c_source_files: CSourceFiles.Index,
1223 win32_resource_file: RcSourceFile.Index,1314 win32_resource_file: RcSourceFile.Index,
...@@ -1376,6 +1467,10 @@ pub const SystemLib = struct {...@@ -1376,6 +1467,10 @@ pub const SystemLib = struct {
13761467
1377 pub const Index = enum(u32) {1468 pub const Index = enum(u32) {
1378 _,1469 _,
1470
1471 pub fn get(this: @This(), c: *const Configuration) SystemLib {
1472 return extraData(c, SystemLib, @intFromEnum(this));
1473 }
1379 };1474 };
13801475
1381 pub const UsePkgConfig = enum(u2) {1476 pub const UsePkgConfig = enum(u2) {
...@@ -1405,12 +1500,16 @@ pub const SystemLib = struct {...@@ -1405,12 +1500,16 @@ pub const SystemLib = struct {
14051500
1406pub const CSourceFiles = struct {1501pub const CSourceFiles = struct {
1407 flags: Flags,1502 flags: Flags,
1408 root: LazyPath,1503 root: LazyPath.Index,
1409 args: Storage.FlagList(.flags, .args_len, String),1504 args: Storage.FlagList(.flags, .args_len, String),
1410 sub_paths: Storage.LengthPrefixedList(String),1505 sub_paths: Storage.LengthPrefixedList(String),
14111506
1412 pub const Index = enum(u32) {1507 pub const Index = enum(u32) {
1413 _,1508 _,
1509
1510 pub fn get(this: @This(), c: *const Configuration) CSourceFiles {
1511 return extraData(c, CSourceFiles, @intFromEnum(this));
1512 }
1414 };1513 };
14151514
1416 pub const Flags = packed struct(u32) {1515 pub const Flags = packed struct(u32) {
...@@ -1422,11 +1521,15 @@ pub const CSourceFiles = struct {...@@ -1422,11 +1521,15 @@ pub const CSourceFiles = struct {
14221521
1423pub const CSourceFile = struct {1522pub const CSourceFile = struct {
1424 flags: Flags,1523 flags: Flags,
1425 file: LazyPath,1524 file: LazyPath.Index,
1426 args: Storage.FlagList(.flags, .args_len, String),1525 args: Storage.FlagList(.flags, .args_len, String),
14271526
1428 pub const Index = enum(u32) {1527 pub const Index = enum(u32) {
1429 _,1528 _,
1529
1530 pub fn get(this: @This(), c: *const Configuration) CSourceFile {
1531 return extraData(c, CSourceFile, @intFromEnum(this));
1532 }
1430 };1533 };
14311534
1432 pub const Flags = packed struct(u32) {1535 pub const Flags = packed struct(u32) {
...@@ -1438,12 +1541,16 @@ pub const CSourceFile = struct {...@@ -1438,12 +1541,16 @@ pub const CSourceFile = struct {
14381541
1439pub const RcSourceFile = struct {1542pub const RcSourceFile = struct {
1440 flags: Flags,1543 flags: Flags,
1441 file: LazyPath,1544 file: LazyPath.Index,
1442 args: Storage.FlagList(.flags, .args_len, String),1545 args: Storage.FlagList(.flags, .args_len, String),
1443 include_paths: Storage.FlagLengthPrefixedList(.flags, .include_paths, LazyPath),1546 include_paths: Storage.FlagLengthPrefixedList(.flags, .include_paths, LazyPath.Index),
14441547
1445 pub const Index = enum(u32) {1548 pub const Index = enum(u32) {
1446 _,1549 _,
1550
1551 pub fn get(this: @This(), c: *const Configuration) RcSourceFile {
1552 return extraData(c, RcSourceFile, @intFromEnum(this));
1553 }
1447 };1554 };
14481555
1449 pub const Flags = packed struct(u32) {1556 pub const Flags = packed struct(u32) {
...@@ -1472,6 +1579,18 @@ pub const OptionalCSourceLanguage = enum(u3) {...@@ -1472,6 +1579,18 @@ pub const OptionalCSourceLanguage = enum(u3) {
1472 .assembly_with_preprocessor => .assembly_with_preprocessor,1579 .assembly_with_preprocessor => .assembly_with_preprocessor,
1473 };1580 };
1474 }1581 }
1582
1583 pub fn get(this: @This()) ?std.Build.Module.CSourceLanguage {
1584 return switch (this) {
1585 .c => .c,
1586 .cpp => .cpp,
1587 .objective_c => .objective_c,
1588 .objective_cpp => .objective_cpp,
1589 .assembly => .assembly,
1590 .assembly_with_preprocessor => .assembly_with_preprocessor,
1591 .default => null,
1592 };
1593 }
1475};1594};
14761595
1477pub const ResolvedTarget = struct {1596pub const ResolvedTarget = struct {
...@@ -1483,7 +1602,7 @@ pub const ResolvedTarget = struct {...@@ -1483,7 +1602,7 @@ pub const ResolvedTarget = struct {
1483 pub const Index = enum(u32) {1602 pub const Index = enum(u32) {
1484 _,1603 _,
14851604
1486 pub fn get(this: @This(), c: *const Configuration) ?ResolvedTarget {1605 pub fn get(this: @This(), c: *const Configuration) ResolvedTarget {
1487 return extraData(c, ResolvedTarget, @intFromEnum(this));1606 return extraData(c, ResolvedTarget, @intFromEnum(this));
1488 }1607 }
1489 };1608 };
...@@ -2006,13 +2125,27 @@ pub const Storage = enum {...@@ -2006,13 +2125,27 @@ pub const Storage = enum {
2006 return end - i;2125 return end - i;
2007 }2126 }
20082127
2009 pub fn data(buffer: []const u32, i: *usize, comptime S: type) S {2128 pub fn data(buffer: []const u32, i: *usize, comptime T: type) T {
2010 var result: S = undefined;2129 switch (@typeInfo(T)) {
2011 const fields = @typeInfo(S).@"struct".fields;2130 .@"struct" => |info| {
2012 inline for (fields) |field| {2131 var result: T = undefined;
2013 @field(result, field.name) = dataField(buffer, i, &result, field.type);2132 inline for (info.fields) |field| {
2133 @field(result, field.name) = dataField(buffer, i, &result, field.type);
2134 }
2135 return result;
2136 },
2137 .@"union" => |info| {
2138 const flags: T.Flags = @bitCast(buffer[i.*]);
2139 return switch (flags.tag) {
2140 inline else => |comptime_tag| @unionInit(
2141 T,
2142 @tagName(comptime_tag),
2143 data(buffer, i, info.fields[@intFromEnum(comptime_tag)].type),
2144 ),
2145 };
2146 },
2147 else => comptime unreachable,
2014 }2148 }
2015 return result;
2016 }2149 }
20172150
2018 fn dataField(buffer: []const u32, i: *usize, container: anytype, comptime Field: type) Field {2151 fn dataField(buffer: []const u32, i: *usize, container: anytype, comptime Field: type) Field {
...@@ -2332,6 +2465,7 @@ pub fn load(arena: Allocator, reader: *Io.Reader) LoadError!Configuration {...@@ -2332,6 +2465,7 @@ pub fn load(arena: Allocator, reader: *Io.Reader) LoadError!Configuration {
2332 .available_options = try arena.alloc(AvailableOption, header.available_options_len),2465 .available_options = try arena.alloc(AvailableOption, header.available_options_len),
2333 .extra = try arena.alloc(u32, header.extra_len),2466 .extra = try arena.alloc(u32, header.extra_len),
2334 .default_step = header.default_step,2467 .default_step = header.default_step,
2468 .generated_files_len = header.generated_files_len,
2335 };2469 };
2336 var vecs = [_][]u8{2470 var vecs = [_][]u8{
2337 result.string_bytes,2471 result.string_bytes,