authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-02-17 17:08:55-08:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-05-25 18:54:33-07:00
log0505318efe0d2757a344dded9ae1607f948f7511
tree80feb60a23f512c1110aec4d477cfece57d79cef
parent2b11859a1049910a2bd8031e53c24beea305ae10

make runner gets compiled and run

and --print-configuration prints some deserialized stuff

11 files changed, 593 insertions(+), 477 deletions(-)

lib/compiler/configure_runner.zig+48-17
......@@ -1,18 +1,19 @@
11const builtin = @import("builtin");
22
33const std = @import("std");
4const Allocator = std.mem.Allocator;
5const Color = std.zig.Color;
6const Configuration = std.Build.Configuration;
7const File = std.Io.File;
48const Io = std.Io;
9const Step = std.Build.Step;
10const Writer = std.Io.Writer;
511const assert = std.debug.assert;
12const fatal = std.process.fatal;
613const fmt = std.fmt;
14const log = std.log;
715const mem = std.mem;
816const process = std.process;
9const File = std.Io.File;
10const Step = std.Build.Step;
11const Allocator = std.mem.Allocator;
12const fatal = std.process.fatal;
13const Writer = std.Io.Writer;
14const Color = std.zig.Color;
15const Configuration = std.Build.Configuration;
1617
1718pub const root = @import("@build");
1819pub const dependencies = @import("@dependencies");
......@@ -95,7 +96,6 @@ pub fn main(init: process.Init.Minimal) !void {
9596 .query = .{},
9697 .result = try std.zig.system.resolveTargetQuery(io, .{}),
9798 },
98 .time_report = false,
9999 };
100100
101101 graph.cache.addPrefix(.{ .path = null, .handle = cwd });
......@@ -141,9 +141,9 @@ pub fn main(init: process.Init.Minimal) !void {
141141 fatal(" access the help menu with 'zig build -h'", .{});
142142 }
143143 } else if (mem.cutPrefix(u8, arg, "-fsys=")) |name| {
144 graph.system_library_options.put(arena, name, .user_enabled) catch @panic("OOM");
144 try graph.system_integration_options.put(arena, name, .user_enabled);
145145 } else if (mem.cutPrefix(u8, arg, "-fno-sys=")) |name| {
146 graph.system_library_options.put(arena, name, .user_disabled) catch @panic("OOM");
146 try graph.system_integration_options.put(arena, name, .user_disabled);
147147 } else if (mem.eql(u8, arg, "--release")) {
148148 graph.release_mode = .any;
149149 } else if (mem.cutPrefix(u8, arg, "--release=")) |text| {
......@@ -177,8 +177,6 @@ pub fn main(init: process.Init.Minimal) !void {
177177 } else if (mem.cutPrefix(u8, arg, "--build-id=")) |style| {
178178 builder.build_id = std.zig.BuildId.parse(style) catch |err|
179179 fatal("unable to parse --build-id style '{s}': {t}", .{ style, err });
180 } else if (mem.eql(u8, arg, "--debug-rt")) {
181 graph.debug_compiler_runtime_libs = true;
182180 } else if (mem.eql(u8, arg, "--debug-compile-errors")) {
183181 builder.debug_compile_errors = true;
184182 } else if (mem.eql(u8, arg, "--debug-incremental")) {
......@@ -204,10 +202,16 @@ pub fn main(init: process.Init.Minimal) !void {
204202
205203 try builder.runBuild(root);
206204
205 if (builder.validateUserInputDidItFail()) {
206 fatal(" access the help menu with 'zig build -h'", .{});
207 }
208
207209 var wc: Configuration.Wip = .init(gpa);
208210 defer wc.deinit();
209211 assert(try wc.addString("") == .empty);
210212
213 try serializeSystemIntegrationOptions(&graph, &wc);
214
211215 var stdout_buffer: [1024]u8 = undefined;
212216 var file_writer = Io.File.stdout().writerStreaming(io, &stdout_buffer);
213217 serialize(builder, &wc, &file_writer.interface) catch |err| switch (err) {
......@@ -367,7 +371,7 @@ fn serialize(b: *std.Build, wc: *Configuration.Wip, writer: *Io.Writer) !void {
367371 .root_name = try wc.addString(c.name),
368372 }));
369373
370 std.log.err("TODO serialize the trailing Compile step data", .{});
374 log.err("TODO serialize the trailing Compile step data", .{});
371375
372376 break :e extra_index;
373377 },
......@@ -441,7 +445,7 @@ fn serialize(b: *std.Build, wc: *Configuration.Wip, writer: *Io.Writer) !void {
441445 .captured_stderr = captured_stderr,
442446 }));
443447
444 std.log.err("TODO serialize the trailing Run step data", .{});
448 log.err("TODO serialize the trailing Run step data", .{});
445449
446450 break :e extra_index;
447451 },
......@@ -489,7 +493,7 @@ fn addModule(
489493 m.import_table.values(),
490494 @intFromEnum(import_table) + 1 + m.import_table.entries.len..,
491495 ) |dep, extra_index| {
492 // TODO module dependencies can be cyclic
496 log.err("TODO module dependencies can be cyclic", .{});
493497 wc.extra.items[extra_index] = @intFromEnum(try addModule(wc, module_map, dep));
494498 }
495499
......@@ -530,7 +534,7 @@ fn addModule(
530534 .resolved_target = try addOptionalResolvedTarget(wc, m.resolved_target),
531535 })));
532536
533 std.log.err("TODO serialize the trailing Module data", .{});
537 log.err("TODO serialize the trailing Module data", .{});
534538
535539 try module_map.putNoClobber(gpa, m, module_index);
536540
......@@ -542,7 +546,7 @@ fn addOptionalResolvedTarget(
542546 optional_resolved_target: ?std.Build.ResolvedTarget,
543547) !Configuration.ResolvedTarget.OptionalIndex {
544548 const resolved_target = optional_resolved_target orelse return .none;
545 // TODO dedupe
549 log.debug("TODO deduplicate resolved targets", .{});
546550 return @enumFromInt(try wc.addExtra(@as(Configuration.ResolvedTarget, .{
547551 .query = try wc.addTargetQuery(resolved_target.query),
548552 .result = try wc.addTarget(resolved_target.result),
......@@ -698,3 +702,30 @@ const Summary = enum { all, new, failures, line, none };
698702fn fatalWithHint(comptime f: []const u8, args: anytype) noreturn {
699703 fatal(f ++ "\n access the help menu with \"zig build -h\"", args);
700704}
705
706fn serializeSystemIntegrationOptions(graph: *std.Build.Graph, wc: *Configuration.Wip) Allocator.Error!void {
707 const gpa = wc.gpa;
708
709 var bad = false;
710 try wc.system_integrations.ensureTotalCapacityPrecise(gpa, graph.system_integration_options.entries.len);
711 for (graph.system_integration_options.keys(), graph.system_integration_options.values()) |k, v| {
712 wc.system_integrations.appendAssumeCapacity(.{
713 .name = try wc.addString(k),
714 .status = switch (v) {
715 .user_disabled, .user_enabled => x: {
716 // The user tried to enable or disable a system library integration, but
717 // the configure script did not recognize that option.
718 log.err("system integration name not recognized by configure script: {s}", .{k});
719 bad = true;
720 break :x .disabled;
721 },
722 .declared_disabled => .disabled,
723 .declared_enabled => .enabled,
724 },
725 });
726 }
727 if (bad) {
728 log.info("access the help menu with \"zig build -h\"", .{});
729 process.exit(1);
730 }
731}
lib/compiler/maker.zig+345-299
......@@ -1,21 +1,23 @@
11const builtin = @import("builtin");
22
33const std = @import("std");
4const Allocator = std.mem.Allocator;
5const Cache = std.Build.Cache;
6const Configuration = std.Build.Configuration;
7const File = std.Io.File;
48const Io = std.Io;
9const Path = std.Build.Cache.Path;
10const Writer = std.Io.Writer;
511const assert = std.debug.assert;
12const fatal = std.process.fatal;
613const fmt = std.fmt;
14const log = std.log;
715const mem = std.mem;
816const process = std.process;
9const File = std.Io.File;
10const Allocator = std.mem.Allocator;
11const fatal = std.process.fatal;
12const Writer = std.Io.Writer;
13const Cache = std.Build.Cache;
14const Configuration = std.Build.Configuration;
1517
1618const Fuzz = @import("maker/Fuzz.zig");
1719const Graph = @import("maker/Graph.zig");
18const Step = @import("maker/Step.zig");
20const Step = void; // @import("maker/Step.zig");
1921const Watch = @import("maker/Watch.zig");
2022const WebServer = @import("maker/WebServer.zig");
2123
......@@ -48,12 +50,12 @@ pub fn main(init: process.Init.Minimal) !void {
4850 // skip my own exe name
4951 var arg_idx: usize = 1;
5052
51 const zig_exe = cutArgPrefixOrFatal(args, &arg_idx, "--zig=");
52 const zig_lib_dir = cutArgPrefixOrFatal(args, &arg_idx, "--lib=");
53 const build_root = cutArgPrefixOrFatal(args, &arg_idx, "--build-root=");
54 const local_cache_root = cutArgPrefixOrFatal(args, &arg_idx, "--local-cache=");
55 const global_cache_root = cutArgPrefixOrFatal(args, &arg_idx, "--global-cache=");
56 const configure_path = cutArgPrefixOrFatal(args, &arg_idx, "--configure=");
53 const zig_exe = expectArgOrFatal(args, &arg_idx, "--zig");
54 const zig_lib_dir = expectArgOrFatal(args, &arg_idx, "--zig-lib-dir");
55 const build_root = expectArgOrFatal(args, &arg_idx, "--build-root");
56 const local_cache_root = expectArgOrFatal(args, &arg_idx, "--local-cache");
57 const global_cache_root = expectArgOrFatal(args, &arg_idx, "--global-cache");
58 const configure_path = expectArgOrFatal(args, &arg_idx, "--configuration");
5759
5860 const cwd: Io.Dir = .cwd();
5961
......@@ -90,11 +92,6 @@ pub fn main(init: process.Init.Minimal) !void {
9092 .environ_map = try init.environ.createMap(arena),
9193 .global_cache_root = global_cache_directory,
9294 .zig_lib_directory = zig_lib_directory,
93 .host = .{
94 .query = .{},
95 .result = try std.zig.system.resolveTargetQuery(io, .{}),
96 },
97 .time_report = false,
9895 };
9996
10097 graph.cache.addPrefix(.{ .path = null, .handle = cwd });
......@@ -105,9 +102,13 @@ pub fn main(init: process.Init.Minimal) !void {
105102
106103 var targets = std.array_list.Managed([]const u8).init(arena);
107104 var debug_log_scopes = std.array_list.Managed([]const u8).init(arena);
108
109 var install_prefix: ?[]const u8 = null;
110 var dir_list: std.Build.DirList = .{};
105 var help_menu = false;
106 var steps_menu = false;
107 var print_configuration = false;
108 var override_install_prefix: ?[]const u8 = null;
109 var override_lib_dir: ?[]const u8 = null;
110 var override_bin_dir: ?[]const u8 = null;
111 var override_include_dir: ?[]const u8 = null;
111112 var error_style: ErrorStyle = .verbose;
112113 var multiline_errors: MultilineErrors = .indent;
113114 var summary: ?Summary = null;
......@@ -115,8 +116,6 @@ pub fn main(init: process.Init.Minimal) !void {
115116 var skip_oom_steps = false;
116117 var test_timeout_ns: ?u64 = null;
117118 var color: Color = .auto;
118 var help_menu = false;
119 var steps_menu = false;
120119 var watch = false;
121120 var fuzz: ?Fuzz.Mode = null;
122121 var debounce_interval_ms: u16 = 50;
......@@ -152,51 +151,53 @@ pub fn main(init: process.Init.Minimal) !void {
152151 }
153152 }
154153
155 var configuration: Configuration = undefined;
156 {
157 var file = cwd.openFile(io, configure_path, .{}) catch |err|
158 fatal("failed to open configuration file {f}: {t}", .{ configure_path, err });
159 defer file.close(io);
160 configuration = Configuration.load(arena, io, file) catch |err|
161 fatal("failed to load configuration file {f}: {t}", .{ configure_path, err });
162 }
163 graph.configuration = &configuration;
164 graph.scanConfiguration();
154 const scanned_config: ScannedConfig = sc: {
155 const configuration = c: {
156 var file = cwd.openFile(io, configure_path, .{}) catch |err|
157 fatal("failed to open configuration file {s}: {t}", .{ configure_path, err });
158 defer file.close(io);
159 break :c Configuration.loadFile(arena, io, file) catch |err|
160 fatal("failed to load configuration file {s}: {t}", .{ configure_path, err });
161 };
162 var top_level_steps: std.ArrayList(Configuration.Step.Index) = .empty;
163 for (configuration.steps, 0..) |*conf_step, step_index| {
164 const flags: Configuration.Step.Flags = @bitCast(configuration.extra[conf_step.extra_index]);
165 if (flags.tag == .top_level) {
166 try top_level_steps.append(arena, @enumFromInt(step_index));
167 }
168 }
169 break :sc .{
170 .configuration = configuration,
171 .top_level_steps = top_level_steps.items,
172 };
173 };
165174
166 std.log.err("TODO handle user -D options", .{});
175 log.err("TODO handle user -D options", .{});
167176
168177 while (nextArg(args, &arg_idx)) |arg| {
169178 if (mem.startsWith(u8, arg, "-")) {
170 if (mem.eql(u8, arg, "--verbose")) {
171 verbose = true;
172 } else if (mem.eql(u8, arg, "-h") or mem.eql(u8, arg, "--help")) {
179 if (mem.eql(u8, arg, "-h") or mem.eql(u8, arg, "--help")) {
173180 help_menu = true;
174 } else if (mem.eql(u8, arg, "-p") or mem.eql(u8, arg, "--prefix")) {
175 install_prefix = nextArgOrFatal(args, &arg_idx);
176181 } else if (mem.eql(u8, arg, "-l") or mem.eql(u8, arg, "--list-steps")) {
177182 steps_menu = true;
178 } else if (mem.startsWith(u8, arg, "-fsys=")) {
179 const name = arg["-fsys=".len..];
180 graph.system_library_options.put(arena, name, .user_enabled) catch @panic("OOM");
181 } else if (mem.startsWith(u8, arg, "-fno-sys=")) {
182 const name = arg["-fno-sys=".len..];
183 graph.system_library_options.put(arena, name, .user_disabled) catch @panic("OOM");
183 } else if (mem.eql(u8, arg, "--print-configuration")) {
184 print_configuration = true;
185 } else if (mem.eql(u8, arg, "--verbose")) {
186 verbose = true;
187 } else if (mem.eql(u8, arg, "-p") or mem.eql(u8, arg, "--prefix")) {
188 override_install_prefix = nextArgOrFatal(args, &arg_idx);
184189 } else if (mem.eql(u8, arg, "--prefix-lib-dir")) {
185 dir_list.lib_dir = nextArgOrFatal(args, &arg_idx);
190 override_lib_dir = nextArgOrFatal(args, &arg_idx);
186191 } else if (mem.eql(u8, arg, "--prefix-exe-dir")) {
187 dir_list.exe_dir = nextArgOrFatal(args, &arg_idx);
192 override_bin_dir = nextArgOrFatal(args, &arg_idx);
188193 } else if (mem.eql(u8, arg, "--prefix-include-dir")) {
189 dir_list.include_dir = nextArgOrFatal(args, &arg_idx);
194 override_include_dir = nextArgOrFatal(args, &arg_idx);
190195 } else if (mem.eql(u8, arg, "--sysroot")) {
191196 sysroot = nextArgOrFatal(args, &arg_idx);
192197 } else if (mem.eql(u8, arg, "--maxrss")) {
193198 const max_rss_text = nextArgOrFatal(args, &arg_idx);
194 max_rss = std.fmt.parseIntSizeSuffix(max_rss_text, 10) catch |err| {
195 std.debug.print("invalid byte size: '{s}': {s}\n", .{
196 max_rss_text, @errorName(err),
197 });
198 process.exit(1);
199 };
199 max_rss = std.fmt.parseIntSizeSuffix(max_rss_text, 10) catch |err|
200 fatal("invalid byte size: '{s}': {t}", .{ max_rss_text, err });
200201 } else if (mem.eql(u8, arg, "--skip-oom-steps")) {
201202 skip_oom_steps = true;
202203 } else if (mem.eql(u8, arg, "--test-timeout")) {
......@@ -270,9 +271,7 @@ pub fn main(init: process.Init.Minimal) !void {
270271 const next_arg = nextArg(args, &arg_idx) orelse
271272 fatalWithHint("expected u32 after '{s}'", .{arg});
272273 graph.random_seed = std.fmt.parseUnsigned(u32, next_arg, 0) catch |err| {
273 fatal("unable to parse seed '{s}' as unsigned 32-bit integer: {s}\n", .{
274 next_arg, @errorName(err),
275 });
274 fatal("unable to parse seed '{s}' as unsigned 32-bit integer: {t}", .{ next_arg, err });
276275 };
277276 } else if (mem.eql(u8, arg, "--debounce")) {
278277 const next_arg = nextArg(args, &arg_idx) orelse
......@@ -288,7 +287,7 @@ pub fn main(init: process.Init.Minimal) !void {
288287 const addr_str = arg["--webui=".len..];
289288 if (std.mem.eql(u8, addr_str, "-")) fatal("web interface cannot listen on stdio", .{});
290289 webui_listen = Io.net.IpAddress.parseLiteral(addr_str) catch |err| {
291 fatal("invalid web UI address '{s}': {s}", .{ addr_str, @errorName(err) });
290 fatal("invalid web UI address '{s}': {t}", .{ addr_str, err });
292291 };
293292 } else if (mem.eql(u8, arg, "--debug-log")) {
294293 const next_arg = nextArgOrFatal(args, &arg_idx);
......@@ -300,11 +299,6 @@ pub fn main(init: process.Init.Minimal) !void {
300299 } else if (mem.cutPrefix(u8, arg, "--debug-rt=")) |rest| {
301300 graph.debug_compiler_runtime_libs = std.meta.stringToEnum(std.builtin.OptimizeMode, rest) orelse
302301 fatal("unrecognized optimization mode: {s}", .{rest});
303 } else if (mem.eql(u8, arg, "--system")) {
304 // The usage text shows another argument after this parameter
305 // but it is handled by the parent process. The build runner
306 // only sees this flag.
307 graph.system_package_mode = true;
308302 } else if (mem.eql(u8, arg, "--libc-runtimes") or mem.eql(u8, arg, "--glibc-runtimes")) {
309303 // --glibc-runtimes was the old name of the flag; kept for compatibility for now.
310304 libc_runtimes_dir = nextArgOrFatal(args, &arg_idx);
......@@ -383,7 +377,7 @@ pub fn main(init: process.Init.Minimal) !void {
383377 } else if (mem.startsWith(u8, arg, "-freference-trace=")) {
384378 const num = arg["-freference-trace=".len..];
385379 reference_trace = std.fmt.parseUnsigned(u32, num, 10) catch |err| {
386 std.debug.print("unable to parse reference_trace count '{s}': {s}", .{ num, @errorName(err) });
380 std.debug.print("unable to parse reference_trace count '{s}': {t}", .{ num, err });
387381 process.exit(1);
388382 };
389383 } else if (mem.eql(u8, arg, "-fno-reference-trace")) {
......@@ -414,6 +408,29 @@ pub fn main(init: process.Init.Minimal) !void {
414408 .off => .no_color,
415409 };
416410
411 if (help_menu) {
412 var w = initStdoutWriter(io);
413 scanned_config.printUsage(&graph, w) catch |err| switch (err) {
414 error.WriteFailed => return stdout_writer_allocation.err.?,
415 else => |e| return e,
416 };
417 w.flush() catch return stdout_writer_allocation.err.?;
418 return;
419 } else if (steps_menu) {
420 var w = initStdoutWriter(io);
421 scanned_config.printSteps(&graph, w) catch |err| switch (err) {
422 error.WriteFailed => return stdout_writer_allocation.err.?,
423 else => |e| return e,
424 };
425 w.flush() catch return stdout_writer_allocation.err.?;
426 return;
427 } else if (print_configuration) {
428 var w = initStdoutWriter(io);
429 scanned_config.print(w) catch return stdout_writer_allocation.err.?;
430 w.flush() catch return stdout_writer_allocation.err.?;
431 return;
432 }
433
417434 if (webui_listen != null) {
418435 if (watch) fatal("using '--webui' and '--watch' together is not yet supported; consider omitting '--watch' in favour of the web UI \"Rebuild\" button", .{});
419436 if (builtin.single_threaded) fatal("'--webui' is not yet supported on single-threaded hosts", .{});
......@@ -424,27 +441,33 @@ pub fn main(init: process.Init.Minimal) !void {
424441 });
425442 defer main_progress_node.end();
426443
427 graph.resolveInstallPrefix(install_prefix, dir_list);
444 const install_prefix_path: Path = if (graph.environ_map.get("DESTDIR")) |dest_dir| .{
445 .root_dir = .cwd(),
446 .sub_path = try Io.Dir.path.join(arena, &.{ dest_dir, override_install_prefix orelse "/usr" }),
447 } else if (override_install_prefix) |cwd_relative| .{
448 .root_dir = .cwd(),
449 .sub_path = cwd_relative,
450 } else .{
451 .root_dir = build_root_directory,
452 .sub_path = "zig-out",
453 };
428454
429 if (graph.validateUserInputDidItFail()) {
430 fatal(" access the help menu with 'zig build -h'", .{});
431 }
455 const install_lib_path: Path = if (override_lib_dir) |cwd_relative| .{
456 .root_dir = .cwd(),
457 .sub_path = cwd_relative,
458 } else try install_prefix_path.join(arena, "lib");
432459
433 validateSystemLibraryOptions(&graph);
460 const install_bin_path: Path = if (override_bin_dir) |cwd_relative| .{
461 .root_dir = .cwd(),
462 .sub_path = cwd_relative,
463 } else try install_prefix_path.join(arena, "bin");
434464
435 if (help_menu) {
436 var w = initStdoutWriter(io);
437 printUsage(&graph, w) catch return stdout_writer_allocation.err.?;
438 w.flush() catch return stdout_writer_allocation.err.?;
439 return;
440 }
465 const install_include_path: Path = if (override_include_dir) |cwd_relative| .{
466 .root_dir = .cwd(),
467 .sub_path = cwd_relative,
468 } else try install_prefix_path.join(arena, "include");
441469
442 if (steps_menu) {
443 var w = initStdoutWriter(io);
444 printSteps(&graph, w) catch return stdout_writer_allocation.err.?;
445 w.flush() catch return stdout_writer_allocation.err.?;
446 return;
447 }
470 if (true) @panic("TODO");
448471
449472 var run: Run = .{
450473 .gpa = gpa,
......@@ -463,6 +486,13 @@ pub fn main(init: process.Init.Minimal) !void {
463486 .error_style = error_style,
464487 .multiline_errors = multiline_errors,
465488 .summary = summary orelse if (watch or webui_listen != null) .line else .failures,
489
490 .install_paths = .{
491 .prefix = install_prefix_path,
492 .lib = install_lib_path,
493 .bin = install_bin_path,
494 .include = install_include_path,
495 },
466496 };
467497 defer {
468498 run.memory_blocked_steps.deinit(gpa);
......@@ -628,9 +658,9 @@ fn prepare(graph: *Graph, step_names: []const []const u8, run: *Run) !void {
628658 try step_stack.ensureUnusedCapacity(gpa, step_names.len);
629659 for (0..step_names.len) |i| {
630660 const step_name = step_names[step_names.len - i - 1];
631 const s = graph.top_level_steps.get(step_name) orelse {
632 std.log.info("access the help menu with \"zig build -h\"", .{});
633 fatal("no step named '{s}'", .{step_name});
661 const s = run.top_level_steps.get(step_name) orelse {
662 log.info("access the help menu with 'zig build -h'", .{});
663 fatal("no such step: {s}", .{step_name});
634664 };
635665 step_stack.putAssumeCapacity(&s.step, {});
636666 }
......@@ -873,11 +903,11 @@ fn runStepNames(
873903 print_node.last = true;
874904 printTreeStep(graph, graph.default_step, run, t, &print_node, &step_stack_copy) catch {};
875905 } else {
876 const last_index = if (run.summary == .all) graph.top_level_steps.count() else blk: {
906 const last_index = if (run.summary == .all) run.top_level_steps.count() else blk: {
877907 var i: usize = step_names.len;
878908 while (i > 0) {
879909 i -= 1;
880 const step = graph.top_level_steps.get(step_names[i]).?.step;
910 const step = run.top_level_steps.get(step_names[i]).?.step;
881911 const found = switch (run.summary) {
882912 .all, .line, .none => unreachable,
883913 .failures => step.state != .success,
......@@ -885,10 +915,10 @@ fn runStepNames(
885915 };
886916 if (found) break :blk i;
887917 }
888 break :blk graph.top_level_steps.count();
918 break :blk run.top_level_steps.count();
889919 };
890920 for (step_names, 0..) |step_name, i| {
891 const tls = graph.top_level_steps.get(step_name).?;
921 const tls = run.top_level_steps.get(step_name).?;
892922 print_node.last = i + 1 == last_index;
893923 printTreeStep(graph, &tls.step, run, t, &print_node, &step_stack_copy) catch {};
894924 }
......@@ -1207,7 +1237,7 @@ fn constructGraphAndCheckForDependencyLoop(
12071237
12081238 // We dupe to avoid shuffling the steps in the summary, it depends
12091239 // on s.dependencies' order.
1210 const deps = gpa.dupe(*Step, s.dependencies.items) catch @panic("OOM");
1240 const deps = try gpa.dupe(*Step, s.dependencies.items);
12111241 defer gpa.free(deps);
12121242
12131243 rand.shuffle(*Step, deps);
......@@ -1327,7 +1357,7 @@ fn makeStep(
13271357 try run.max_rss_mutex.lock(io);
13281358 defer run.max_rss_mutex.unlock(io);
13291359 run.available_rss += s.max_rss;
1330 dispatch_set.ensureUnusedCapacity(gpa, run.memory_blocked_steps.items.len) catch @panic("OOM");
1360 try dispatch_set.ensureUnusedCapacity(gpa, run.memory_blocked_steps.items.len);
13311361 while (run.memory_blocked_steps.getLast()) |candidate| {
13321362 if (run.available_rss < candidate.max_rss) break;
13331363 assert(run.memory_blocked_steps.pop() == candidate);
......@@ -1360,7 +1390,7 @@ fn stepReady(
13601390 defer run.max_rss_mutex.unlock(io);
13611391 if (run.available_rss < s.max_rss) {
13621392 // Running this step right now could possibly exceed the allotted RSS.
1363 run.memory_blocked_steps.append(run.gpa, s) catch @panic("OOM");
1393 try run.memory_blocked_steps.append(run.gpa, s);
13641394 return;
13651395 }
13661396 run.available_rss -= s.max_rss;
......@@ -1454,178 +1484,6 @@ pub fn printErrorMessages(
14541484 try writer.writeByte('\n');
14551485}
14561486
1457fn printSteps(graph: *Graph, w: *Writer) !void {
1458 const arena = graph.arena;
1459 for (graph.top_level_steps.values()) |top_level_step| {
1460 const name = if (&top_level_step.step == graph.default_step)
1461 try fmt.allocPrint(arena, "{s} (default)", .{top_level_step.step.name})
1462 else
1463 top_level_step.step.name;
1464 try w.print(" {s:<28} {s}\n", .{ name, top_level_step.description });
1465 }
1466}
1467
1468fn printUsage(graph: *Graph, w: *Writer) !void {
1469 const arena = graph.arena;
1470
1471 try w.print(
1472 \\Usage: {s} build [steps] [options]
1473 \\
1474 \\Steps:
1475 \\
1476 , .{graph.zig_exe});
1477 try printSteps(graph, w);
1478 try w.writeAll(
1479 \\
1480 \\Project-Specific Options:
1481 \\
1482 );
1483
1484 if (graph.available_options_list.items.len == 0) {
1485 try w.print(" (none)\n", .{});
1486 } else {
1487 for (graph.available_options_list.items) |option| {
1488 const name = try fmt.allocPrint(arena, " -D{s}=[{t}]", .{ option.name, option.type_id });
1489 try w.print("{s:<30} {s}\n", .{ name, option.description });
1490 if (option.enum_options) |enum_options| {
1491 const padding: [33]u8 = @splat(' ');
1492 try w.writeAll(padding ++ "Supported Values:\n");
1493 for (enum_options) |enum_option| {
1494 try w.print(padding ++ " {s}\n", .{enum_option});
1495 }
1496 }
1497 }
1498 }
1499
1500 try w.writeAll(
1501 \\
1502 \\System Integration Options:
1503 \\ --search-prefix [path] Add a path to look for binaries, libraries, headers
1504 \\ --sysroot [path] Set the system root directory (usually /)
1505 \\ --libc [file] Provide a file which specifies libc paths
1506 \\
1507 \\ --system [pkgdir] Disable package fetching; enable all integrations
1508 \\ -fsys=[name] Enable a system integration
1509 \\ -fno-sys=[name] Disable a system integration
1510 \\
1511 \\ -fdarling, -fno-darling Integration with system-installed Darling to
1512 \\ execute macOS programs on Linux hosts
1513 \\ (default: no)
1514 \\ -fqemu, -fno-qemu Integration with system-installed QEMU to execute
1515 \\ foreign-architecture programs on Linux hosts
1516 \\ (default: no)
1517 \\ --libc-runtimes [path] Enhances QEMU integration by providing dynamic libc
1518 \\ (e.g. glibc or musl) built for multiple foreign
1519 \\ architectures, allowing execution of non-native
1520 \\ programs that link with libc.
1521 \\ -frosetta, -fno-rosetta Rely on Rosetta to execute x86_64 programs on
1522 \\ ARM64 macOS hosts. (default: no)
1523 \\ -fwasmtime, -fno-wasmtime Integration with system-installed wasmtime to
1524 \\ execute WASI binaries. (default: no)
1525 \\ -fwine, -fno-wine Integration with system-installed Wine to execute
1526 \\ Windows programs on Linux hosts. (default: no)
1527 \\
1528 \\ Available System Integrations: Enabled:
1529 \\
1530 );
1531 if (graph.system_library_options.entries.len == 0) {
1532 try w.writeAll(" (none) -\n");
1533 } else {
1534 for (graph.system_library_options.keys(), graph.system_library_options.values()) |k, v| {
1535 const status = switch (v) {
1536 .declared_enabled => "yes",
1537 .declared_disabled => "no",
1538 .user_enabled, .user_disabled => unreachable, // already emitted error
1539 };
1540 try w.print(" {s:<43} {s}\n", .{ k, status });
1541 }
1542 }
1543
1544 try w.writeAll(
1545 \\
1546 \\General Options:
1547 \\ -h, --help Print this help and exit
1548 \\ -l, --list-steps Print available steps
1549 \\
1550 \\ -p, --prefix [path] Where to install files (default: zig-out)
1551 \\ --prefix-lib-dir [path] Where to install libraries
1552 \\ --prefix-exe-dir [path] Where to install executables
1553 \\ --prefix-include-dir [path] Where to install C header files
1554 \\ --release[=mode] Request release mode, optionally specifying a
1555 \\ preferred optimization mode: fast, safe, small
1556 \\
1557 \\ --verbose Print commands before executing them
1558 \\ --color [auto|off|on] Enable or disable colored error messages
1559 \\ --error-style [style] Control how build errors are printed
1560 \\ verbose (Default) Report errors with full context
1561 \\ minimal Report errors after summary, excluding context like command lines
1562 \\ verbose_clear Like 'verbose', but clear the terminal at the start of each update
1563 \\ minimal_clear Like 'minimal', but clear the terminal at the start of each update
1564 \\ --multiline-errors [style] Control how multi-line error messages are printed
1565 \\ indent (Default) Indent non-initial lines to align with initial line
1566 \\ newline Include a leading newline so that the error message is on its own lines
1567 \\ none Print as usual so the first line is misaligned
1568 \\ --summary [mode] Control the printing of the build summary
1569 \\ all Print the build summary in its entirety
1570 \\ new Omit cached steps
1571 \\ failures (Default if short-lived) Only print failed steps
1572 \\ line (Default if long-lived) Only print the single-line summary
1573 \\ none Do not print the build summary
1574 \\ -j<N> Limit concurrent jobs (default is to use all CPU cores)
1575 \\ --maxrss <bytes> Limit memory usage (default is to use available memory)
1576 \\ --skip-oom-steps Instead of failing, skip steps that would exceed --maxrss
1577 \\ --test-timeout <timeout> Limit execution time of unit tests, terminating if exceeded.
1578 \\ The timeout must include a unit: ns, us, ms, s, m, h
1579 \\ --watch Continuously rebuild when source files are modified
1580 \\ --debounce <ms> Delay before rebuilding after changed file detected
1581 \\ --webui[=ip] Enable the web interface on the given IP address
1582 \\ --fuzz[=limit] Continuously search for unit test failures with an optional
1583 \\ limit to the max number of iterations. The argument supports
1584 \\ an optional 'K', 'M', or 'G' suffix (e.g. '10K'). Implies
1585 \\ '--webui' when no limit is specified.
1586 \\ --time-report Force full rebuild and provide detailed information on
1587 \\ compilation time of Zig source code (implies '--webui')
1588 \\ -fincremental Enable incremental compilation
1589 \\ -fno-incremental Disable incremental compilation
1590 \\
1591 \\Package Management Options:
1592 \\ --fetch[=mode] Fetch dependency tree (optionally choose laziness) and exit
1593 \\ needed (Default) Lazy dependencies are fetched as needed
1594 \\ all Lazy dependencies are always fetched
1595 \\ --fork=[path] Override one or more projects from dependency tree
1596 \\
1597 \\Advanced Options:
1598 \\ -freference-trace[=num] How many lines of reference trace should be shown per compile error
1599 \\ -fno-reference-trace Disable reference trace
1600 \\ -fallow-so-scripts Allows .so files to be GNU ld scripts
1601 \\ -fno-allow-so-scripts (default) .so files must be ELF files
1602 \\ --build-file [file] Override path to build.zig
1603 \\ --cache-dir [path] Override path to local Zig cache directory
1604 \\ --global-cache-dir [path] Override path to global Zig cache directory
1605 \\ --zig-lib-dir [arg] Override path to Zig lib directory
1606 \\ --build-runner [file] Override path to build runner
1607 \\ --seed [integer] For shuffling dependency traversal order (default: random)
1608 \\ --build-id[=style] At a minor link-time expense, embeds a build ID in binaries
1609 \\ fast 8-byte non-cryptographic hash (COFF, ELF, WASM)
1610 \\ sha1, tree 20-byte cryptographic hash (ELF, WASM)
1611 \\ md5 16-byte cryptographic hash (ELF)
1612 \\ uuid 16-byte random UUID (ELF, WASM)
1613 \\ 0x[hexstring] Constant ID, maximum 32 bytes (ELF, WASM)
1614 \\ none (default) No build ID
1615 \\ --debug-log [scope] Enable debugging the compiler
1616 \\ --debug-pkg-config Fail if unknown pkg-config flags encountered
1617 \\ --debug-rt Debug compiler runtime libraries
1618 \\ --verbose-link Enable compiler debug output for linking
1619 \\ --verbose-air Enable compiler debug output for Zig AIR
1620 \\ --verbose-llvm-ir[=file] Enable compiler debug output for LLVM IR
1621 \\ --verbose-llvm-bc=[file] Enable compiler debug output for LLVM BC
1622 \\ --verbose-cimport Enable compiler debug output for C imports
1623 \\ --verbose-cc Enable compiler debug output for C compilation
1624 \\ --verbose-llvm-cpu-features Enable compiler debug output for LLVM CPU features
1625 \\
1626 );
1627}
1628
16291487fn nextArg(args: []const [:0]const u8, idx: *usize) ?[:0]const u8 {
16301488 if (idx.* >= args.len) return null;
16311489 defer idx.* += 1;
......@@ -1633,17 +1491,17 @@ fn nextArg(args: []const [:0]const u8, idx: *usize) ?[:0]const u8 {
16331491}
16341492
16351493fn nextArgOrFatal(args: []const [:0]const u8, idx: *usize) [:0]const u8 {
1636 return nextArg(args, idx) orelse
1637 fatal("expected argument after {q}\n access the help menu with \"zig build -h\"", .{args[idx.* - 1]});
1494 return nextArg(args, idx) orelse {
1495 log.info("access the help menu with \"zig build -h\"", .{});
1496 fatal("expected argument after {q}", .{args[idx.* - 1]});
1497 };
16381498}
16391499
1640fn cutArgPrefixOrFatal(args: []const [:0]const u8, idx: *usize, prefix: []const u8) []const u8 {
1641 if (nextArg(args, idx)) |next_arg| {
1642 if (mem.cutPrefix(u8, next_arg, prefix)) |arg| {
1643 return arg;
1644 }
1645 }
1646 fatal("expected argument after {q} to start with {q}", .{ args[idx.* - 1], prefix });
1500fn expectArgOrFatal(args: []const [:0]const u8, index_ptr: *usize, first: []const u8) []const u8 {
1501 const next_arg = nextArg(args, index_ptr) orelse fatal("missing {q} argument", .{first});
1502 if (!mem.eql(u8, first, next_arg)) fatal("expected {q} instead of {q}", .{ first, next_arg });
1503 const arg = nextArg(args, index_ptr) orelse fatal("expected argument after {q}", .{first});
1504 return arg;
16471505}
16481506
16491507fn argsRest(args: []const [:0]const u8, idx: usize) ?[]const [:0]const u8 {
......@@ -1674,29 +1532,28 @@ const MultilineErrors = enum { indent, newline, none };
16741532const Summary = enum { all, new, failures, line, none };
16751533
16761534fn fatalWithHint(comptime f: []const u8, args: anytype) noreturn {
1677 std.debug.print(f ++ "\n access the help menu with 'zig build -h'\n", args);
1678 process.exit(1);
1535 log.info("access the help menu with 'zig build -h'", .{});
1536 fatal(f, args);
16791537}
16801538
1681fn validateSystemLibraryOptions(graph: *Graph) void {
1682 var bad = false;
1683 for (graph.system_library_options.keys(), graph.system_library_options.values()) |k, v| {
1684 switch (v) {
1685 .user_disabled, .user_enabled => {
1686 // The user tried to enable or disable a system library integration, but
1687 // the build script did not recognize that option.
1688 std.debug.print("system library name not recognized by build script: '{s}'\n", .{k});
1689 bad = true;
1690 },
1691 .declared_disabled, .declared_enabled => {},
1692 }
1693 }
1694 if (bad) {
1695 std.debug.print(" access the help menu with 'zig build -h'\n", .{});
1696 process.exit(1);
1539fn cleanTmpFiles(io: Io, steps: []const *Step) void {
1540 for (steps) |step| {
1541 const wf = step.cast(Step.WriteFile) orelse continue;
1542 if (wf.mode != .tmp) continue;
1543 const path = wf.generated_directory.path orelse continue;
1544 Io.Dir.cwd().deleteTree(io, path) catch |err| {
1545 log.warn("failed to delete {s}: {t}", .{ path, err });
1546 };
16971547 }
16981548}
16991549
1550const InstallPaths = struct {
1551 prefix: Path,
1552 lib: Path,
1553 bin: Path,
1554 include: Path,
1555};
1556
17001557var stdio_buffer_allocation: [256]u8 = undefined;
17011558var stdout_writer_allocation: Io.File.Writer = undefined;
17021559
......@@ -1705,13 +1562,202 @@ fn initStdoutWriter(io: Io) *Writer {
17051562 return &stdout_writer_allocation.interface;
17061563}
17071564
1708fn cleanTmpFiles(io: Io, steps: []const *Step) void {
1709 for (steps) |step| {
1710 const wf = step.cast(Step.WriteFile) orelse continue;
1711 if (wf.mode != .tmp) continue;
1712 const path = wf.generated_directory.path orelse continue;
1713 Io.Dir.cwd().deleteTree(io, path) catch |err| {
1714 std.log.warn("failed to delete {s}: {t}", .{ path, err });
1715 };
1565const ScannedConfig = struct {
1566 configuration: Configuration,
1567 top_level_steps: []const Configuration.Step.Index,
1568
1569 fn print(sc: *const ScannedConfig, w: *Writer) Writer.Error!void {
1570 var serializer: std.zon.Serializer = .{ .writer = w };
1571 var s = try serializer.beginStruct(.{});
1572
1573 try s.field("default_step", @intFromEnum(sc.configuration.default_step), .{});
1574 {
1575 var tuple = try s.beginTupleField("top_level_steps", .{});
1576 for (sc.top_level_steps) |step| try tuple.field(@intFromEnum(step), .{});
1577 try tuple.end();
1578 }
1579
1580 try s.end();
17161581 }
1717}
1582
1583 fn printSteps(sc: *const ScannedConfig, graph: *Graph, w: *Writer) !void {
1584 const arena = graph.arena;
1585 const c = &sc.configuration;
1586 for (sc.top_level_steps) |step_index| {
1587 const step = step_index.ptr(c);
1588 const name = step.name.slice(c);
1589 const decorated_name = if (step_index == c.default_step)
1590 try fmt.allocPrint(arena, "{s} (default)", .{name})
1591 else
1592 name;
1593 const top_level = c.extraData(Configuration.Step.TopLevel, step.extra_index);
1594 const description = top_level.description.slice(c);
1595 try w.print(" {s:<28} {s}\n", .{ decorated_name, description });
1596 }
1597 }
1598
1599 fn printUsage(sc: *const ScannedConfig, graph: *Graph, w: *Writer) !void {
1600 const arena = graph.arena;
1601
1602 try w.print(
1603 \\Usage: {s} build [steps] [options]
1604 \\
1605 \\Steps:
1606 \\
1607 , .{graph.zig_exe});
1608 try printSteps(sc, graph, w);
1609 try w.writeAll(
1610 \\
1611 \\Project-Specific Options:
1612 \\
1613 );
1614
1615 const available_options = sc.configuration.available_options;
1616 if (available_options.len == 0) {
1617 try w.print(" (none)\n", .{});
1618 } else {
1619 for (available_options) |option| {
1620 const name = option.name.slice(&sc.configuration);
1621 const description = option.description.slice(&sc.configuration);
1622 const help = try fmt.allocPrint(arena, " -D{s}=[{t}]", .{ name, option.type });
1623 try w.print("{s:<30} {s}\n", .{ help, description });
1624 if (option.enum_options.slice(&sc.configuration)) |enum_options| {
1625 const padding: [33]u8 = @splat(' ');
1626 try w.writeAll(padding ++ "Supported Values:\n");
1627 for (enum_options) |enum_option_index| {
1628 const enum_option = enum_option_index.slice(&sc.configuration);
1629 try w.print(padding ++ " {s}\n", .{enum_option});
1630 }
1631 }
1632 }
1633 }
1634
1635 try w.writeAll(
1636 \\
1637 \\System Integration Options:
1638 \\ --search-prefix [path] Add a path to look for binaries, libraries, headers
1639 \\ --sysroot [path] Set the system root directory (usually /)
1640 \\ --libc [file] Provide a file which specifies libc paths
1641 \\
1642 \\ --system [pkgdir] Disable package fetching; enable all integrations
1643 \\ -fsys=[name] Enable a system integration
1644 \\ -fno-sys=[name] Disable a system integration
1645 \\
1646 \\ -fdarling, -fno-darling Integration with system-installed Darling to
1647 \\ execute macOS programs on Linux hosts
1648 \\ (default: no)
1649 \\ -fqemu, -fno-qemu Integration with system-installed QEMU to execute
1650 \\ foreign-architecture programs on Linux hosts
1651 \\ (default: no)
1652 \\ --libc-runtimes [path] Enhances QEMU integration by providing dynamic libc
1653 \\ (e.g. glibc or musl) built for multiple foreign
1654 \\ architectures, allowing execution of non-native
1655 \\ programs that link with libc.
1656 \\ -frosetta, -fno-rosetta Rely on Rosetta to execute x86_64 programs on
1657 \\ ARM64 macOS hosts. (default: no)
1658 \\ -fwasmtime, -fno-wasmtime Integration with system-installed wasmtime to
1659 \\ execute WASI binaries. (default: no)
1660 \\ -fwine, -fno-wine Integration with system-installed Wine to execute
1661 \\ Windows programs on Linux hosts. (default: no)
1662 \\
1663 \\ Available System Integrations: Enabled:
1664 \\
1665 );
1666 if (sc.configuration.system_integrations.len == 0) {
1667 try w.writeAll(" (none) -\n");
1668 } else {
1669 for (sc.configuration.system_integrations) |system_integration| {
1670 const name = system_integration.name.slice(&sc.configuration);
1671 const status = switch (system_integration.status) {
1672 .disabled => "no",
1673 .enabled => "yes",
1674 };
1675 try w.print(" {s:<43} {s}\n", .{ name, status });
1676 }
1677 }
1678
1679 try w.writeAll(
1680 \\
1681 \\General Options:
1682 \\ -h, --help Print this help and exit
1683 \\ -l, --list-steps Print available steps
1684 \\
1685 \\ -p, --prefix [path] Where to install files (default: zig-out)
1686 \\ --prefix-lib-dir [path] Where to install libraries
1687 \\ --prefix-exe-dir [path] Where to install executables
1688 \\ --prefix-include-dir [path] Where to install C header files
1689 \\ --release[=mode] Request release mode, optionally specifying a
1690 \\ preferred optimization mode: fast, safe, small
1691 \\
1692 \\ --verbose Print commands before executing them
1693 \\ --color [auto|off|on] Enable or disable colored error messages
1694 \\ --error-style [style] Control how build errors are printed
1695 \\ verbose (Default) Report errors with full context
1696 \\ minimal Report errors after summary, excluding context like command lines
1697 \\ verbose_clear Like 'verbose', but clear the terminal at the start of each update
1698 \\ minimal_clear Like 'minimal', but clear the terminal at the start of each update
1699 \\ --multiline-errors [style] Control how multi-line error messages are printed
1700 \\ indent (Default) Indent non-initial lines to align with initial line
1701 \\ newline Include a leading newline so that the error message is on its own lines
1702 \\ none Print as usual so the first line is misaligned
1703 \\ --summary [mode] Control the printing of the build summary
1704 \\ all Print the build summary in its entirety
1705 \\ new Omit cached steps
1706 \\ failures (Default if short-lived) Only print failed steps
1707 \\ line (Default if long-lived) Only print the single-line summary
1708 \\ none Do not print the build summary
1709 \\ -j<N> Limit concurrent jobs (default is to use all CPU cores)
1710 \\ --maxrss <bytes> Limit memory usage (default is to use available memory)
1711 \\ --skip-oom-steps Instead of failing, skip steps that would exceed --maxrss
1712 \\ --test-timeout <timeout> Limit execution time of unit tests, terminating if exceeded.
1713 \\ The timeout must include a unit: ns, us, ms, s, m, h
1714 \\ --watch Continuously rebuild when source files are modified
1715 \\ --debounce <ms> Delay before rebuilding after changed file detected
1716 \\ --webui[=ip] Enable the web interface on the given IP address
1717 \\ --fuzz[=limit] Continuously search for unit test failures with an optional
1718 \\ limit to the max number of iterations. The argument supports
1719 \\ an optional 'K', 'M', or 'G' suffix (e.g. '10K'). Implies
1720 \\ '--webui' when no limit is specified.
1721 \\ --time-report Force full rebuild and provide detailed information on
1722 \\ compilation time of Zig source code (implies '--webui')
1723 \\ -fincremental Enable incremental compilation
1724 \\ -fno-incremental Disable incremental compilation
1725 \\
1726 \\Package Management Options:
1727 \\ --fetch[=mode] Fetch dependency tree (optionally choose laziness) and exit
1728 \\ needed (Default) Lazy dependencies are fetched as needed
1729 \\ all Lazy dependencies are always fetched
1730 \\ --fork=[path] Override one or more projects from dependency tree
1731 \\
1732 \\Advanced Options:
1733 \\ -freference-trace[=num] How many lines of reference trace should be shown per compile error
1734 \\ -fno-reference-trace Disable reference trace
1735 \\ -fallow-so-scripts Allows .so files to be GNU ld scripts
1736 \\ -fno-allow-so-scripts (default) .so files must be ELF files
1737 \\ --build-file [file] Override path to build.zig
1738 \\ --cache-dir [path] Override path to local Zig cache directory
1739 \\ --global-cache-dir [path] Override path to global Zig cache directory
1740 \\ --zig-lib-dir [arg] Override path to Zig lib directory
1741 \\ --build-runner [file] Override path to build runner
1742 \\ --seed [integer] For shuffling dependency traversal order (default: random)
1743 \\ --build-id[=style] At a minor link-time expense, embeds a build ID in binaries
1744 \\ fast 8-byte non-cryptographic hash (COFF, ELF, WASM)
1745 \\ sha1, tree 20-byte cryptographic hash (ELF, WASM)
1746 \\ md5 16-byte cryptographic hash (ELF)
1747 \\ uuid 16-byte random UUID (ELF, WASM)
1748 \\ 0x[hexstring] Constant ID, maximum 32 bytes (ELF, WASM)
1749 \\ none (default) No build ID
1750 \\ --debug-log [scope] Enable debugging the compiler
1751 \\ --debug-pkg-config Fail if unknown pkg-config flags encountered
1752 \\ --debug-rt Debug compiler runtime libraries
1753 \\ --verbose-link Enable compiler debug output for linking
1754 \\ --verbose-air Enable compiler debug output for Zig AIR
1755 \\ --verbose-llvm-ir[=file] Enable compiler debug output for LLVM IR
1756 \\ --verbose-llvm-bc=[file] Enable compiler debug output for LLVM BC
1757 \\ --verbose-cimport Enable compiler debug output for C imports
1758 \\ --verbose-cc Enable compiler debug output for C compilation
1759 \\ --verbose-llvm-cpu-features Enable compiler debug output for LLVM CPU features
1760 \\
1761 );
1762 }
1763};
lib/compiler/maker/Fuzz.zig+10-8
......@@ -1,17 +1,19 @@
1const std = @import("Std");
1const Fuzz = @This();
2
3const std = @import("std");
24const Io = std.Io;
35const Build = std.Build;
4const Cache = Build.Cache;
6const Cache = std.Build.Cache;
57const Step = std.Build.Step;
68const assert = std.debug.assert;
79const fatal = std.process.fatal;
810const Allocator = std.mem.Allocator;
911const log = std.log;
1012const Coverage = std.debug.Coverage;
11const abi = Build.abi.fuzz;
13const abi = std.Build.abi.fuzz;
1214
13const Fuzz = @This();
14const build_runner = @import("root");
15const maker = @import("../maker.zig");
16const WebServer = @import("WebServer.zig");
1517
1618gpa: Allocator,
1719io: Io,
......@@ -33,7 +35,7 @@ queue_cond: Io.Condition,
3335msg_queue: std.ArrayList(Msg),
3436
3537pub const Mode = union(enum) {
36 forever: struct { ws: *Build.WebServer },
38 forever: struct { ws: *WebServer },
3739 limit: Limited,
3840
3941 pub const Limited = struct {
......@@ -173,7 +175,7 @@ fn rebuildTestsWorkerRunFallible(run: *Step.Run, gpa: Allocator, parent_prog_nod
173175 var buf: [256]u8 = undefined;
174176 const stderr = try io.lockStderr(&buf, graph.stderr_mode);
175177 defer io.unlockStderr();
176 build_runner.printErrorMessages(gpa, &compile.step, .{}, stderr.terminal(), .verbose, .indent) catch {};
178 maker.printErrorMessages(gpa, &compile.step, .{}, stderr.terminal(), .verbose, .indent) catch {};
177179 }
178180
179181 const rebuilt_bin_path = result catch |err| switch (err) {
......@@ -196,7 +198,7 @@ fn fuzzWorkerRun(fuzz: *Fuzz, run: *Step.Run) void {
196198 error.Canceled => return,
197199 };
198200 defer io.unlockStderr();
199 build_runner.printErrorMessages(gpa, &run.step, .{}, stderr.terminal(), .verbose, .indent) catch {};
201 maker.printErrorMessages(gpa, &run.step, .{}, stderr.terminal(), .verbose, .indent) catch {};
200202 return;
201203 },
202204 else => {
lib/compiler/maker/Graph.zig+8-75
......@@ -6,87 +6,20 @@ const Io = std.Io;
66const Allocator = std.mem.Allocator;
77const Configuration = std.Build.Configuration;
88
9const Step = @import("Step.zig");
10const Package = @import("Package.zig");
11
129io: Io,
1310/// Process lifetime.
1411arena: Allocator,
15system_library_options: std.StringArrayHashMapUnmanaged(std.Build.SystemLibraryMode),
16system_package_mode: bool,
17debug_compiler_runtime_libs: ?std.builtin.OptimizeMode = null,
1812cache: std.Build.Cache,
19zig_exe: [:0]const u8,
13zig_exe: []const u8,
2014environ_map: std.process.Environ.Map,
2115global_cache_root: std.Build.Cache.Directory,
2216zig_lib_directory: std.Build.Cache.Directory,
23incremental: ?bool,
24random_seed: u32,
25allow_so_scripts: ?bool,
26time_report: bool,
17
18debug_compiler_runtime_libs: ?std.builtin.OptimizeMode = null,
19incremental: ?bool = null,
20random_seed: u32 = 0,
21allow_so_scripts: ?bool = null,
22time_report: bool = false,
2723/// Similar to the `Io.Terminal.Mode` returned by `Io.lockStderr`, but also
2824/// respects the '--color' flag.
29stderr_mode: ?Io.Terminal.Mode,
30
31configuration: *const Configuration,
32top_level_steps: std.AutoArrayHashMapUnmanaged(Configuration.String, Configuration.Step.Index),
33
34pub const DirList = struct {
35 lib_dir: ?[]const u8 = null,
36 exe_dir: ?[]const u8 = null,
37 include_dir: ?[]const u8 = null,
38};
39
40/// This function is intended to be called by lib/build_runner.zig, not a build.zig file.
41pub fn resolveInstallPrefix(graph: *Graph, p: *Package, install_prefix: ?[]const u8, dir_list: DirList) !void {
42 if (p.dest_dir) |dest_dir| {
43 p.install_prefix = install_prefix orelse "/usr";
44 p.install_path = b.pathJoin(&.{ dest_dir, p.install_prefix });
45 } else {
46 p.install_prefix = install_prefix orelse
47 (p.build_root.join(b.allocator, &.{"zig-out"}) catch @panic("unhandled error"));
48 b.install_path = b.install_prefix;
49 }
50
51 var lib_list = [_][]const u8{ b.install_path, "lib" };
52 var exe_list = [_][]const u8{ b.install_path, "bin" };
53 var h_list = [_][]const u8{ b.install_path, "include" };
54
55 if (dir_list.lib_dir) |dir| {
56 if (fs.path.isAbsolute(dir)) lib_list[0] = b.dest_dir orelse "";
57 lib_list[1] = dir;
58 }
59
60 if (dir_list.exe_dir) |dir| {
61 if (fs.path.isAbsolute(dir)) exe_list[0] = b.dest_dir orelse "";
62 exe_list[1] = dir;
63 }
64
65 if (dir_list.include_dir) |dir| {
66 if (fs.path.isAbsolute(dir)) h_list[0] = b.dest_dir orelse "";
67 h_list[1] = dir;
68 }
69
70 b.lib_dir = b.pathJoin(&lib_list);
71 b.exe_dir = b.pathJoin(&exe_list);
72 b.h_dir = b.pathJoin(&h_list);
73}
74
75fn determineAndApplyInstallPrefix(b: *Build) error{OutOfMemory}!void {
76 // Create an installation directory local to this package. This will be used when
77 // dependant packages require a standard prefix, such as include directories for C headers.
78 var hash = b.graph.cache.hash;
79 // Random bytes to make unique. Refresh this with new random bytes when
80 // implementation is modified in a non-backwards-compatible way.
81 hash.add(@as(u32, 0xd8cb0056));
82 hash.addBytes(b.dep_prefix);
83
84 var wyhash = std.hash.Wyhash.init(0);
85 hashUserInputOptionsMap(b.allocator, b.user_input_options, &wyhash);
86 hash.add(wyhash.final());
87
88 const digest = hash.final();
89 const install_prefix = try b.cache_root.join(b.allocator, &.{ "i", &digest });
90 b.resolveInstallPrefix(install_prefix, .{});
91}
92
25stderr_mode: ?Io.Terminal.Mode = null,
lib/compiler/maker/Package.zig+18
......@@ -10,3 +10,21 @@ exe_dir: []const u8,
1010h_dir: []const u8,
1111/// Path to the directory containing build.zig.
1212build_root: std.Build.Cache.Path,
13
14fn determineAndApplyInstallPrefix(p: *Package) error{OutOfMemory}!void {
15 // Create an installation directory local to this package. This will be used when
16 // dependant packages require a standard prefix, such as include directories for C headers.
17 var hash = p.graph.cache.hash;
18 // Random bytes to make unique. Refresh this with new random bytes when
19 // implementation is modified in a non-backwards-compatible way.
20 hash.add(@as(u32, 0xd8cb0056));
21 hash.addBytes(p.dep_prefix);
22
23 var wyhash = std.hash.Wyhash.init(0);
24 hashUserInputOptionsMap(p.allocator, p.user_input_options, &wyhash);
25 hash.add(wyhash.final());
26
27 const digest = hash.final();
28 const install_prefix = try p.cache_root.join(p.allocator, &.{ "i", &digest });
29 p.resolveInstallPrefix(install_prefix, .{});
30}
lib/compiler/maker/Step.zig+12
......@@ -848,3 +848,15 @@ pub fn allocPrintCmd(
848848 return aw.toOwnedSlice();
849849}
850850
851pub fn getInstallPath(b: *Build, dir: InstallDir, dest_rel_path: []const u8) []const u8 {
852 assert(!fs.path.isAbsolute(dest_rel_path)); // Install paths must be relative to the prefix
853 const base_dir = switch (dir) {
854 .prefix => b.install_path,
855 .bin => b.exe_dir,
856 .lib => b.lib_dir,
857 .header => b.h_dir,
858 .custom => |p| b.pathJoin(&.{ b.install_path, p }),
859 };
860 return b.pathResolve(&.{ base_dir, dest_rel_path });
861}
862
lib/compiler/maker/WebServer.zig+18-17
......@@ -1,3 +1,21 @@
1const WebServer = @This();
2
3const builtin = @import("builtin");
4
5const std = @import("std");
6const Allocator = std.mem.Allocator;
7const Build = std.Build;
8const Cache = std.Build.Cache;
9const Io = std.Io;
10const abi = std.Build.abi;
11const assert = std.debug.assert;
12const http = std.http;
13const log = std.log.scoped(.web_server);
14const mem = std.mem;
15const net = std.Io.net;
16
17const Fuzz = @import("Fuzz.zig");
18
119gpa: Allocator,
220graph: *const Build.Graph,
321all_steps: []const *Build.Step,
......@@ -907,20 +925,3 @@ const cache_control_header: http.Header = .{
907925 .name = "Cache-Control",
908926 .value = "max-age=0, must-revalidate",
909927};
910
911const builtin = @import("builtin");
912
913const std = @import("std");
914const Io = std.Io;
915const net = std.Io.net;
916const assert = std.debug.assert;
917const mem = std.mem;
918const log = std.log.scoped(.web_server);
919const Allocator = std.mem.Allocator;
920const Build = std.Build;
921const Cache = Build.Cache;
922const Fuzz = Build.Fuzz;
923const abi = Build.abi;
924const http = std.http;
925
926const WebServer = @This();
lib/std/Build.zig+3-21
......@@ -92,9 +92,8 @@ pub const Graph = struct {
9292 io: Io,
9393 /// Process lifetime.
9494 arena: Allocator,
95 system_library_options: std.StringArrayHashMapUnmanaged(SystemLibraryMode) = .empty,
95 system_integration_options: std.StringArrayHashMapUnmanaged(SystemLibraryMode) = .empty,
9696 system_package_mode: bool = false,
97 debug_compiler_runtime_libs: ?std.builtin.OptimizeMode = null,
9897 cache: Cache,
9998 zig_exe: []const u8,
10099 environ_map: process.Environ.Map,
......@@ -108,7 +107,7 @@ pub const Graph = struct {
108107 /// Steps should use `io` to limit the number of jobs, however in the case of
109108 /// a single step spawning a fixed number of processes this can be used.
110109 max_jobs: ?u32 = null,
111 time_report: bool,
110 time_report: bool = false,
112111 /// Similar to the `Io.Terminal.Mode` returned by `Io.lockStderr`, but also
113112 /// respects the '--color' flag.
114113 stderr_mode: ?Io.Terminal.Mode = null,
......@@ -322,11 +321,6 @@ fn createChild(
322321 .invalid_user_input = false,
323322 .default_step = undefined,
324323 .top_level_steps = .{},
325 .install_prefix = undefined,
326 .lib_dir = parent.lib_dir,
327 .exe_dir = parent.exe_dir,
328 .h_dir = parent.h_dir,
329 .install_path = parent.install_path,
330324 .sysroot = parent.sysroot,
331325 .build_root = build_root,
332326 .cache_root = parent.cache_root,
......@@ -1769,18 +1763,6 @@ pub fn run(b: *Build, argv: []const []const u8) []u8 {
17691763 );
17701764}
17711765
1772pub fn getInstallPath(b: *Build, dir: InstallDir, dest_rel_path: []const u8) []const u8 {
1773 assert(!fs.path.isAbsolute(dest_rel_path)); // Install paths must be relative to the prefix
1774 const base_dir = switch (dir) {
1775 .prefix => b.install_path,
1776 .bin => b.exe_dir,
1777 .lib => b.lib_dir,
1778 .header => b.h_dir,
1779 .custom => |p| b.pathJoin(&.{ b.install_path, p }),
1780 };
1781 return b.pathResolve(&.{ base_dir, dest_rel_path });
1782}
1783
17841766pub const Dependency = struct {
17851767 builder: *Build,
17861768
......@@ -2572,7 +2554,7 @@ pub fn systemIntegrationOption(
25722554 name: []const u8,
25732555 config: SystemIntegrationOptionConfig,
25742556) bool {
2575 const gop = b.graph.system_library_options.getOrPut(b.allocator, name) catch @panic("OOM");
2557 const gop = b.graph.system_integration_options.getOrPut(b.allocator, name) catch @panic("OOM");
25762558 if (gop.found_existing) switch (gop.value_ptr.*) {
25772559 .user_disabled => {
25782560 gop.value_ptr.* = .declared_disabled;
lib/std/zig/Configuration.zig+98-6
......@@ -11,7 +11,10 @@ steps: []Step,
1111path_deps_base: []Path.Base,
1212path_deps_sub: []String,
1313unlazy_deps: []String,
14system_integrations: []SystemIntegration,
15available_options: []AvailableOption,
1416extra: []u32,
17default_step: Step.Index,
1518
1619/// The field order here matches `Configuration` which documents the order in
1720/// the serialized format.
......@@ -20,6 +23,8 @@ pub const Header = extern struct {
2023 steps_len: u32,
2124 path_deps_len: u32,
2225 unlazy_deps_len: u32,
26 system_integrations_len: u32,
27 available_options_len: u32,
2328 extra_len: u32,
2429
2530 default_step: Step.Index,
......@@ -33,6 +38,8 @@ pub const Wip = struct {
3338
3439 string_bytes: std.ArrayList(u8) = .empty,
3540 unlazy_deps: std.ArrayList(String) = .empty,
41 system_integrations: std.ArrayList(SystemIntegration) = .empty,
42 available_options: std.ArrayList(AvailableOption) = .empty,
3643 steps: std.ArrayList(Step) = .empty,
3744 path_deps: std.MultiArrayList(Path) = .empty,
3845 extra: std.ArrayList(u32) = .empty,
......@@ -107,6 +114,8 @@ pub const Wip = struct {
107114 const gpa = wip.gpa;
108115 wip.string_bytes.deinit(gpa);
109116 wip.unlazy_deps.deinit(gpa);
117 wip.system_integrations.deinit(gpa);
118 wip.available_options.deinit(gpa);
110119 wip.steps.deinit(gpa);
111120 wip.path_deps.deinit(gpa);
112121 wip.extra.deinit(gpa);
......@@ -123,6 +132,8 @@ pub const Wip = struct {
123132 .steps_len = @intCast(wip.steps.items.len),
124133 .path_deps_len = @intCast(wip.path_deps.len),
125134 .unlazy_deps_len = @intCast(wip.unlazy_deps.items.len),
135 .system_integrations_len = @intCast(wip.system_integrations.items.len),
136 .available_options_len = @intCast(wip.available_options.items.len),
126137 .extra_len = @intCast(wip.extra.items.len),
127138
128139 .default_step = static.default_step,
......@@ -134,6 +145,8 @@ pub const Wip = struct {
134145 @ptrCast(wip.path_deps.items(.base)),
135146 @ptrCast(wip.path_deps.items(.sub)),
136147 @ptrCast(wip.unlazy_deps.items),
148 @ptrCast(wip.system_integrations.items),
149 @ptrCast(wip.available_options.items),
137150 @ptrCast(wip.extra.items),
138151 };
139152 try w.writeVecAll(&buffers);
......@@ -367,6 +380,37 @@ pub const Wip = struct {
367380 }
368381};
369382
383pub const SystemIntegration = extern struct {
384 name: String,
385 status: Status,
386
387 pub const Status = enum(u32) {
388 disabled = 0,
389 enabled = 1,
390 };
391};
392
393pub const AvailableOption = extern struct {
394 name: String,
395 description: String,
396 type: Type,
397 /// If the `type_id` is `enum` or `enum_list` this provides the list of enum options
398 enum_options: OptionalStringList,
399
400 pub const Type = enum(u8) {
401 bool,
402 int,
403 float,
404 @"enum",
405 enum_list,
406 string,
407 list,
408 build_id,
409 lazy_path,
410 lazy_path_list,
411 };
412};
413
370414pub const Step = extern struct {
371415 name: String,
372416 deps: Deps,
......@@ -375,8 +419,19 @@ pub const Step = extern struct {
375419 /// with `Tag`.
376420 extra_index: u32,
377421
422 /// Points into `steps`.
378423 pub const Index = enum(u32) {
379424 _,
425
426 pub fn ptr(i: Index, c: *const Configuration) *const Step {
427 return &c.steps[@intFromEnum(i)];
428 }
429 };
430
431 /// Shared by all steps.
432 pub const Flags = packed struct(u32) {
433 tag: Tag,
434 _: u27 = 0,
380435 };
381436
382437 pub const Tag = enum(u5) {
......@@ -400,7 +455,7 @@ pub const Step = extern struct {
400455 };
401456
402457 pub const TopLevel = struct {
403 flags: Flags = .{},
458 flags: @This().Flags = .{},
404459 description: String,
405460
406461 pub const Flags = packed struct(u32) {
......@@ -410,7 +465,7 @@ pub const Step = extern struct {
410465 };
411466
412467 pub const InstallArtifact = struct {
413 flags: Flags,
468 flags: @This().Flags,
414469
415470 dest_dir: InstallDir,
416471 dest_sub_path: String,
......@@ -445,7 +500,7 @@ pub const Step = extern struct {
445500 /// * stdio_limit: u64, // if stdio_limit is set
446501 /// * producer: Step.Index, // if producer is set. always compile step
447502 pub const Run = struct {
448 flags: Flags,
503 flags: @This().Flags,
449504 file_inputs_len: u32,
450505 args_len: u32,
451506 cwd: OptionalLazyPath,
......@@ -554,7 +609,7 @@ pub const Step = extern struct {
554609 /// * error_limit if flag is set
555610 /// * Hexstring if build_id is hexstring
556611 pub const Compile = struct {
557 flags: Flags,
612 flags: @This().Flags,
558613 flags2: Flags2,
559614 flags3: Flags3,
560615 flags4: Flags4,
......@@ -989,12 +1044,26 @@ pub const ImportTable = enum(u32) {
9891044 _,
9901045};
9911046
992/// Points into `extra`, where the first element is number of deps,
993/// following elements is `Step.Index` per dep.
1047/// Points into `extra`, where the first element is count of deps, following
1048/// elements is `Step.Index` per count.
9941049pub const Deps = enum(u32) {
9951050 _,
9961051};
9971052
1053/// Points into `extra`, where the first element is count of strings, following
1054/// elements is `String` per count.
1055///
1056/// Stored identically to `Deps`.
1057pub const OptionalStringList = enum(u32) {
1058 none = maxInt(u32),
1059 _,
1060
1061 pub fn slice(osl: OptionalStringList, c: *const Configuration) ?[]const String {
1062 const len = c.extra[@intFromEnum(osl)];
1063 return @ptrCast(c.extra[@intFromEnum(osl) + 1 ..][0..len]);
1064 }
1065};
1066
9981067pub const Path = extern struct {
9991068 base: Base,
10001069 sub: String,
......@@ -1444,6 +1513,23 @@ pub const TargetQuery = struct {
14441513 };
14451514};
14461515
1516pub fn extraData(c: *const Configuration, comptime T: type, index: usize) T {
1517 const extra = c.extra;
1518 var i: usize = index;
1519 var result: T = undefined;
1520 inline for (@typeInfo(T).@"struct".fields) |field| {
1521 comptime assert(@sizeOf(field.type) == @sizeOf(u32));
1522 @field(result, field.name) = switch (@typeInfo(field.type)) {
1523 .int => extra[i],
1524 .@"enum" => @enumFromInt(extra[i]),
1525 .@"struct" => @bitCast(extra[i]),
1526 else => comptime unreachable,
1527 };
1528 i += 1;
1529 }
1530 return result;
1531}
1532
14471533pub const LoadFileError = Io.File.Reader.Error || Allocator.Error || error{EndOfStream};
14481534
14491535pub fn loadFile(arena: Allocator, io: Io, file: Io.File) LoadFileError!Configuration {
......@@ -1465,7 +1551,10 @@ pub fn load(arena: Allocator, reader: *Io.Reader) LoadError!Configuration {
14651551 .path_deps_sub = try arena.alloc(String, header.path_deps_len),
14661552 .path_deps_base = try arena.alloc(Path.Base, header.path_deps_len),
14671553 .unlazy_deps = try arena.alloc(String, header.unlazy_deps_len),
1554 .system_integrations = try arena.alloc(SystemIntegration, header.system_integrations_len),
1555 .available_options = try arena.alloc(AvailableOption, header.available_options_len),
14681556 .extra = try arena.alloc(u32, header.extra_len),
1557 .default_step = header.default_step,
14691558 };
14701559 var vecs = [_][]u8{
14711560 result.string_bytes,
......@@ -1473,6 +1562,9 @@ pub fn load(arena: Allocator, reader: *Io.Reader) LoadError!Configuration {
14731562 @ptrCast(result.path_deps_base),
14741563 @ptrCast(result.path_deps_sub),
14751564 @ptrCast(result.unlazy_deps),
1565 @ptrCast(result.system_integrations),
1566 @ptrCast(result.available_options),
1567 @ptrCast(result.extra),
14761568 };
14771569 try reader.readVecAll(&vecs);
14781570 return result;
src/Compilation.zig+1-3
......@@ -3233,9 +3233,7 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) UpdateE
32333233 }
32343234
32353235 // Failure here only means an unnecessary cache miss.
3236 man.writeManifest() catch |err| {
3237 log.warn("failed to write cache manifest: {s}", .{@errorName(err)});
3238 };
3236 man.writeManifest() catch |err| log.warn("failed to write cache manifest: {t}", .{err});
32393237
32403238 assert(whole.lock == null);
32413239 whole.lock = man.toOwnedLock();
src/main.zig+32-31
......@@ -3682,26 +3682,16 @@ fn buildOutputType(
36823682 if (t.arch == target.cpu.arch and t.os == target.os.tag) {
36833683 // If there's a `glibc_min`, there's also an `os_ver`.
36843684 if (t.glibc_min) |glibc_min| {
3685 std.log.info("zig can provide libc for related target {s}-{s}.{f}-{s}.{d}.{d}", .{
3686 @tagName(t.arch),
3687 @tagName(t.os),
3688 t.os_ver.?,
3689 @tagName(t.abi),
3690 glibc_min.major,
3691 glibc_min.minor,
3685 std.log.info("zig can provide libc for related target {t}-{t}.{f}-{t}.{d}.{d}", .{
3686 t.arch, t.os, t.os_ver.?, t.abi, glibc_min.major, glibc_min.minor,
36923687 });
36933688 } else if (t.os_ver) |os_ver| {
3694 std.log.info("zig can provide libc for related target {s}-{s}.{f}-{s}", .{
3695 @tagName(t.arch),
3696 @tagName(t.os),
3697 os_ver,
3698 @tagName(t.abi),
3689 std.log.info("zig can provide libc for related target {t}-{t}.{f}-{t}", .{
3690 t.arch, t.os, os_ver, t.abi,
36993691 });
37003692 } else {
3701 std.log.info("zig can provide libc for related target {s}-{s}-{s}", .{
3702 @tagName(t.arch),
3703 @tagName(t.os),
3704 @tagName(t.abi),
3693 std.log.info("zig can provide libc for related target {t}-{t}-{t}", .{
3694 t.arch, t.os, t.abi,
37053695 });
37063696 }
37073697 }
......@@ -3710,7 +3700,7 @@ fn buildOutputType(
37103700 },
37113701 else => fatal("{f}", .{create_diag}),
37123702 },
3713 else => fatal("failed to create compilation: {s}", .{@errorName(err)}),
3703 else => fatal("failed to create compilation: {t}", .{err}),
37143704 };
37153705 var comp_destroyed = false;
37163706 defer if (!comp_destroyed) comp.destroy();
......@@ -4984,7 +4974,6 @@ fn cmdBuild(
49844974 try configure_argv.ensureUnusedCapacity(arena, 16);
49854975 try make_argv.ensureUnusedCapacity(arena, 16);
49864976
4987 const argv_index_exe = configure_argv.items.len;
49884977 _ = configure_argv.addOneAssumeCapacity();
49894978 _ = make_argv.addOneAssumeCapacity();
49904979
......@@ -5069,9 +5058,7 @@ fn cmdBuild(
50695058 } else if (mem.cutPrefix(u8, arg, "--fetch=")) |sub_arg| {
50705059 fetch_only = true;
50715060 fetch_mode = std.meta.stringToEnum(Package.Fetch.JobQueue.Mode, sub_arg) orelse
5072 fatal("expected [needed|all] after '--fetch=', found '{s}'", .{
5073 sub_arg,
5074 });
5061 fatal("expected [needed|all] after '--fetch=', found '{s}'", .{sub_arg});
50755062 } else if (mem.cutPrefix(u8, arg, "--fork=")) |sub_arg| {
50765063 try forks.append(arena, .{
50775064 .manifest_ast = undefined,
......@@ -5093,7 +5080,7 @@ fn cmdBuild(
50935080 continue;
50945081 } else if (mem.cutPrefix(u8, arg, "-freference-trace=")) |num| {
50955082 reference_trace = std.fmt.parseUnsigned(u32, num, 10) catch |err| {
5096 fatal("unable to parse reference_trace count '{s}': {s}", .{ num, @errorName(err) });
5083 fatal("unable to parse reference_trace count '{s}': {t}", .{ num, err });
50975084 };
50985085 } else if (mem.eql(u8, arg, "-fno-reference-trace")) {
50995086 reference_trace = null;
......@@ -5169,7 +5156,8 @@ fn cmdBuild(
51695156 } else if (mem.eql(u8, arg, "--")) {
51705157 // The rest of the args are supposed to get passed onto
51715158 // build runner's `build.args`
5172 try configure_argv.appendSlice(arena, args[i..]);
5159 try configure_argv.append(arena, "--have-run-args");
5160 try make_argv.appendSlice(arena, args[i..]);
51735161 break;
51745162 }
51755163 }
......@@ -5273,7 +5261,12 @@ fn cmdBuild(
52735261
52745262 // Kick off an optimized compilation of the make runner.
52755263 var make_runner_task = io.async(compileMakeRunner, .{ gpa, arena, io, .{
5276 .dirs = &dirs,
5264 .dirs = .{
5265 .cwd = dirs.cwd,
5266 .zig_lib = dirs.zig_lib,
5267 .global_cache = dirs.global_cache,
5268 .local_cache = dirs.global_cache,
5269 },
52775270 .environ_map = environ_map,
52785271 .parent_prog_node = root_prog_node,
52795272 .resolved_target = resolved_target,
......@@ -5281,6 +5274,7 @@ fn cmdBuild(
52815274 .thread_limit = thread_limit,
52825275 .self_exe_path = self_exe_path,
52835276 .color = color,
5277 .reference_trace = reference_trace,
52845278 } });
52855279 defer _ = make_runner_task.cancel(io) catch {};
52865280
......@@ -5289,6 +5283,11 @@ fn cmdBuild(
52895283 configure_argv.items[argv_index_global_cache_dir] = dirs.global_cache.path orelse cwd_path;
52905284 configure_argv.items[argv_index_cache_dir] = dirs.local_cache.path orelse cwd_path;
52915285
5286 make_argv.items[argv_index_zig_lib_dir] = dirs.zig_lib.path orelse cwd_path;
5287 make_argv.items[argv_index_build_file] = build_root.directory.path orelse cwd_path;
5288 make_argv.items[argv_index_global_cache_dir] = dirs.global_cache.path orelse cwd_path;
5289 make_argv.items[argv_index_cache_dir] = dirs.local_cache.path orelse cwd_path;
5290
52925291 // Dummy http client that is not actually used when fetch_command is unsupported.
52935292 // Prevents bootstrap from depending on a bunch of unnecessary stuff.
52945293 var http_client: if (dev.env.supports(.fetch_command)) std.http.Client else struct {
......@@ -5601,7 +5600,7 @@ fn cmdBuild(
56015600 .sub_path = try std.fmt.allocPrint(arena, "o/{s}/{s}", .{ hex_digest, comp.emit_bin.? }),
56025601 };
56035602 _ = try config_man.addFilePath(exe_path, null);
5604 configure_argv.items[argv_index_exe] = try exe_path.toString(arena);
5603 configure_argv.items[0] = try exe_path.toString(arena);
56055604
56065605 if (try config_man.hit()) {
56075606 const digest = config_man.final();
......@@ -5758,15 +5757,15 @@ fn cmdBuild(
57585757 }) {
57595758 .exited => |code| {
57605759 if (code == 0) return cleanExit(io);
5761 const cmd = try std.mem.join(arena, " ", configure_argv.items);
5760 const cmd = try std.mem.join(arena, " ", make_argv.items);
57625761 fatal("the following maker command failed with exit code {d}:\n{s}", .{ code, cmd });
57635762 },
57645763 .signal => |sig| {
5765 const cmd = try std.mem.join(arena, " ", configure_argv.items);
5764 const cmd = try std.mem.join(arena, " ", make_argv.items);
57665765 fatal("the following maker command terminated with signal {t}:\n{s}", .{ sig, cmd });
57675766 },
57685767 else => {
5769 const cmd = try std.mem.join(arena, " ", configure_argv.items);
5768 const cmd = try std.mem.join(arena, " ", make_argv.items);
57705769 fatal("the following maker command crashed:\n{s}", .{cmd});
57715770 },
57725771 }
......@@ -5777,13 +5776,14 @@ const MakeRunner = struct {
57775776
57785777 const Options = struct {
57795778 environ_map: *const process.Environ.Map,
5780 dirs: *Compilation.Directories,
5779 dirs: Compilation.Directories,
57815780 parent_prog_node: std.Progress.Node,
57825781 resolved_target: Package.Module.ResolvedTarget,
57835782 libc_installation: ?*const LibCInstallation,
57845783 self_exe_path: []const u8,
57855784 thread_limit: usize,
57865785 color: Color,
5786 reference_trace: ?u32,
57875787 };
57885788};
57895789
......@@ -5798,7 +5798,7 @@ fn compileMakeRunner(gpa: Allocator, arena: Allocator, io: Io, options: MakeRunn
57985798 const strip = optimize_mode != .Debug;
57995799
58005800 const main_mod_paths: Package.Module.CreateOptions.Paths = .{
5801 .root = try .fromRoot(arena, options.dirs.*, .zig_lib, "compiler"),
5801 .root = try .fromRoot(arena, options.dirs, .zig_lib, "compiler"),
58025802 .root_src_path = "maker.zig",
58035803 };
58045804
......@@ -5827,7 +5827,7 @@ fn compileMakeRunner(gpa: Allocator, arena: Allocator, io: Io, options: MakeRunn
58275827
58285828 var create_diag: Compilation.CreateDiagnostic = undefined;
58295829 const comp = Compilation.create(gpa, arena, io, &create_diag, .{
5830 .dirs = options.dirs.*,
5830 .dirs = options.dirs,
58315831 .root_name = "maker",
58325832 .config = config,
58335833 .root_mod = root_mod,
......@@ -5837,6 +5837,7 @@ fn compileMakeRunner(gpa: Allocator, arena: Allocator, io: Io, options: MakeRunn
58375837 .thread_limit = options.thread_limit,
58385838 .cache_mode = .whole,
58395839 .environ_map = options.environ_map,
5840 .reference_trace = options.reference_trace,
58405841 }) catch |err| switch (err) {
58415842 error.CreateFail => fatal("failed to create compilation: {f}", .{create_diag}),
58425843 error.Canceled => |e| return e,