authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-02-19 13:50:56-08:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-05-25 18:54:34-07:00
log959103c3fd544abe06f32b279a6ebd1a3cd1f61b
tree40cec1c748381e2065bdd765367b80a587f8588e
parent6b7ce1fa22b301ac06d3bfa0a8938546966f684c

Maker.Step.Compile: progress towards lowering zig args


9 files changed, 409 insertions(+), 575 deletions(-)

lib/compiler/Maker.zig+48-41
......@@ -124,7 +124,6 @@ pub fn main(init: process.Init.Minimal) !void {
124124 graph.cache.hash.addBytes(builtin.zig_version_string);
125125
126126 var step_names: std.ArrayList([]const u8) = .empty;
127 var debug_log_scopes: std.ArrayList([]const u8) = .empty;
128127 var help_menu = false;
129128 var steps_menu = false;
130129 var print_configuration = false;
......@@ -143,10 +142,6 @@ pub fn main(init: process.Init.Minimal) !void {
143142 var fuzz: ?Fuzz.Mode = null;
144143 var debounce_interval_ms: u16 = 50;
145144 var webui_listen: ?Io.net.IpAddress = null;
146 var verbose = false;
147 var sysroot: ?[]const u8 = null;
148 var search_prefixes: std.ArrayList([]const u8) = .empty;
149 var libc_file: ?[]const u8 = null;
150145 var debug_pkg_config: bool = false;
151146 // After following the steps in https://codeberg.org/ziglang/infra/src/branch/master/libc-update/glibc.md,
152147 // this will be the directory $glibc-build-dir/install/glibcs
......@@ -159,7 +154,6 @@ pub fn main(init: process.Init.Minimal) !void {
159154 var enable_wasmtime = false;
160155 var enable_darling = false;
161156 var enable_rosetta = false;
162 var reference_trace: ?u32 = null;
163157 var run_args: ?[]const []const u8 = null;
164158
165159 if (std.zig.EnvVar.ZIG_BUILD_ERROR_STYLE.get(&graph.environ_map)) |str| {
......@@ -182,8 +176,6 @@ pub fn main(init: process.Init.Minimal) !void {
182176 steps_menu = true;
183177 } else if (mem.eql(u8, arg, "--print-configuration")) {
184178 print_configuration = true;
185 } else if (mem.eql(u8, arg, "--verbose")) {
186 verbose = true;
187179 } else if (mem.eql(u8, arg, "-p") or mem.eql(u8, arg, "--prefix")) {
188180 override_install_prefix = nextArgOrFatal(args, &arg_idx);
189181 } else if (mem.eql(u8, arg, "--prefix-lib-dir")) {
......@@ -193,11 +185,12 @@ pub fn main(init: process.Init.Minimal) !void {
193185 } else if (mem.eql(u8, arg, "--prefix-include-dir")) {
194186 override_include_dir = nextArgOrFatal(args, &arg_idx);
195187 } else if (mem.eql(u8, arg, "--sysroot")) {
196 sysroot = nextArgOrFatal(args, &arg_idx);
188 graph.sysroot = nextArgOrFatal(args, &arg_idx);
197189 } else if (mem.eql(u8, arg, "--maxrss")) {
190 // TODO refactor and reuse the fuzz number parsing here
198191 const max_rss_text = nextArgOrFatal(args, &arg_idx);
199192 max_rss = std.fmt.parseIntSizeSuffix(max_rss_text, 10) catch |err|
200 fatal("invalid byte size: '{s}': {t}", .{ max_rss_text, err });
193 fatal("invalid byte size {q}: {t}", .{ max_rss_text, err });
201194 } else if (mem.eql(u8, arg, "--skip-oom-steps")) {
202195 skip_oom_steps = true;
203196 } else if (mem.eql(u8, arg, "--test-timeout")) {
......@@ -217,7 +210,7 @@ pub fn main(init: process.Init.Minimal) !void {
217210 };
218211 const timeout_str = nextArgOrFatal(args, &arg_idx);
219212 const num_end_idx = std.mem.findLastNone(u8, timeout_str, "abcdefghijklmnopqrstuvwxyz") orelse fatal(
220 "invalid timeout '{s}': expected unit (ns, us, ms, s, m, h)",
213 "invalid timeout {q}: expected unit (ns, us, ms, s, m, h)",
221214 .{timeout_str},
222215 );
223216 const num_str = timeout_str[0 .. num_end_idx + 1];
......@@ -227,57 +220,63 @@ pub fn main(init: process.Init.Minimal) !void {
227220 break @floatFromInt(unit_and_factor[1]);
228221 }
229222 } else fatal(
230 "invalid timeout '{s}': invalid unit '{s}' (expected ns, us, ms, s, m, h)",
223 "invalid timeout {q}: invalid unit {q} (expected ns, us, ms, s, m, h)",
231224 .{ timeout_str, unit_str },
232225 );
233226 const num_parsed = std.fmt.parseFloat(f64, num_str) catch |err| fatal(
234 "invalid timeout '{s}': invalid number '{s}' ({t})",
227 "invalid timeout {q}: invalid number {q} ({t})",
235228 .{ timeout_str, num_str, err },
236229 );
237230 test_timeout_ns = std.math.lossyCast(u64, unit_factor * num_parsed);
238231 } else if (mem.eql(u8, arg, "--search-prefix")) {
239 try search_prefixes.append(arena, nextArgOrFatal(args, &arg_idx));
232 try graph.search_prefixes.append(arena, nextArgOrFatal(args, &arg_idx));
240233 } else if (mem.eql(u8, arg, "--libc")) {
241 libc_file = nextArgOrFatal(args, &arg_idx);
234 graph.libc_file = nextArgOrFatal(args, &arg_idx);
242235 } else if (mem.eql(u8, arg, "--color")) {
243236 const next_arg = nextArg(args, &arg_idx) orelse
244 fatalWithHint("expected [auto|on|off] after '{s}'", .{arg});
237 fatalWithHint("expected [auto|on|off] after {q}", .{arg});
245238 color = std.meta.stringToEnum(Color, next_arg) orelse {
246 fatalWithHint("expected [auto|on|off] after '{s}', found '{s}'", .{
239 fatalWithHint("expected [auto|on|off] after {q}, found {q}", .{
247240 arg, next_arg,
248241 });
249242 };
250243 } else if (mem.eql(u8, arg, "--error-style")) {
251244 const next_arg = nextArg(args, &arg_idx) orelse
252 fatalWithHint("expected style after '{s}'", .{arg});
245 fatalWithHint("expected style after {q}", .{arg});
253246 error_style = std.meta.stringToEnum(ErrorStyle, next_arg) orelse {
254 fatalWithHint("expected style after '{s}', found '{s}'", .{ arg, next_arg });
247 fatalWithHint("expected style after {q}, found {q}", .{ arg, next_arg });
255248 };
256249 } else if (mem.eql(u8, arg, "--multiline-errors")) {
257250 const next_arg = nextArg(args, &arg_idx) orelse
258 fatalWithHint("expected style after '{s}'", .{arg});
251 fatalWithHint("expected style after {q}", .{arg});
259252 multiline_errors = std.meta.stringToEnum(MultilineErrors, next_arg) orelse {
260 fatalWithHint("expected style after '{s}', found '{s}'", .{ arg, next_arg });
253 fatalWithHint("expected style after {q}, found {q}", .{ arg, next_arg });
261254 };
262255 } else if (mem.eql(u8, arg, "--summary")) {
263256 const next_arg = nextArg(args, &arg_idx) orelse
264 fatalWithHint("expected [all|new|failures|line|none] after '{s}'", .{arg});
257 fatalWithHint("expected [all|new|failures|line|none] after {q}", .{arg});
265258 summary = std.meta.stringToEnum(Summary, next_arg) orelse {
266 fatalWithHint("expected [all|new|failures|line|none] after '{s}', found '{s}'", .{
259 fatalWithHint("expected [all|new|failures|line|none] after {q}, found {q}", .{
267260 arg, next_arg,
268261 });
269262 };
270263 } else if (mem.eql(u8, arg, "--seed")) {
271264 const next_arg = nextArg(args, &arg_idx) orelse
272 fatalWithHint("expected u32 after '{s}'", .{arg});
265 fatalWithHint("expected u32 after {q}", .{arg});
273266 graph.random_seed = std.fmt.parseUnsigned(u32, next_arg, 0) catch |err| {
274 fatal("unable to parse seed '{s}' as unsigned 32-bit integer: {t}", .{ next_arg, err });
267 fatal("unable to parse seed {q} as unsigned 32-bit integer: {t}", .{ next_arg, err });
275268 };
269 } else if (mem.eql(u8, arg, "--build-id")) {
270 graph.build_id = .fast;
271 } else if (mem.cutPrefix(u8, arg, "--build-id=")) |style| {
272 graph.build_id = std.zig.BuildId.parse(style) catch |err|
273 fatal("unable to parse --build-id style {q}: {t}", .{ style, err });
276274 } else if (mem.eql(u8, arg, "--debounce")) {
275 // TODO refactor and reuse the timeout parsing code also here
277276 const next_arg = nextArg(args, &arg_idx) orelse
278 fatalWithHint("expected u16 after '{s}'", .{arg});
277 fatalWithHint("expected u16 after {q}", .{arg});
279278 debounce_interval_ms = std.fmt.parseUnsigned(u16, next_arg, 0) catch |err| {
280 fatal("unable to parse debounce interval '{s}' as unsigned 16-bit integer: {t}\n", .{
279 fatal("unable to parse debounce interval {q} as unsigned 16-bit integer: {t}", .{
281280 next_arg, err,
282281 });
283282 };
......@@ -287,11 +286,15 @@ pub fn main(init: process.Init.Minimal) !void {
287286 const addr_str = arg["--webui=".len..];
288287 if (std.mem.eql(u8, addr_str, "-")) fatal("web interface cannot listen on stdio", .{});
289288 webui_listen = Io.net.IpAddress.parseLiteral(addr_str) catch |err| {
290 fatal("invalid web UI address '{s}': {t}", .{ addr_str, err });
289 fatal("invalid web UI address {q}: {t}", .{ addr_str, err });
291290 };
292291 } else if (mem.eql(u8, arg, "--debug-log")) {
293292 const next_arg = nextArgOrFatal(args, &arg_idx);
294 try debug_log_scopes.append(arena, next_arg);
293 try graph.debug_log_scopes.append(arena, next_arg);
294 } else if (mem.eql(u8, arg, "--debug-compile-errors")) {
295 graph.debug_compile_errors = true;
296 } else if (mem.eql(u8, arg, "--debug-incremental")) {
297 graph.debug_incremental = true;
295298 } else if (mem.eql(u8, arg, "--debug-pkg-config")) {
296299 debug_pkg_config = true;
297300 } else if (mem.eql(u8, arg, "--debug-rt")) {
......@@ -302,6 +305,14 @@ pub fn main(init: process.Init.Minimal) !void {
302305 } else if (mem.eql(u8, arg, "--libc-runtimes") or mem.eql(u8, arg, "--glibc-runtimes")) {
303306 // --glibc-runtimes was the old name of the flag; kept for compatibility for now.
304307 libc_runtimes_dir = nextArgOrFatal(args, &arg_idx);
308 } else if (mem.eql(u8, arg, "--verbose")) {
309 graph.verbose = true;
310 } else if (mem.eql(u8, arg, "--verbose-air")) {
311 graph.verbose_air = true;
312 } else if (mem.eql(u8, arg, "--verbose-cc")) {
313 graph.verbose_cc = true;
314 } else if (mem.eql(u8, arg, "--verbose-llvm-ir")) {
315 graph.verbose_llvm_ir = true;
305316 } else if (mem.eql(u8, arg, "--watch")) {
306317 watch = true;
307318 } else if (mem.eql(u8, arg, "--time-report")) {
......@@ -373,18 +384,15 @@ pub fn main(init: process.Init.Minimal) !void {
373384 } else if (mem.eql(u8, arg, "-fno-allow-so-scripts")) {
374385 graph.allow_so_scripts = false;
375386 } else if (mem.eql(u8, arg, "-freference-trace")) {
376 reference_trace = 256;
377 } else if (mem.startsWith(u8, arg, "-freference-trace=")) {
378 const num = arg["-freference-trace=".len..];
379 reference_trace = std.fmt.parseUnsigned(u32, num, 10) catch |err| {
380 std.debug.print("unable to parse reference_trace count '{s}': {t}", .{ num, err });
381 process.exit(1);
382 };
387 graph.reference_trace = 256;
388 } else if (mem.cutPrefix(u8, arg, "-freference-trace=")) |num| {
389 graph.reference_trace = std.fmt.parseUnsigned(u32, num, 10) catch |err|
390 fatal("unable to parse reference_trace count {q}: {t}", .{ num, err });
383391 } else if (mem.eql(u8, arg, "-fno-reference-trace")) {
384 reference_trace = null;
392 graph.reference_trace = null;
385393 } else if (mem.cutPrefix(u8, arg, "-j")) |text| {
386394 const n = std.fmt.parseUnsigned(u32, text, 10) catch |err|
387 fatal("unable to parse jobs count '{s}': {t}", .{ text, err });
395 fatal("unable to parse jobs count {q}: {t}", .{ text, err });
388396 if (n < 1) fatal("number of jobs must be at least 1", .{});
389397 threaded.setAsyncLimit(.limited(n));
390398 graph.max_jobs = n;
......@@ -392,7 +400,7 @@ pub fn main(init: process.Init.Minimal) !void {
392400 run_args = argsRest(args, arg_idx);
393401 break;
394402 } else {
395 fatalWithHint("unrecognized argument: '{s}'", .{arg});
403 fatalWithHint("unrecognized argument: {s}", .{arg});
396404 }
397405 } else {
398406 try step_names.append(arena, arg);
......@@ -1848,8 +1856,7 @@ const ScannedConfig = struct {
18481856 \\ --debug-rt Debug compiler runtime libraries
18491857 \\ --verbose-link Enable compiler debug output for linking
18501858 \\ --verbose-air Enable compiler debug output for Zig AIR
1851 \\ --verbose-llvm-ir[=file] Enable compiler debug output for LLVM IR
1852 \\ --verbose-llvm-bc=[file] Enable compiler debug output for LLVM BC
1859 \\ --verbose-llvm-ir Enable compiler debug output for LLVM IR
18531860 \\ --verbose-cimport Enable compiler debug output for C imports
18541861 \\ --verbose-cc Enable compiler debug output for C compilation
18551862 \\ --verbose-llvm-cpu-features Enable compiler debug output for LLVM CPU features
lib/compiler/Maker/Graph.zig+20
......@@ -23,3 +23,23 @@ time_report: bool = false,
2323/// Similar to the `Io.Terminal.Mode` returned by `Io.lockStderr`, but also
2424/// respects the '--color' flag.
2525stderr_mode: ?Io.Terminal.Mode = null,
26reference_trace: ?u32 = null,
27debug_log_scopes: std.ArrayList([]const u8) = .empty,
28debug_compile_errors: bool = false,
29debug_incremental: bool = false,
30verbose: bool = false,
31verbose_air: bool = false,
32verbose_cc: bool = false,
33verbose_link: bool = false,
34verbose_llvm_cpu_features: bool = false,
35verbose_llvm_ir: bool = false,
36libc_file: ?[]const u8 = null,
37/// What does this do? Nobody bothered to document it, and I think it's a
38/// smelly option. So unless somebody deletes these passive aggressive comments
39/// and replaces them with actual documentation, I'm going to delete this
40/// option from the build system in a future release. In other words, this is
41/// deprecated due to lack of test coverage, lack of documentation, and a hunch
42/// that it's a bad option that should be avoided.
43sysroot: ?[]const u8 = null,
44search_prefixes: std.ArrayList([]const u8) = .empty,
45build_id: ?std.zig.BuildId = null,
lib/compiler/Maker/Step.zig+11-83
......@@ -298,7 +298,7 @@ pub fn captureChildProcess(
298298
299299 // If an error occurs, it's happened in this command:
300300 assert(s.result_failed_command == null);
301 s.result_failed_command = try allocPrintCmd(gpa, .inherit, null, argv);
301 s.result_failed_command = try std.zig.allocPrintCmd(gpa, .inherit, null, argv);
302302
303303 try handleChildProcUnsupported(s);
304304 try handleVerbose(s, .inherit, argv);
......@@ -354,15 +354,15 @@ pub fn evalZigProcess(
354354 argv: []const []const u8,
355355 prog_node: std.Progress.Node,
356356 watch: bool,
357 web_server: ?*WebServer,
358 gpa: Allocator,
357 maker: *Maker,
359358) !?Cache.Path {
359 const gpa = maker.gpa;
360360 const b = s.owner;
361361 const io = b.graph.io;
362362
363363 // If an error occurs, it's happened in this command:
364364 assert(s.result_failed_command == null);
365 s.result_failed_command = try allocPrintCmd(gpa, .inherit, null, argv);
365 s.result_failed_command = try std.zig.allocPrintCmd(gpa, .inherit, null, argv);
366366
367367 if (s.getZigProcess()) |zp| update: {
368368 assert(watch);
......@@ -374,7 +374,7 @@ pub fn evalZigProcess(
374374 zp.deinit(io);
375375 gpa.destroy(zp);
376376 } else zp.saveState(prog_node);
377 const result = zigProcessUpdate(s, zp, watch, web_server, gpa) catch |err| switch (err) {
377 const result = zigProcessUpdate(s, zp, watch, maker) catch |err| switch (err) {
378378 error.BrokenPipe, error.EndOfStream => |reason| {
379379 std.log.info("{s} restart required: {t}", .{ argv[0], reason });
380380 // Process restart required.
......@@ -431,7 +431,7 @@ pub fn evalZigProcess(
431431
432432 const result = result: {
433433 defer if (watch) zp.saveState(prog_node);
434 break :result try zigProcessUpdate(s, zp, watch, web_server, gpa);
434 break :result try zigProcessUpdate(s, zp, watch, maker);
435435 };
436436
437437 if (!watch) {
......@@ -485,7 +485,8 @@ pub fn installDir(s: *Step, dest_path: []const u8) !Io.Dir.CreatePathStatus {
485485 return s.fail("unable to create dir '{s}': {t}", .{ dest_path, err });
486486}
487487
488fn zigProcessUpdate(s: *Step, zp: *ZigProcess, watch: bool, web_server: ?*WebServer, gpa: Allocator) !?Path {
488fn zigProcessUpdate(s: *Step, zp: *ZigProcess, watch: bool, maker: *Maker) !?Path {
489 const gpa = maker.gpa;
489490 const b = s.owner;
490491 const arena = b.allocator;
491492 const io = b.graph.io;
......@@ -586,7 +587,7 @@ fn zigProcessUpdate(s: *Step, zp: *ZigProcess, watch: bool, web_server: ?*WebSer
586587 }
587588 }
588589 },
589 .time_report => if (web_server) |ws| {
590 .time_report => if (maker.web_server) |ws| {
590591 const TimeReport = std.zig.Server.Message.TimeReport;
591592 const tr: *align(1) const TimeReport = @ptrCast(body[0..@sizeOf(TimeReport)]);
592593 ws.updateTimeReportCompile(.{
......@@ -641,11 +642,11 @@ pub fn handleVerbose(
641642 opt_env: ?*const std.process.Environ.Map,
642643 argv: []const []const u8,
643644) error{OutOfMemory}!void {
644 if (!s.verbose) return;
645645 const graph = s.graph;
646 if (!graph.verbose) return;
646647 // Intention of verbose is to print all sub-process command lines to
647648 // stderr before spawning them.
648 const text = try allocPrintCmd(arena, cwd, if (opt_env) |env| .{
649 const text = try std.zig.allocPrintCmd(arena, cwd, if (opt_env) |env| .{
649650 .child = env,
650651 .parent = &graph.environ_map,
651652 } else null, argv);
......@@ -835,79 +836,6 @@ fn addWatchInputFromPath(step: *Step, path: Cache.Path, basename: []const u8) !v
835836 try gop.value_ptr.append(gpa, basename);
836837}
837838
838pub fn allocPrintCmd(
839 gpa: Allocator,
840 cwd: std.process.Child.Cwd,
841 opt_env: ?struct {
842 child: *const std.process.Environ.Map,
843 parent: *const std.process.Environ.Map,
844 },
845 argv: []const []const u8,
846) Allocator.Error![]u8 {
847 const shell = struct {
848 fn escape(writer: *Io.Writer, string: []const u8, is_argv0: bool) !void {
849 for (string) |c| {
850 if (switch (c) {
851 else => true,
852 '%', '+'...':', '@'...'Z', '_', 'a'...'z' => false,
853 '=' => is_argv0,
854 }) break;
855 } else return writer.writeAll(string);
856
857 try writer.writeByte('"');
858 for (string) |c| {
859 if (switch (c) {
860 std.ascii.control_code.nul => break,
861 '!', '"', '$', '\\', '`' => true,
862 else => !std.ascii.isPrint(c),
863 }) try writer.writeByte('\\');
864 switch (c) {
865 std.ascii.control_code.nul => unreachable,
866 std.ascii.control_code.bel => try writer.writeByte('a'),
867 std.ascii.control_code.bs => try writer.writeByte('b'),
868 std.ascii.control_code.ht => try writer.writeByte('t'),
869 std.ascii.control_code.lf => try writer.writeByte('n'),
870 std.ascii.control_code.vt => try writer.writeByte('v'),
871 std.ascii.control_code.ff => try writer.writeByte('f'),
872 std.ascii.control_code.cr => try writer.writeByte('r'),
873 std.ascii.control_code.esc => try writer.writeByte('E'),
874 ' '...'~' => try writer.writeByte(c),
875 else => try writer.print("{o:0>3}", .{c}),
876 }
877 }
878 try writer.writeByte('"');
879 }
880 };
881
882 var aw: Io.Writer.Allocating = .init(gpa);
883 defer aw.deinit();
884 const writer = &aw.writer;
885 switch (cwd) {
886 .inherit => {},
887 .path => |path| writer.print("cd {s} && ", .{path}) catch return error.OutOfMemory,
888 .dir => @panic("TODO"),
889 }
890 if (opt_env) |env| {
891 var it = env.child.iterator();
892 while (it.next()) |entry| {
893 const key = entry.key_ptr.*;
894 const value = entry.value_ptr.*;
895 if (env.parent.get(key)) |process_value| {
896 if (std.mem.eql(u8, value, process_value)) continue;
897 }
898 writer.print("{s}=", .{key}) catch return error.OutOfMemory;
899 shell.escape(writer, value, false) catch return error.OutOfMemory;
900 writer.writeByte(' ') catch return error.OutOfMemory;
901 }
902 }
903 shell.escape(writer, argv[0], true) catch return error.OutOfMemory;
904 for (argv[1..]) |arg| {
905 writer.writeByte(' ') catch return error.OutOfMemory;
906 shell.escape(writer, arg, false) catch return error.OutOfMemory;
907 }
908 return aw.toOwnedSlice();
909}
910
911839fn oomWrap(s: *Step, result: error{OutOfMemory}!void) void {
912840 result catch {
913841 s.result_oom = true;
lib/compiler/Maker/Step/Compile.zig+232-259
......@@ -10,6 +10,7 @@ const Io = std.Io;
1010const Sha256 = std.crypto.hash.sha2.Sha256;
1111const assert = std.debug.assert;
1212const mem = std.mem;
13const allocPrint = std.fmt.allocPrint;
1314
1415const Step = @import("../Step.zig");
1516const Maker = @import("../../Maker.zig");
......@@ -17,6 +18,8 @@ const Maker = @import("../../Maker.zig");
1718/// Populated during the make phase when there is a long-lived compiler process.
1819/// Managed by the build runner, not user build script.
1920zig_process: ?*Step.ZigProcess = null,
21/// Persisted to reuse memory on subsequent make.
22zig_args: std.ArrayList([]const u8) = .empty,
2023
2124pub fn make(
2225 compile: *Compile,
......@@ -24,14 +27,15 @@ pub fn make(
2427 maker: *Maker,
2528 progress_node: std.Progress.Node,
2629) Step.ExtendedMakeError!void {
27 if (true) @panic("TODO implement compile.make()");
2830 const graph = maker.graph;
2931 const step = maker.stepByIndex(step_index);
30 const zig_args = try getZigArgs(compile, maker, false);
32 compile.zig_args.clearRetainingCapacity();
33 if (true) @panic("TODO implement compile.make()");
34 try lowerZigArgs(compile, step_index, maker, &compile.zig_args, false);
3135 const process_arena = graph.arena; // TODO don't leak into the process_arena
3236
3337 const maybe_output_dir = step.evalZigProcess(
34 zig_args,
38 compile.zig_args.items,
3539 progress_node,
3640 (graph.incremental == true) and (maker.watch or maker.web_server != null),
3741 maker,
......@@ -47,7 +51,7 @@ pub fn make(
4751 // Update generated files
4852 if (maybe_output_dir) |output_dir| {
4953 if (compile.emit_directory) |lp| {
50 lp.path = try std.fmt.allocPrint(process_arena, "{f}", .{output_dir});
54 lp.path = try allocPrint(process_arena, "{f}", .{output_dir});
5155 }
5256
5357 // zig fmt: off
......@@ -70,23 +74,26 @@ pub fn make(
7074 {
7175 try doAtomicSymLinks(
7276 step,
73 compile.getEmittedBin().getPath2(step.owner, step),
77 compile.getEmittedBin().getPath2(step),
7478 compile.major_only_filename.?,
7579 compile.name_only_filename.?,
7680 );
7781 }
7882}
7983
80fn getZigArgs(compile: *Compile, maker: *Maker, fuzz: bool) ![][]const u8 {
81 const step = &compile.step;
82 const b = step.owner;
84fn lowerZigArgs(
85 compile: *Compile,
86 step_index: Configuration.Step.Index,
87 maker: *Maker,
88 zig_args: *std.ArrayList([]const u8),
89 fuzz: bool,
90) Allocator.Error!void {
91 const step = maker.stepByIndex(step_index);
8392 const graph = maker.graph;
8493 const arena = graph.arena; // TODO don't leak into the process arena
94 const gpa = maker.gpa;
8595
86 var zig_args = std.array_list.Managed([]const u8).init(arena);
87 defer zig_args.deinit();
88
89 try zig_args.append(graph.zig_exe);
96 try zig_args.append(gpa, graph.zig_exe);
9097
9198 const cmd = switch (compile.kind) {
9299 .lib => "build-lib",
......@@ -95,10 +102,10 @@ fn getZigArgs(compile: *Compile, maker: *Maker, fuzz: bool) ![][]const u8 {
95102 .@"test" => "test",
96103 .test_obj => "test-obj",
97104 };
98 try zig_args.append(cmd);
105 try zig_args.append(gpa, cmd);
99106
100 if (b.reference_trace) |some| {
101 try zig_args.append(try std.fmt.allocPrint(arena, "-freference-trace={d}", .{some}));
107 if (graph.reference_trace) |some| {
108 try zig_args.append(gpa, try allocPrint(arena, "-freference-trace={d}", .{some}));
102109 }
103110 try addFlag(&zig_args, "allow-so-scripts", compile.allow_so_scripts orelse graph.allow_so_scripts);
104111
......@@ -107,33 +114,31 @@ fn getZigArgs(compile: *Compile, maker: *Maker, fuzz: bool) ![][]const u8 {
107114 try addFlag(&zig_args, "new-linker", compile.use_new_linker);
108115
109116 if (compile.root_module.resolved_target.?.query.ofmt) |ofmt| {
110 try zig_args.append(try std.fmt.allocPrint(arena, "-ofmt={s}", .{@tagName(ofmt)}));
117 try zig_args.append(gpa, try allocPrint(arena, "-ofmt={t}", .{ofmt}));
111118 }
112119
113120 switch (compile.entry) {
114121 .default => {},
115 .disabled => try zig_args.append("-fno-entry"),
116 .enabled => try zig_args.append("-fentry"),
122 .disabled => try zig_args.append(gpa, "-fno-entry"),
123 .enabled => try zig_args.append(gpa, "-fentry"),
117124 .symbol_name => |entry_name| {
118 try zig_args.append(try std.fmt.allocPrint(arena, "-fentry={s}", .{entry_name}));
125 try zig_args.append(gpa, try allocPrint(arena, "-fentry={s}", .{entry_name}));
119126 },
120127 }
121128
122129 {
123130 for (compile.force_undefined_symbols.keys()) |symbol_name| {
124 try zig_args.append("--force_undefined");
125 try zig_args.append(symbol_name.*);
131 try zig_args.append(gpa, "--force_undefined");
132 try zig_args.append(gpa, symbol_name.*);
126133 }
127134 }
128135
129136 if (compile.stack_size) |stack_size| {
130 try zig_args.append("--stack");
131 try zig_args.append(try std.fmt.allocPrint(arena, "{}", .{stack_size}));
137 try zig_args.append(gpa, "--stack");
138 try zig_args.append(gpa, try allocPrint(arena, "{}", .{stack_size}));
132139 }
133140
134 if (fuzz) {
135 try zig_args.append("-ffuzz");
136 }
141 try addBool(gpa, zig_args, fuzz, "-ffuzz");
137142
138143 {
139144 // Stores system libraries that have already been seen for at least one
......@@ -183,14 +188,14 @@ fn getZigArgs(compile: *Compile, maker: *Maker, fuzz: bool) ![][]const u8 {
183188 switch (link_object) {
184189 .static_path => |static_path| {
185190 if (my_responsibility) {
186 try zig_args.append(static_path.getPath2(mod.owner, step));
191 try zig_args.append(gpa, static_path.getPath2(step));
187192 total_linker_objects += 1;
188193 }
189194 },
190195 .system_lib => |system_lib| {
191196 const system_lib_gop = try seen_system_libs.getOrPut(arena, system_lib.name);
192197 if (system_lib_gop.found_existing) {
193 try zig_args.appendSlice(system_lib_gop.value_ptr.*);
198 try zig_args.appendSlice(gpa, system_lib_gop.value_ptr.*);
194199 continue;
195200 } else {
196201 system_lib_gop.value_ptr.* = &.{};
......@@ -205,16 +210,16 @@ fn getZigArgs(compile: *Compile, maker: *Maker, fuzz: bool) ![][]const u8 {
205210 {
206211 switch (system_lib.search_strategy) {
207212 .no_fallback => switch (system_lib.preferred_link_mode) {
208 .dynamic => try zig_args.append("-search_dylibs_only"),
209 .static => try zig_args.append("-search_static_only"),
213 .dynamic => try zig_args.append(gpa, "-search_dylibs_only"),
214 .static => try zig_args.append(gpa, "-search_static_only"),
210215 },
211216 .paths_first => switch (system_lib.preferred_link_mode) {
212 .dynamic => try zig_args.append("-search_paths_first"),
213 .static => try zig_args.append("-search_paths_first_static"),
217 .dynamic => try zig_args.append(gpa, "-search_paths_first"),
218 .static => try zig_args.append(gpa, "-search_paths_first_static"),
214219 },
215220 .mode_first => switch (system_lib.preferred_link_mode) {
216 .dynamic => try zig_args.append("-search_dylibs_first"),
217 .static => try zig_args.append("-search_static_first"),
221 .dynamic => try zig_args.append(gpa, "-search_dylibs_first"),
222 .static => try zig_args.append(gpa, "-search_static_first"),
218223 },
219224 }
220225 prev_search_strategy = system_lib.search_strategy;
......@@ -227,11 +232,11 @@ fn getZigArgs(compile: *Compile, maker: *Maker, fuzz: bool) ![][]const u8 {
227232 break :prefix "-l";
228233 };
229234 switch (system_lib.use_pkg_config) {
230 .no => try zig_args.append(b.fmt("{s}{s}", .{ prefix, system_lib.name })),
235 .no => try zig_args.append(gpa, try allocPrint(arena, "{s}{s}", .{ prefix, system_lib.name })),
231236 .yes, .force => {
232237 if (compile.runPkgConfig(maker, system_lib.name)) |result| {
233 try zig_args.appendSlice(result.cflags);
234 try zig_args.appendSlice(result.libs);
238 try zig_args.appendSlice(gpa, result.cflags);
239 try zig_args.appendSlice(gpa, result.libs);
235240 try seen_system_libs.put(arena, system_lib.name, result.cflags);
236241 } else |err| switch (err) {
237242 error.PkgConfigInvalidOutput,
......@@ -243,7 +248,7 @@ fn getZigArgs(compile: *Compile, maker: *Maker, fuzz: bool) ![][]const u8 {
243248 .yes => {
244249 // pkg-config failed, so fall back to linking the library
245250 // by name directly.
246 try zig_args.append(b.fmt("{s}{s}", .{
251 try zig_args.append(gpa, try allocPrint(arena, "{s}{s}", .{
247252 prefix,
248253 system_lib.name,
249254 }));
......@@ -267,7 +272,7 @@ fn getZigArgs(compile: *Compile, maker: *Maker, fuzz: bool) ![][]const u8 {
267272 const included_in_lib_or_obj = !my_responsibility and
268273 (dep_compile.kind == .lib or dep_compile.kind == .obj or dep_compile.kind == .test_obj);
269274 if (!already_linked and !included_in_lib_or_obj) {
270 try zig_args.append(other.getEmittedBin().getPath2(b, step));
275 try zig_args.append(gpa, other.getEmittedBin().getPath2(step));
271276 total_linker_objects += 1;
272277 }
273278 },
......@@ -288,15 +293,15 @@ fn getZigArgs(compile: *Compile, maker: *Maker, fuzz: bool) ![][]const u8 {
288293 else
289294 try other.getGeneratedFilePath("generated_bin", &compile.step);
290295
291 try zig_args.append(full_path_lib);
296 try zig_args.append(gpa, full_path_lib);
292297 total_linker_objects += 1;
293298
294299 if (other.linkage == .dynamic and
295300 compile.rootModuleTarget().os.tag != .windows)
296301 {
297302 if (Dir.path.dirname(full_path_lib)) |dirname| {
298 try zig_args.append("-rpath");
299 try zig_args.append(dirname);
303 try zig_args.append(gpa, "-rpath");
304 try zig_args.append(gpa, dirname);
300305 }
301306 }
302307 },
......@@ -306,11 +311,11 @@ fn getZigArgs(compile: *Compile, maker: *Maker, fuzz: bool) ![][]const u8 {
306311 if (!my_responsibility) break :l;
307312
308313 if (prev_has_cflags) {
309 try zig_args.append("-cflags");
310 try zig_args.append("--");
314 try zig_args.append(gpa, "-cflags");
315 try zig_args.append(gpa, "--");
311316 prev_has_cflags = false;
312317 }
313 try zig_args.append(asm_file.getPath2(mod.owner, step));
318 try zig_args.append(gpa, asm_file.getPath2(mod.owner, step));
314319 total_linker_objects += 1;
315320 },
316321
......@@ -318,24 +323,24 @@ fn getZigArgs(compile: *Compile, maker: *Maker, fuzz: bool) ![][]const u8 {
318323 if (!my_responsibility) break :l;
319324
320325 if (prev_has_cflags or c_source_file.flags.len != 0) {
321 try zig_args.append("-cflags");
326 try zig_args.append(gpa, "-cflags");
322327 for (c_source_file.flags) |arg| {
323 try zig_args.append(arg);
328 try zig_args.append(gpa, arg);
324329 }
325 try zig_args.append("--");
330 try zig_args.append(gpa, "--");
326331 }
327332 prev_has_cflags = (c_source_file.flags.len != 0);
328333
329334 if (c_source_file.language) |lang| {
330 try zig_args.append("-x");
331 try zig_args.append(lang.internalIdentifier());
335 try zig_args.append(gpa, "-x");
336 try zig_args.append(gpa, lang.internalIdentifier());
332337 }
333338
334 try zig_args.append(c_source_file.file.getPath2(mod.owner, step));
339 try zig_args.append(gpa, c_source_file.file.getPath2(mod.owner, step));
335340
336341 if (c_source_file.language != null) {
337 try zig_args.append("-x");
338 try zig_args.append("none");
342 try zig_args.append(gpa, "-x");
343 try zig_args.append(gpa, "none");
339344 }
340345 total_linker_objects += 1;
341346 },
......@@ -344,27 +349,27 @@ fn getZigArgs(compile: *Compile, maker: *Maker, fuzz: bool) ![][]const u8 {
344349 if (!my_responsibility) break :l;
345350
346351 if (prev_has_cflags or c_source_files.flags.len != 0) {
347 try zig_args.append("-cflags");
352 try zig_args.append(gpa, "-cflags");
348353 for (c_source_files.flags) |arg| {
349 try zig_args.append(arg);
354 try zig_args.append(gpa, arg);
350355 }
351 try zig_args.append("--");
356 try zig_args.append(gpa, "--");
352357 }
353358 prev_has_cflags = (c_source_files.flags.len != 0);
354359
355360 if (c_source_files.language) |lang| {
356 try zig_args.append("-x");
357 try zig_args.append(lang.internalIdentifier());
361 try zig_args.append(gpa, "-x");
362 try zig_args.append(gpa, lang.internalIdentifier());
358363 }
359364
360365 const root_path = c_source_files.root.getPath2(mod.owner, step);
361366 for (c_source_files.files) |file| {
362 try zig_args.append(b.pathJoin(&.{ root_path, file }));
367 try zig_args.append(gpa, try Dir.path.join(arena, &.{ root_path, file }));
363368 }
364369
365370 if (c_source_files.language != null) {
366 try zig_args.append("-x");
367 try zig_args.append("none");
371 try zig_args.append(gpa, "-x");
372 try zig_args.append(gpa, "none");
368373 }
369374
370375 total_linker_objects += c_source_files.files.len;
......@@ -375,23 +380,23 @@ fn getZigArgs(compile: *Compile, maker: *Maker, fuzz: bool) ![][]const u8 {
375380
376381 if (rc_source_file.flags.len == 0 and rc_source_file.include_paths.len == 0) {
377382 if (prev_has_rcflags) {
378 try zig_args.append("-rcflags");
379 try zig_args.append("--");
383 try zig_args.append(gpa, "-rcflags");
384 try zig_args.append(gpa, "--");
380385 prev_has_rcflags = false;
381386 }
382387 } else {
383 try zig_args.append("-rcflags");
388 try zig_args.append(gpa, "-rcflags");
384389 for (rc_source_file.flags) |arg| {
385 try zig_args.append(arg);
390 try zig_args.append(gpa, arg);
386391 }
387392 for (rc_source_file.include_paths) |include_path| {
388 try zig_args.append("/I");
389 try zig_args.append(include_path.getPath2(mod.owner, step));
393 try zig_args.append(gpa, "/I");
394 try zig_args.append(gpa, include_path.getPath2(mod.owner, step));
390395 }
391 try zig_args.append("--");
396 try zig_args.append(gpa, "--");
392397 prev_has_rcflags = true;
393398 }
394 try zig_args.append(rc_source_file.file.getPath2(mod.owner, step));
399 try zig_args.append(gpa, rc_source_file.file.getPath2(mod.owner, step));
395400 total_linker_objects += 1;
396401 },
397402 }
......@@ -414,7 +419,7 @@ fn getZigArgs(compile: *Compile, maker: *Maker, fuzz: bool) ![][]const u8 {
414419 if (std.mem.eql(u8, import_cli_name, name)) {
415420 zig_args.appendAssumeCapacity(import_cli_name);
416421 } else {
417 zig_args.appendAssumeCapacity(b.fmt("{s}={s}", .{ name, import_cli_name }));
422 zig_args.appendAssumeCapacity(try allocPrint(arena, "{s}={s}", .{ name, import_cli_name }));
418423 }
419424 }
420425
......@@ -427,9 +432,9 @@ fn getZigArgs(compile: *Compile, maker: *Maker, fuzz: bool) ![][]const u8 {
427432 // files must have a module parent.
428433 if (mod.root_source_file) |lp| {
429434 const src = lp.getPath2(mod.owner, step);
430 try zig_args.append(b.fmt("-M{s}={s}", .{ module_cli_name, src }));
435 try zig_args.append(gpa, try allocPrint(arena, "-M{s}={s}", .{ module_cli_name, src }));
431436 } else if (moduleNeedsCliArg(mod)) {
432 try zig_args.append(b.fmt("-M{s}", .{module_cli_name}));
437 try zig_args.append(gpa, try allocPrint(arena, "-M{s}", .{module_cli_name}));
433438 }
434439 }
435440 }
......@@ -441,275 +446,248 @@ fn getZigArgs(compile: *Compile, maker: *Maker, fuzz: bool) ![][]const u8 {
441446
442447 for (frameworks.keys(), frameworks.values()) |name, info| {
443448 if (info.needed) {
444 try zig_args.append("-needed_framework");
449 try zig_args.append(gpa, "-needed_framework");
445450 } else if (info.weak) {
446 try zig_args.append("-weak_framework");
451 try zig_args.append(gpa, "-weak_framework");
447452 } else {
448 try zig_args.append("-framework");
453 try zig_args.append(gpa, "-framework");
449454 }
450 try zig_args.append(name);
455 try zig_args.append(gpa, name);
451456 }
452457
453458 if (compile.is_linking_libcpp) {
454 try zig_args.append("-lc++");
459 try zig_args.append(gpa, "-lc++");
455460 }
456461
457462 if (compile.is_linking_libc) {
458 try zig_args.append("-lc");
463 try zig_args.append(gpa, "-lc");
459464 }
460465 }
461466
462467 if (compile.win32_manifest) |manifest_file| {
463 try zig_args.append(manifest_file.getPath2(b, step));
468 try zig_args.append(gpa, manifest_file.getPath2(step));
464469 }
465470
466471 if (compile.win32_module_definition) |module_file| {
467 try zig_args.append(module_file.getPath2(b, step));
472 try zig_args.append(gpa, module_file.getPath2(step));
468473 }
469474
470475 if (compile.image_base) |image_base| {
471 try zig_args.append("--image-base");
472 try zig_args.append(b.fmt("0x{x}", .{image_base}));
476 try zig_args.appendSlice(gpa, &.{
477 "--image-base", try allocPrint(arena, "0x{x}", .{image_base}),
478 });
473479 }
474480
475481 for (compile.filters) |filter| {
476 try zig_args.append("--test-filter");
477 try zig_args.append(filter);
482 try zig_args.appendSlice(gpa, &.{ "--test-filter", filter });
478483 }
479484
480485 if (compile.test_runner) |test_runner| {
481 try zig_args.append("--test-runner");
482 try zig_args.append(test_runner.path.getPath2(b, step));
486 try zig_args.appendSlice(gpa, &.{ "--test-runner", test_runner.path.getPath2(step) });
483487 }
484488
485 for (b.debug_log_scopes) |log_scope| {
486 try zig_args.append("--debug-log");
487 try zig_args.append(log_scope);
489 for (graph.debug_log_scopes) |log_scope| {
490 try zig_args.appendSlice(gpa, &.{ "--debug-log", log_scope });
488491 }
489492
490 if (b.debug_compile_errors) {
491 try zig_args.append("--debug-compile-errors");
492 }
493 try addBool(gpa, zig_args, graph.debug_compile_errors, "--debug-compile-errors");
494 try addBool(gpa, zig_args, graph.debug_incremental, "--debug-incremental");
495 try addBool(gpa, zig_args, graph.verbose_air, "--verbose-air");
496 try addBool(gpa, zig_args, graph.verbose_llvm_ir, "--verbose-llvm-ir");
497 try addBool(gpa, zig_args, graph.verbose_link or compile.verbose_link, "--verbose-link");
498 try addBool(gpa, zig_args, graph.verbose_cc or compile.verbose_cc, "--verbose-cc");
499 try addBool(gpa, zig_args, graph.verbose_llvm_cpu_features, "--verbose-llvm-cpu-features");
500 try addBool(gpa, zig_args, graph.time_report, "--time-report");
493501
494 if (b.debug_incremental) {
495 try zig_args.append("--debug-incremental");
496 }
497
498 if (b.verbose_air) try zig_args.append("--verbose-air");
499 if (b.verbose_llvm_ir) |path| try zig_args.append(b.fmt("--verbose-llvm-ir={s}", .{path}));
500 if (b.verbose_llvm_bc) |path| try zig_args.append(b.fmt("--verbose-llvm-bc={s}", .{path}));
501 if (b.verbose_link or compile.verbose_link) try zig_args.append("--verbose-link");
502 if (b.verbose_cc or compile.verbose_cc) try zig_args.append("--verbose-cc");
503 if (b.verbose_llvm_cpu_features) try zig_args.append("--verbose-llvm-cpu-features");
504 if (graph.time_report) try zig_args.append("--time-report");
505
506 if (compile.generated_asm != null) try zig_args.append("-femit-asm");
507 if (compile.generated_bin == null) try zig_args.append("-fno-emit-bin");
508 if (compile.generated_docs != null) try zig_args.append("-femit-docs");
509 if (compile.generated_implib != null) try zig_args.append("-femit-implib");
510 if (compile.generated_llvm_bc != null) try zig_args.append("-femit-llvm-bc");
511 if (compile.generated_llvm_ir != null) try zig_args.append("-femit-llvm-ir");
512 if (compile.generated_h != null) try zig_args.append("-femit-h");
502 if (compile.generated_asm != null) try zig_args.append(gpa, "-femit-asm");
503 if (compile.generated_bin == null) try zig_args.append(gpa, "-fno-emit-bin");
504 if (compile.generated_docs != null) try zig_args.append(gpa, "-femit-docs");
505 if (compile.generated_implib != null) try zig_args.append(gpa, "-femit-implib");
506 if (compile.generated_llvm_bc != null) try zig_args.append(gpa, "-femit-llvm-bc");
507 if (compile.generated_llvm_ir != null) try zig_args.append(gpa, "-femit-llvm-ir");
508 if (compile.generated_h != null) try zig_args.append(gpa, "-femit-h");
513509
514510 try addFlag(&zig_args, "formatted-panics", compile.formatted_panics);
515511
516512 switch (compile.compress_debug_sections) {
517513 .none => {},
518 .zlib => try zig_args.append("--compress-debug-sections=zlib"),
519 .zstd => try zig_args.append("--compress-debug-sections=zstd"),
514 .zlib => try zig_args.append(gpa, "--compress-debug-sections=zlib"),
515 .zstd => try zig_args.append(gpa, "--compress-debug-sections=zstd"),
520516 }
521517
522518 if (compile.link_eh_frame_hdr) {
523 try zig_args.append("--eh-frame-hdr");
519 try zig_args.append(gpa, "--eh-frame-hdr");
524520 }
525521 if (compile.link_emit_relocs) {
526 try zig_args.append("--emit-relocs");
522 try zig_args.append(gpa, "--emit-relocs");
527523 }
528524 if (compile.link_function_sections) {
529 try zig_args.append("-ffunction-sections");
525 try zig_args.append(gpa, "-ffunction-sections");
530526 }
531527 if (compile.link_data_sections) {
532 try zig_args.append("-fdata-sections");
528 try zig_args.append(gpa, "-fdata-sections");
533529 }
534530 if (compile.link_gc_sections) |x| {
535 try zig_args.append(if (x) "--gc-sections" else "--no-gc-sections");
531 try zig_args.append(gpa, if (x) "--gc-sections" else "--no-gc-sections");
536532 }
537533 if (!compile.linker_dynamicbase) {
538 try zig_args.append("--no-dynamicbase");
534 try zig_args.append(gpa, "--no-dynamicbase");
539535 }
540536 if (compile.linker_allow_shlib_undefined) |x| {
541 try zig_args.append(if (x) "-fallow-shlib-undefined" else "-fno-allow-shlib-undefined");
542 }
543 if (compile.link_z_notext) {
544 try zig_args.append("-z");
545 try zig_args.append("notext");
546 }
547 if (!compile.link_z_relro) {
548 try zig_args.append("-z");
549 try zig_args.append("norelro");
550 }
551 if (compile.link_z_lazy) {
552 try zig_args.append("-z");
553 try zig_args.append("lazy");
554 }
555 if (compile.link_z_common_page_size) |size| {
556 try zig_args.append("-z");
557 try zig_args.append(b.fmt("common-page-size={d}", .{size}));
558 }
559 if (compile.link_z_max_page_size) |size| {
560 try zig_args.append("-z");
561 try zig_args.append(b.fmt("max-page-size={d}", .{size}));
562 }
563 if (compile.link_z_defs) {
564 try zig_args.append("-z");
565 try zig_args.append("defs");
566 }
537 try zig_args.append(gpa, if (x) "-fallow-shlib-undefined" else "-fno-allow-shlib-undefined");
538 }
539 if (compile.link_z_notext) try zig_args.appendSlice(gpa, &.{ "-z", "notext" });
540 if (!compile.link_z_relro) try zig_args.appendSlice(gpa, &.{ "-z", "norelro" });
541 if (compile.link_z_lazy) try zig_args.appendSlice(gpa, &.{ "-z", "lazy" });
542 if (compile.link_z_common_page_size) |size| try zig_args.appendSlice(gpa, &.{
543 "-z",
544 try allocPrint(arena, "common-page-size={d}", .{size}),
545 });
546 if (compile.link_z_max_page_size) |size| try zig_args.appendSlice(gpa, &.{
547 "-z",
548 try allocPrint(arena, "max-page-size={d}", .{size}),
549 });
550 if (compile.link_z_defs) try zig_args.appendSlice(gpa, &.{ "-z", "defs" });
567551
568552 if (compile.libc_file) |libc_file| {
569 try zig_args.append("--libc");
570 try zig_args.append(libc_file.getPath2(b, step));
571 } else if (b.libc_file) |libc_file| {
572 try zig_args.append("--libc");
573 try zig_args.append(libc_file);
553 try zig_args.appendSlice(gpa, &.{ "--libc", libc_file.getPath2(step) });
554 } else if (graph.libc_file) |libc_file| {
555 try zig_args.appendSlice(gpa, &.{ "--libc", libc_file });
574556 }
575557
576 try zig_args.append("--cache-dir");
577 try zig_args.append(b.cache_root.path orelse ".");
558 try zig_args.append(gpa, "--cache-dir");
559 try zig_args.append(gpa, graph.cache_root.path orelse ".");
578560
579 try zig_args.append("--global-cache-dir");
580 try zig_args.append(graph.global_cache_root.path orelse ".");
561 try zig_args.append(gpa, "--global-cache-dir");
562 try zig_args.append(gpa, graph.global_cache_root.path orelse ".");
581563
582564 if (graph.debug_compiler_runtime_libs) |mode|
583 try zig_args.append(b.fmt("--debug-rt={t}", .{mode}));
565 try zig_args.append(gpa, try allocPrint(arena, "--debug-rt={t}", .{mode}));
584566
585 try zig_args.append("--name");
586 try zig_args.append(compile.name);
567 try zig_args.append(gpa, "--name");
568 try zig_args.append(gpa, compile.name);
587569
588570 if (compile.linkage) |some| switch (some) {
589 .dynamic => try zig_args.append("-dynamic"),
590 .static => try zig_args.append("-static"),
571 .dynamic => try zig_args.append(gpa, "-dynamic"),
572 .static => try zig_args.append(gpa, "-static"),
591573 };
592574 if (compile.kind == .lib and compile.linkage != null and compile.linkage.? == .dynamic) {
593575 if (compile.version) |version| {
594 try zig_args.append("--version");
595 try zig_args.append(b.fmt("{f}", .{version}));
576 try zig_args.append(gpa, "--version");
577 try zig_args.append(gpa, try allocPrint(arena, "{f}", .{version}));
596578 }
597579
598580 if (compile.rootModuleTarget().os.tag.isDarwin()) {
599 const install_name = compile.install_name orelse b.fmt("@rpath/{s}{s}{s}", .{
581 const install_name = compile.install_name orelse try allocPrint(arena, "@rpath/{s}{s}{s}", .{
600582 compile.rootModuleTarget().libPrefix(),
601583 compile.name,
602584 compile.rootModuleTarget().dynamicLibSuffix(),
603585 });
604 try zig_args.append("-install_name");
605 try zig_args.append(install_name);
586 try zig_args.append(gpa, "-install_name");
587 try zig_args.append(gpa, install_name);
606588 }
607589 }
608590
609591 if (compile.entitlements) |entitlements| {
610 try zig_args.appendSlice(&[_][]const u8{ "--entitlements", entitlements });
592 try zig_args.appendSlice(gpa, &[_][]const u8{ "--entitlements", entitlements });
611593 }
612594 if (compile.pagezero_size) |pagezero_size| {
613 const size = try std.fmt.allocPrint(arena, "{x}", .{pagezero_size});
614 try zig_args.appendSlice(&[_][]const u8{ "-pagezero_size", size });
595 const size = try allocPrint(arena, "{x}", .{pagezero_size});
596 try zig_args.appendSlice(gpa, &[_][]const u8{ "-pagezero_size", size });
615597 }
616598 if (compile.headerpad_size) |headerpad_size| {
617 const size = try std.fmt.allocPrint(arena, "{x}", .{headerpad_size});
618 try zig_args.appendSlice(&[_][]const u8{ "-headerpad", size });
599 const size = try allocPrint(arena, "{x}", .{headerpad_size});
600 try zig_args.appendSlice(gpa, &[_][]const u8{ "-headerpad", size });
619601 }
620602 if (compile.headerpad_max_install_names) {
621 try zig_args.append("-headerpad_max_install_names");
603 try zig_args.append(gpa, "-headerpad_max_install_names");
622604 }
623605 if (compile.dead_strip_dylibs) {
624 try zig_args.append("-dead_strip_dylibs");
606 try zig_args.append(gpa, "-dead_strip_dylibs");
625607 }
626608 if (compile.force_load_objc) {
627 try zig_args.append("-ObjC");
609 try zig_args.append(gpa, "-ObjC");
628610 }
629611 if (compile.discard_local_symbols) {
630 try zig_args.append("--discard-all");
612 try zig_args.append(gpa, "--discard-all");
631613 }
632614
633615 try addFlag(&zig_args, "compiler-rt", compile.bundle_compiler_rt);
634616 try addFlag(&zig_args, "ubsan-rt", compile.bundle_ubsan_rt);
635617 try addFlag(&zig_args, "dll-export-fns", compile.dll_export_fns);
636618 if (compile.rdynamic) {
637 try zig_args.append("-rdynamic");
619 try zig_args.append(gpa, "-rdynamic");
638620 }
639621 if (compile.import_memory) {
640 try zig_args.append("--import-memory");
622 try zig_args.append(gpa, "--import-memory");
641623 }
642624 if (compile.export_memory) {
643 try zig_args.append("--export-memory");
625 try zig_args.append(gpa, "--export-memory");
644626 }
645627 if (compile.import_symbols) {
646 try zig_args.append("--import-symbols");
628 try zig_args.append(gpa, "--import-symbols");
647629 }
648630 if (compile.import_table) {
649 try zig_args.append("--import-table");
631 try zig_args.append(gpa, "--import-table");
650632 }
651633 if (compile.export_table) {
652 try zig_args.append("--export-table");
634 try zig_args.append(gpa, "--export-table");
653635 }
654636 if (compile.initial_memory) |initial_memory| {
655 try zig_args.append(b.fmt("--initial-memory={d}", .{initial_memory}));
637 try zig_args.append(gpa, try allocPrint(arena, "--initial-memory={d}", .{initial_memory}));
656638 }
657639 if (compile.max_memory) |max_memory| {
658 try zig_args.append(b.fmt("--max-memory={d}", .{max_memory}));
640 try zig_args.append(gpa, try allocPrint(arena, "--max-memory={d}", .{max_memory}));
659641 }
660642 if (compile.shared_memory) {
661 try zig_args.append("--shared-memory");
643 try zig_args.append(gpa, "--shared-memory");
662644 }
663645 if (compile.global_base) |global_base| {
664 try zig_args.append(b.fmt("--global-base={d}", .{global_base}));
646 try zig_args.append(gpa, try allocPrint(arena, "--global-base={d}", .{global_base}));
665647 }
666648
667649 if (compile.wasi_exec_model) |model| {
668 try zig_args.append(b.fmt("-mexec-model={s}", .{@tagName(model)}));
650 try zig_args.append(gpa, try allocPrint(arena, "-mexec-model={t}", .{model}));
669651 }
670652 if (compile.linker_script) |linker_script| {
671 try zig_args.append("--script");
672 try zig_args.append(linker_script.getPath2(b, step));
653 try zig_args.append(gpa, "--script");
654 try zig_args.append(gpa, linker_script.getPath2(step));
673655 }
674656
675657 if (compile.version_script) |version_script| {
676 try zig_args.append("--version-script");
677 try zig_args.append(version_script.getPath2(b, step));
658 try zig_args.append(gpa, "--version-script");
659 try zig_args.append(gpa, version_script.getPath2(step));
678660 }
679661 if (compile.linker_allow_undefined_version) |x| {
680 try zig_args.append(if (x) "--undefined-version" else "--no-undefined-version");
662 try zig_args.append(gpa, if (x) "--undefined-version" else "--no-undefined-version");
681663 }
682664
683665 if (compile.linker_enable_new_dtags) |enabled| {
684 try zig_args.append(if (enabled) "--enable-new-dtags" else "--disable-new-dtags");
666 try zig_args.append(gpa, if (enabled) "--enable-new-dtags" else "--disable-new-dtags");
685667 }
686668
687669 if (compile.kind == .@"test") {
688670 if (compile.exec_cmd_args) |exec_cmd_args| {
689671 for (exec_cmd_args) |cmd_arg| {
690672 if (cmd_arg) |arg| {
691 try zig_args.append("--test-cmd");
692 try zig_args.append(arg);
673 try zig_args.append(gpa, "--test-cmd");
674 try zig_args.append(gpa, arg);
693675 } else {
694 try zig_args.append("--test-cmd-bin");
676 try zig_args.append(gpa, "--test-cmd-bin");
695677 }
696678 }
697679 }
698680 }
699681
700 if (b.sysroot) |sysroot| {
701 try zig_args.appendSlice(&[_][]const u8{ "--sysroot", sysroot });
702 }
682 if (graph.sysroot) |sysroot| try zig_args.appendSlice(gpa, &.{ "--sysroot", sysroot });
703683
704684 // -I and -L arguments that appear after the last --mod argument apply to all modules.
705685 const cwd: Io.Dir = .cwd();
706686 const io = graph.io;
707687
708 for (b.search_prefixes.items) |search_prefix| {
688 for (graph.search_prefixes.items) |search_prefix| {
709689 var prefix_dir = cwd.openDir(io, search_prefix, .{}) catch |err| {
710 return step.fail("unable to open prefix directory '{s}': {s}", .{
711 search_prefix, @errorName(err),
712 });
690 return step.fail("unable to open prefix directory '{s}': {t}", .{ search_prefix, err });
713691 };
714692 defer prefix_dir.close(io);
715693
......@@ -718,58 +696,53 @@ fn getZigArgs(compile: *Compile, maker: *Maker, fuzz: bool) ![][]const u8 {
718696 // CLI parsing code, when the linker sees an -L directory that does not exist.
719697
720698 if (prefix_dir.access(io, "lib", .{})) |_| {
721 try zig_args.appendSlice(&.{
722 "-L", b.pathJoin(&.{ search_prefix, "lib" }),
699 try zig_args.appendSlice(gpa, &.{
700 "-L", try Dir.path.join(arena, &.{ search_prefix, "lib" }),
723701 });
724702 } else |err| switch (err) {
725703 error.FileNotFound => {},
726 else => |e| return step.fail("unable to access '{s}/lib' directory: {s}", .{
727 search_prefix, @errorName(e),
728 }),
704 else => |e| return step.fail("unable to access '{s}/lib' directory: {t}", .{ search_prefix, e }),
729705 }
730706
731707 if (prefix_dir.access(io, "include", .{})) |_| {
732 try zig_args.appendSlice(&.{
733 "-I", b.pathJoin(&.{ search_prefix, "include" }),
708 try zig_args.appendSlice(gpa, &.{
709 "-I", try Dir.path.join(arena, &.{ search_prefix, "include" }),
734710 });
735711 } else |err| switch (err) {
736712 error.FileNotFound => {},
737 else => |e| return step.fail("unable to access '{s}/include' directory: {s}", .{
738 search_prefix, @errorName(e),
739 }),
713 else => |e| return step.fail("unable to access '{s}/include' directory: {t}", .{ search_prefix, e }),
740714 }
741715 }
742716
743717 if (compile.rc_includes != .any) {
744 try zig_args.append("-rcincludes");
745 try zig_args.append(@tagName(compile.rc_includes));
718 try zig_args.appendSlice(gpa, &.{ "-rcincludes", @tagName(compile.rc_includes) });
746719 }
747720
748721 try addFlag(&zig_args, "each-lib-rpath", compile.each_lib_rpath);
749722
750 if (compile.build_id orelse b.build_id) |build_id| {
751 try zig_args.append(switch (build_id) {
752 .hexstring => |hs| b.fmt("--build-id=0x{x}", .{hs.toSlice()}),
753 .none, .fast, .uuid, .sha1, .md5 => b.fmt("--build-id={s}", .{@tagName(build_id)}),
723 if (compile.build_id orelse graph.build_id) |build_id| {
724 try zig_args.append(gpa, switch (build_id) {
725 .hexstring => |hs| try allocPrint(arena, "--build-id=0x{x}", .{hs.toSlice()}),
726 .none, .fast, .uuid, .sha1, .md5 => try allocPrint(arena, "--build-id={t}", .{build_id}),
754727 });
755728 }
756729
757730 const opt_zig_lib_dir = if (compile.zig_lib_dir) |dir|
758 dir.getPath2(b, step)
731 dir.getPath2(step)
759732 else if (graph.zig_lib_directory.path) |_|
760 b.fmt("{f}", .{graph.zig_lib_directory})
733 try allocPrint(arena, "{f}", .{graph.zig_lib_directory})
761734 else
762735 null;
763736
764737 if (opt_zig_lib_dir) |zig_lib_dir| {
765 try zig_args.append("--zig-lib-dir");
766 try zig_args.append(zig_lib_dir);
738 try zig_args.append(gpa, "--zig-lib-dir");
739 try zig_args.append(gpa, zig_lib_dir);
767740 }
768741
769742 try addFlag(&zig_args, "PIE", compile.pie);
770743
771744 if (compile.lto) |lto| {
772 try zig_args.append(switch (lto) {
745 try zig_args.append(gpa, switch (lto) {
773746 .full => "-flto=full",
774747 .thin => "-flto=thin",
775748 .none => "-fno-lto",
......@@ -779,21 +752,20 @@ fn getZigArgs(compile: *Compile, maker: *Maker, fuzz: bool) ![][]const u8 {
779752 try addFlag(&zig_args, "sanitize-coverage-trace-pc-guard", compile.sanitize_coverage_trace_pc_guard);
780753
781754 if (compile.subsystem) |subsystem| {
782 try zig_args.append("--subsystem");
783 try zig_args.append(@tagName(subsystem));
755 try zig_args.appendSlice(gpa, &.{ "--subsystem", @tagName(subsystem) });
784756 }
785757
786758 if (compile.mingw_unicode_entry_point) {
787 try zig_args.append("-municode");
759 try zig_args.append(gpa, "-municode");
788760 }
789761
790 if (compile.error_limit) |err_limit| try zig_args.appendSlice(&.{
791 "--error-limit", b.fmt("{d}", .{err_limit}),
762 if (compile.error_limit) |err_limit| try zig_args.appendSlice(gpa, &.{
763 "--error-limit", try allocPrint(arena, "{d}", .{err_limit}),
792764 });
793765
794766 try addFlag(&zig_args, "incremental", graph.incremental);
795767
796 try zig_args.append("--listen=-");
768 try zig_args.append(gpa, "--listen=-");
797769
798770 // Windows has an argument length limit of 32,766 characters, macOS 262,144 and Linux
799771 // 2,097,152. If our args exceed 30 KiB, we instead write them to a "response file" and
......@@ -804,7 +776,7 @@ fn getZigArgs(compile: *Compile, maker: *Maker, fuzz: bool) ![][]const u8 {
804776 args_length += arg.len + 1; // +1 to account for null terminator
805777 }
806778 if (args_length >= 30 * 1024) {
807 try b.cache_root.handle.createDirPath(io, "args");
779 try graph.cache_root.handle.createDirPath(io, "args");
808780
809781 const args_to_escape = zig_args.items[2..];
810782 var escaped_args = try std.array_list.Managed([]const u8).initCapacity(arena, args_to_escape.len);
......@@ -837,21 +809,21 @@ fn getZigArgs(compile: *Compile, maker: *Maker, fuzz: bool) ![][]const u8 {
837809 _ = try std.fmt.bufPrint(&args_hex_hash, "{x}", .{&args_hash});
838810
839811 const args_file = "args" ++ Dir.path.sep_str ++ args_hex_hash;
840 if (b.cache_root.handle.access(io, args_file, .{})) |_| {
812 if (graph.cache_root.handle.access(io, args_file, .{})) |_| {
841813 // The args file is already present from a previous run.
842814 } else |err| switch (err) {
843815 error.FileNotFound => {
844 var af = b.cache_root.handle.createFileAtomic(io, args_file, .{
816 var af = graph.cache_root.handle.createFileAtomic(io, args_file, .{
845817 .replace = false,
846818 .make_path = true,
847819 }) catch |e| return step.fail("failed creating tmp args file {f}{s}: {t}", .{
848 b.cache_root, args_file, e,
820 graph.cache_root, args_file, e,
849821 });
850822 defer af.deinit(io);
851823
852824 af.file.writeStreamingAll(io, args) catch |e| {
853825 return step.fail("failed writing args data to tmp file {f}{s}: {t}", .{
854 b.cache_root, args_file, e,
826 graph.cache_root, args_file, e,
855827 });
856828 };
857829 // Note we can't clean up this file, not even after build
......@@ -862,7 +834,7 @@ fn getZigArgs(compile: *Compile, maker: *Maker, fuzz: bool) ![][]const u8 {
862834 // The args file was created by another concurrent build process.
863835 },
864836 else => |other_err| return step.fail("failed linking tmp file {f}{s}: {t}", .{
865 b.cache_root, args_file, other_err,
837 graph.cache_root, args_file, other_err,
866838 }),
867839 };
868840 },
......@@ -871,32 +843,34 @@ fn getZigArgs(compile: *Compile, maker: *Maker, fuzz: bool) ![][]const u8 {
871843
872844 const resolved_args_file = try mem.concat(arena, u8, &.{
873845 "@",
874 try b.cache_root.join(arena, &.{args_file}),
846 try graph.cache_root.join(arena, &.{args_file}),
875847 });
876848
877849 zig_args.shrinkRetainingCapacity(2);
878 try zig_args.append(resolved_args_file);
850 try zig_args.append(gpa, resolved_args_file);
879851 }
880852
881853 return try zig_args.toOwnedSlice();
882854}
883855
884pub fn rebuildInFuzzMode(c: *Compile, maker: *Maker, progress_node: std.Progress.Node) !Path {
856pub fn rebuildInFuzzMode(compile: *Compile, maker: *Maker, progress_node: std.Progress.Node) !Path {
885857 const gpa = maker.graph.gpa;
886858
887 c.step.result_error_msgs.clearRetainingCapacity();
888 c.step.result_stderr = "";
859 compile.step.result_error_msgs.clearRetainingCapacity();
860 compile.step.result_stderr = "";
889861
890 c.step.result_error_bundle.deinit(gpa);
891 c.step.result_error_bundle = std.zig.ErrorBundle.empty;
862 compile.step.result_error_bundle.deinit(gpa);
863 compile.step.result_error_bundle = std.zig.ErrorBundle.empty;
892864
893 if (c.step.result_failed_command) |cmd| {
865 if (compile.step.result_failed_command) |cmd| {
894866 gpa.free(cmd);
895 c.step.result_failed_command = null;
867 compile.step.result_failed_command = null;
896868 }
897869
898 const zig_args = try getZigArgs(c, maker, true);
899 const maybe_output_bin_path = try c.step.evalZigProcess(zig_args, progress_node, false, null, gpa);
870 const zig_args = &compile.zig_args;
871 zig_args.clearRetainingCapacity();
872 try lowerZigArgs(compile, maker, zig_args, true);
873 const maybe_output_bin_path = try compile.step.evalZigProcess(zig_args.items, progress_node, false, maker);
900874 return maybe_output_bin_path.?;
901875}
902876
......@@ -907,24 +881,24 @@ pub fn doAtomicSymLinks(
907881 filename_major_only: []const u8,
908882 filename_name_only: []const u8,
909883) !void {
910 const b = step.owner;
911884 const graph = maker.graph;
885 const arena = graph.arena; // TODO don't leak into process arena
912886 const io = graph.io;
913887 const out_dir = Dir.path.dirname(output_path) orelse ".";
914888 const out_basename = Dir.path.basename(output_path);
915889 // sym link for libfoo.so.1 to libfoo.so.1.2.3
916 const major_only_path = b.pathJoin(&.{ out_dir, filename_major_only });
890 const major_only_path = try Dir.path.join(arena, &.{ out_dir, filename_major_only });
917891 const cwd: Io.Dir = .cwd();
918892 cwd.symLinkAtomic(io, out_basename, major_only_path, .{}) catch |err| {
919 return step.fail("unable to symlink {s} -> {s}: {s}", .{
920 major_only_path, out_basename, @errorName(err),
893 return step.fail("unable to symlink {s} -> {s}: {t}", .{
894 major_only_path, out_basename, err,
921895 });
922896 };
923897 // sym link for libfoo.so to libfoo.so.1
924 const name_only_path = b.pathJoin(&.{ out_dir, filename_name_only });
898 const name_only_path = try Dir.path.join(arena, &.{ out_dir, filename_name_only });
925899 cwd.symLinkAtomic(io, filename_major_only, name_only_path, .{}) catch |err| {
926 return step.fail("Unable to symlink {s} -> {s}: {s}", .{
927 name_only_path, filename_major_only, @errorName(err),
900 return step.fail("unable to symlink {s} -> {s}: {t}", .{
901 name_only_path, filename_major_only, err,
928902 });
929903 };
930904}
......@@ -983,14 +957,13 @@ fn getPkgConfigList(b: *std.Build) ![]const PkgConfigPkg {
983957 }
984958}
985959
986fn addFlag(args: *std.array_list.Managed([]const u8), comptime name: []const u8, opt: ?bool) !void {
960fn addBool(gpa: Allocator, args: *std.ArrayList([]const u8), arg: []const u8, opt: bool) !void {
961 if (opt) try args.append(gpa, arg);
962}
963
964fn addFlag(gpa: Allocator, args: *std.ArrayList([]const u8), comptime name: []const u8, opt: ?bool) !void {
987965 const cond = opt orelse return;
988 try args.ensureUnusedCapacity(1);
989 if (cond) {
990 args.appendAssumeCapacity("-f" ++ name);
991 } else {
992 args.appendAssumeCapacity("-fno-" ++ name);
993 }
966 try args.append(gpa, if (cond) "-f" ++ name else "-fno-" ++ name);
994967}
995968
996969const PkgConfigResult = struct {
......@@ -1267,7 +1240,7 @@ const CliNamedModules = struct {
12671240 try compile.modules.putNoClobber(arena, mod, {});
12681241 break;
12691242 }
1270 name = try std.fmt.allocPrint(arena, "{s}{d}", .{ orig_name, n });
1243 name = try allocPrint(arena, "{s}{d}", .{ orig_name, n });
12711244 n += 1;
12721245 }
12731246 }
lib/compiler/Maker/Step/Run.zig+2-2
......@@ -1564,7 +1564,7 @@ fn runCommand(
15641564 const cwd: process.Child.Cwd = if (run.cwd) |lazy_cwd| .{ .path = lazy_cwd.getPath2(b, step) } else .inherit;
15651565
15661566 try step.handleChildProcUnsupported();
1567 try Step.handleVerbose2(step.owner, cwd, run.environ_map, argv);
1567 try Step.handleVerbose(step.owner, cwd, run.environ_map, argv);
15681568
15691569 const allow_skip = switch (run.stdio) {
15701570 .check, .zig_test => run.skip_foreign_checks,
......@@ -1701,7 +1701,7 @@ fn runCommand(
17011701
17021702 gpa.free(step.result_failed_command.?);
17031703 step.result_failed_command = null;
1704 try Step.handleVerbose2(step.owner, cwd, run.environ_map, interp_argv.items);
1704 try Step.handleVerbose(step.owner, cwd, run.environ_map, interp_argv.items);
17051705
17061706 break :term spawnChildAndCollect(run, maker, progress_node, interp_argv.items, &environ_map, has_side_effects, fuzz_context) catch |e| {
17071707 if (!run.failing_to_execute_foreign_is_an_error) return error.MakeSkipped;
lib/compiler/configure_runner.zig+8-17
......@@ -148,39 +148,30 @@ pub fn main(init: process.Init.Minimal) !void {
148148 graph.release_mode = .any;
149149 } else if (mem.cutPrefix(u8, arg, "--release=")) |text| {
150150 graph.release_mode = std.meta.stringToEnum(std.Build.ReleaseMode, text) orelse {
151 fatalWithHint("expected [off|any|fast|safe|small] in '{s}', found '{s}'", .{
151 fatalWithHint("expected [off|any|fast|safe|small] in {q}, found {q}", .{
152152 arg, text,
153153 });
154154 };
155155 } else if (mem.eql(u8, arg, "--color")) {
156156 const next_arg = nextArg(args, &arg_idx) orelse
157 fatalWithHint("expected [auto|on|off] after '{s}'", .{arg});
157 fatalWithHint("expected [auto|on|off] after {q}", .{arg});
158158 color = std.meta.stringToEnum(Color, next_arg) orelse {
159 fatalWithHint("expected [auto|on|off] after '{s}', found '{s}'", .{
159 fatalWithHint("expected [auto|on|off] after {q}, found {q}", .{
160160 arg, next_arg,
161161 });
162162 };
163163 } else if (mem.eql(u8, arg, "--error-style")) {
164164 const next_arg = nextArg(args, &arg_idx) orelse
165 fatalWithHint("expected style after '{s}'", .{arg});
165 fatalWithHint("expected style after {q}", .{arg});
166166 error_style = std.meta.stringToEnum(ErrorStyle, next_arg) orelse {
167 fatalWithHint("expected style after '{s}', found '{s}'", .{ arg, next_arg });
167 fatalWithHint("expected style after {q}, found {q}", .{ arg, next_arg });
168168 };
169169 } else if (mem.eql(u8, arg, "--multiline-errors")) {
170170 const next_arg = nextArg(args, &arg_idx) orelse
171 fatalWithHint("expected style after '{s}'", .{arg});
171 fatalWithHint("expected style after {q}", .{arg});
172172 multiline_errors = std.meta.stringToEnum(MultilineErrors, next_arg) orelse {
173 fatalWithHint("expected style after '{s}', found '{s}'", .{ arg, next_arg });
173 fatalWithHint("expected style after {q}, found {q}", .{ arg, next_arg });
174174 };
175 } else if (mem.eql(u8, arg, "--build-id")) {
176 builder.build_id = .fast;
177 } else if (mem.cutPrefix(u8, arg, "--build-id=")) |style| {
178 builder.build_id = std.zig.BuildId.parse(style) catch |err|
179 fatal("unable to parse --build-id style '{s}': {t}", .{ style, err });
180 } else if (mem.eql(u8, arg, "--debug-compile-errors")) {
181 builder.debug_compile_errors = true;
182 } else if (mem.eql(u8, arg, "--debug-incremental")) {
183 builder.debug_incremental = true;
184175 } else if (mem.eql(u8, arg, "--system")) {
185176 // The usage text shows another argument after this parameter
186177 // but it is handled by the parent process. The build runner
......@@ -189,7 +180,7 @@ pub fn main(init: process.Init.Minimal) !void {
189180 } else if (mem.eql(u8, arg, "--have-run-args")) {
190181 graph.have_run_args = true;
191182 } else {
192 fatalWithHint("unrecognized argument: '{s}'", .{arg});
183 fatalWithHint("unrecognized argument: {q}", .{arg});
193184 }
194185 }
195186
lib/std/Build.zig+11-173
......@@ -46,8 +46,6 @@ install_prefix: []const u8,
4646build_root: Cache.Directory,
4747cache_root: Cache.Directory,
4848debug_log_scopes: []const []const u8 = &.{},
49debug_compile_errors: bool = false,
50debug_incremental: bool = false,
5149/// Number of stack frames captured when a `StackTrace` is recorded for debug purposes,
5250/// in particular at `Step` creation.
5351/// Set to 0 to disable stack collection.
......@@ -75,8 +73,6 @@ pkg_hash: []const u8,
7573/// A mapping from dependency names to package hashes.
7674available_deps: AvailableDeps,
7775
78build_id: ?std.zig.BuildId = null,
79
8076pub const ReleaseMode = enum {
8177 off,
8278 any,
......@@ -227,13 +223,6 @@ pub fn create(
227223 .graph = graph,
228224 .build_root = build_root,
229225 .cache_root = cache_root,
230 .verbose = false,
231 .verbose_link = false,
232 .verbose_cc = false,
233 .verbose_air = false,
234 .verbose_llvm_ir = null,
235 .verbose_llvm_bc = null,
236 .verbose_llvm_cpu_features = false,
237226 .invalid_user_input = false,
238227 .allocator = arena,
239228 .user_input_options = UserInputOptionsMap.init(arena),
......@@ -302,22 +291,12 @@ fn createChild(
302291 .user_input_options = user_input_options,
303292 .available_options_map = AvailableOptionsMap.init(allocator),
304293 .available_options_list = std.array_list.Managed(AvailableOption).init(allocator),
305 .verbose = parent.verbose,
306 .verbose_link = parent.verbose_link,
307 .verbose_cc = parent.verbose_cc,
308 .verbose_air = parent.verbose_air,
309 .verbose_llvm_ir = parent.verbose_llvm_ir,
310 .verbose_llvm_bc = parent.verbose_llvm_bc,
311 .verbose_llvm_cpu_features = parent.verbose_llvm_cpu_features,
312294 .invalid_user_input = false,
313295 .default_step = undefined,
314296 .top_level_steps = .{},
315 .sysroot = parent.sysroot,
316297 .build_root = build_root,
317298 .cache_root = parent.cache_root,
318299 .debug_log_scopes = parent.debug_log_scopes,
319 .debug_compile_errors = parent.debug_compile_errors,
320 .debug_incremental = parent.debug_incremental,
321300 .enable_darling = parent.enable_darling,
322301 .enable_qemu = parent.enable_qemu,
323302 .enable_rosetta = parent.enable_rosetta,
......@@ -1125,7 +1104,7 @@ pub fn option(b: *Build, comptime T: type, name_raw: []const u8, description_raw
11251104 if (std.zig.BuildId.parse(s)) |build_id| {
11261105 return build_id;
11271106 } else |err| {
1128 log.err("unable to parse option '-D{s}': {s}", .{ name, @errorName(err) });
1107 log.err("unable to parse option '-D{s}': {t}", .{ name, err });
11291108 b.markInvalidUserInput();
11301109 return null;
11311110 }
......@@ -1594,8 +1573,9 @@ pub fn addCheckFile(
15941573}
15951574
15961575pub fn truncateFile(b: *Build, dest_path: []const u8) (Io.Dir.CreateDirError || Io.Dir.StatFileError)!void {
1597 const io = b.graph.io;
1598 if (b.verbose) log.info("truncate {s}", .{dest_path});
1576 const graph = b.graph;
1577 const io = graph.io;
1578 if (graph.verbose) log.info("truncate {s}", .{dest_path});
15991579 const cwd = Io.Dir.cwd();
16001580 var src_file = cwd.createFile(io, dest_path, .{}) catch |err| switch (err) {
16011581 error.FileNotFound => blk: {
......@@ -1705,9 +1685,13 @@ pub fn runAllowFail(
17051685
17061686 const graph = b.graph;
17071687 const io = graph.io;
1688 const arena = graph.arena;
17081689
17091690 const max_output_size = 400 * 1024;
1710 try Step.handleVerbose2(b, .inherit, &graph.environ_map, argv);
1691 if (graph.verbose) {
1692 const text = std.zig.allocPrintCmd(arena, .inherit, null, argv);
1693 std.log.scoped(.verbose).info("{s}", .{text});
1694 }
17111695
17121696 var child = try std.process.spawn(io, .{
17131697 .argv = argv,
......@@ -1718,10 +1702,10 @@ pub fn runAllowFail(
17181702 });
17191703
17201704 var stdout_reader = child.stdout.?.readerStreaming(io, &.{});
1721 const stdout = stdout_reader.interface.allocRemaining(b.allocator, .limited(max_output_size)) catch {
1705 const stdout = stdout_reader.interface.allocRemaining(arena, .limited(max_output_size)) catch {
17221706 return error.ReadFailure;
17231707 };
1724 errdefer b.allocator.free(stdout);
1708 errdefer arena.free(stdout);
17251709
17261710 const term = try child.wait(io);
17271711 switch (term) {
......@@ -2089,34 +2073,6 @@ pub fn runBuild(b: *Build, build_zig: anytype) anyerror!void {
20892073pub const GeneratedFile = struct {
20902074 /// The step that generates the file.
20912075 step: *Step,
2092 /// The path to the generated file. Must be either absolute or relative to the build runner cwd.
2093 /// This value must be set in the `fn make()` of the `step` and must not be `null` afterwards.
2094 path: ?[]const u8 = null,
2095
2096 /// Deprecated, see `getPath3`.
2097 pub fn getPath(gen: GeneratedFile) []const u8 {
2098 return gen.step.owner.pathFromCwd(gen.path orelse std.debug.panic(
2099 "getPath() was called on a GeneratedFile that wasn't built yet. Is there a missing Step dependency on step '{s}'?",
2100 .{gen.step.name},
2101 ));
2102 }
2103
2104 /// Deprecated, see `getPath3`.
2105 pub fn getPath2(gen: GeneratedFile, src_builder: *Build, asking_step: ?*Step) []const u8 {
2106 return getPath3(gen, src_builder, asking_step) catch |err| switch (err) {
2107 error.Canceled => std.process.exit(1),
2108 };
2109 }
2110
2111 pub fn getPath3(gen: GeneratedFile, src_builder: *Build, asking_step: ?*Step) Io.Cancelable![]const u8 {
2112 return gen.path orelse {
2113 const graph = gen.step.owner.graph;
2114 const io = graph.io;
2115 const stderr = try io.lockStderr(&.{}, graph.stderr_mode);
2116 dumpBadGetPathHelp(gen.step, stderr.terminal(), src_builder, asking_step) catch {};
2117 @panic("misconfigured build script");
2118 };
2119 }
21202076};
21212077
21222078// dirnameAllowEmpty is a variant of fs.path.dirname
......@@ -2290,94 +2246,6 @@ pub const LazyPath = union(enum) {
22902246 }
22912247 }
22922248
2293 /// Deprecated, see `getPath4`.
2294 pub fn getPath(lazy_path: LazyPath, src_builder: *Build) []const u8 {
2295 return getPath2(lazy_path, src_builder, null);
2296 }
2297
2298 /// Deprecated, see `getPath4`.
2299 pub fn getPath2(lazy_path: LazyPath, src_builder: *Build, asking_step: ?*Step) []const u8 {
2300 const p = getPath3(lazy_path, src_builder, asking_step);
2301 return src_builder.pathResolve(&.{ p.root_dir.path orelse ".", p.sub_path });
2302 }
2303
2304 /// Deprecated, see `getPath4`.
2305 pub fn getPath3(lazy_path: LazyPath, src_builder: *Build, asking_step: ?*Step) Cache.Path {
2306 return getPath4(lazy_path, src_builder, asking_step) catch |err| switch (err) {
2307 error.Canceled => std.process.exit(1),
2308 };
2309 }
2310
2311 /// Intended to be used during the make phase only.
2312 ///
2313 /// `asking_step` is only used for debugging purposes; it's the step being
2314 /// run that is asking for the path.
2315 pub fn getPath4(lazy_path: LazyPath, src_builder: *Build, asking_step: ?*Step) Io.Cancelable!Cache.Path {
2316 switch (lazy_path) {
2317 .src_path => |sp| return .{
2318 .root_dir = sp.owner.build_root,
2319 .sub_path = sp.sub_path,
2320 },
2321 .cwd_relative => |sub_path| return .{
2322 .root_dir = Cache.Directory.cwd(),
2323 .sub_path = sub_path,
2324 },
2325 .generated => |gen| {
2326 // TODO make gen.file.path not be absolute and use that as the
2327 // basis for not traversing up too many directories.
2328
2329 const graph = src_builder.graph;
2330
2331 var file_path: Cache.Path = .{
2332 .root_dir = Cache.Directory.cwd(),
2333 .sub_path = gen.file.path orelse {
2334 const io = graph.io;
2335 const stderr = try io.lockStderr(&.{}, graph.stderr_mode);
2336 dumpBadGetPathHelp(gen.file.step, stderr.terminal(), src_builder, asking_step) catch {};
2337 io.unlockStderr();
2338 @panic("misconfigured build script");
2339 },
2340 };
2341
2342 if (gen.up > 0) {
2343 const cache_root_path = src_builder.cache_root.path orelse
2344 (src_builder.cache_root.join(src_builder.allocator, &.{"."}) catch @panic("OOM"));
2345
2346 for (0..gen.up) |_| {
2347 if (mem.eql(u8, file_path.sub_path, cache_root_path)) {
2348 // If we hit the cache root and there's still more to go,
2349 // the script attempted to go too far.
2350 dumpBadDirnameHelp(gen.file.step, asking_step,
2351 \\dirname() attempted to traverse outside the cache root.
2352 \\This is not allowed.
2353 \\
2354 , .{}) catch {};
2355 @panic("misconfigured build script");
2356 }
2357
2358 // path is absolute.
2359 // dirname will return null only if we're at root.
2360 // Typically, we'll stop well before that at the cache root.
2361 file_path.sub_path = fs.path.dirname(file_path.sub_path) orelse {
2362 dumpBadDirnameHelp(gen.file.step, asking_step,
2363 \\dirname() reached root.
2364 \\No more directories left to go up.
2365 \\
2366 , .{}) catch {};
2367 @panic("misconfigured build script");
2368 };
2369 }
2370 }
2371
2372 return file_path.join(src_builder.allocator, gen.sub_path) catch @panic("OOM");
2373 },
2374 .dependency => |dep| return .{
2375 .root_dir = dep.dependency.builder.build_root,
2376 .sub_path = dep.sub_path,
2377 },
2378 }
2379 }
2380
23812249 pub fn basename(lazy_path: LazyPath, src_builder: *Build, asking_step: ?*Step) []const u8 {
23822250 return fs.path.basename(switch (lazy_path) {
23832251 .src_path => |sp| sp.sub_path,
......@@ -2451,36 +2319,6 @@ fn dumpBadDirnameHelp(
24512319 stderr.setColor(.reset) catch {};
24522320}
24532321
2454/// In this function the stderr mutex has already been locked.
2455pub fn dumpBadGetPathHelp(s: *Step, t: Io.Terminal, src_builder: *Build, asking_step: ?*Step) anyerror!void {
2456 const w = t.writer;
2457 try w.print(
2458 \\getPath() was called on a GeneratedFile that wasn't built yet.
2459 \\ source package path: {s}
2460 \\ Is there a missing Step dependency on step '{s}'?
2461 \\
2462 , .{
2463 src_builder.build_root.path orelse ".",
2464 s.name,
2465 });
2466
2467 t.setColor(.red) catch {};
2468 try w.writeAll(" The step was created by this stack trace:\n");
2469 t.setColor(.reset) catch {};
2470
2471 s.dump(t);
2472 if (asking_step) |as| {
2473 t.setColor(.red) catch {};
2474 try w.print(" The step '{s}' that is missing a dependency on the above step was created by this stack trace:\n", .{as.name});
2475 t.setColor(.reset) catch {};
2476
2477 as.dump(t);
2478 }
2479 t.setColor(.red) catch {};
2480 try w.writeAll(" Proceeding to panic.\n");
2481 t.setColor(.reset) catch {};
2482}
2483
24842322pub const InstallDir = union(enum) {
24852323 prefix: void,
24862324 lib: void,
lib/std/Build/Step/Compile.zig+4
......@@ -87,9 +87,13 @@ libc_file: ?LazyPath = null,
8787each_lib_rpath: ?bool = null,
8888/// On ELF targets, this will emit a link section called ".note.gnu.build-id"
8989/// which can be used to coordinate a stripped binary with its debug symbols.
90///
9091/// As an example, the bloaty project refuses to work unless its inputs have
9192/// build ids, in order to prevent accidental mismatches.
93///
9294/// The default is to not include this section because it slows down linking.
95///
96/// This option overrides the CLI argument passed to `zig build`.
9397build_id: ?std.zig.BuildId = null,
9498
9599/// Create a .eh_frame_hdr section and a PT_GNU_EH_FRAME segment in the ELF
lib/std/zig.zig+73
......@@ -1157,6 +1157,79 @@ pub const ClangCliParam = struct {
11571157 }
11581158};
11591159
1160pub fn allocPrintCmd(
1161 gpa: Allocator,
1162 cwd: std.process.Child.Cwd,
1163 opt_env: ?struct {
1164 child: *const std.process.Environ.Map,
1165 parent: *const std.process.Environ.Map,
1166 },
1167 argv: []const []const u8,
1168) Allocator.Error![]u8 {
1169 const shell = struct {
1170 fn escape(writer: *Io.Writer, string: []const u8, is_argv0: bool) !void {
1171 for (string) |c| {
1172 if (switch (c) {
1173 else => true,
1174 '%', '+'...':', '@'...'Z', '_', 'a'...'z' => false,
1175 '=' => is_argv0,
1176 }) break;
1177 } else return writer.writeAll(string);
1178
1179 try writer.writeByte('"');
1180 for (string) |c| {
1181 if (switch (c) {
1182 std.ascii.control_code.nul => break,
1183 '!', '"', '$', '\\', '`' => true,
1184 else => !std.ascii.isPrint(c),
1185 }) try writer.writeByte('\\');
1186 switch (c) {
1187 std.ascii.control_code.nul => unreachable,
1188 std.ascii.control_code.bel => try writer.writeByte('a'),
1189 std.ascii.control_code.bs => try writer.writeByte('b'),
1190 std.ascii.control_code.ht => try writer.writeByte('t'),
1191 std.ascii.control_code.lf => try writer.writeByte('n'),
1192 std.ascii.control_code.vt => try writer.writeByte('v'),
1193 std.ascii.control_code.ff => try writer.writeByte('f'),
1194 std.ascii.control_code.cr => try writer.writeByte('r'),
1195 std.ascii.control_code.esc => try writer.writeByte('E'),
1196 ' '...'~' => try writer.writeByte(c),
1197 else => try writer.print("{o:0>3}", .{c}),
1198 }
1199 }
1200 try writer.writeByte('"');
1201 }
1202 };
1203
1204 var aw: Io.Writer.Allocating = .init(gpa);
1205 defer aw.deinit();
1206 const writer = &aw.writer;
1207 switch (cwd) {
1208 .inherit => {},
1209 .path => |path| writer.print("cd {s} && ", .{path}) catch return error.OutOfMemory,
1210 .dir => @panic("TODO"),
1211 }
1212 if (opt_env) |env| {
1213 var it = env.child.iterator();
1214 while (it.next()) |entry| {
1215 const key = entry.key_ptr.*;
1216 const value = entry.value_ptr.*;
1217 if (env.parent.get(key)) |process_value| {
1218 if (std.mem.eql(u8, value, process_value)) continue;
1219 }
1220 writer.print("{s}=", .{key}) catch return error.OutOfMemory;
1221 shell.escape(writer, value, false) catch return error.OutOfMemory;
1222 writer.writeByte(' ') catch return error.OutOfMemory;
1223 }
1224 }
1225 shell.escape(writer, argv[0], true) catch return error.OutOfMemory;
1226 for (argv[1..]) |arg| {
1227 writer.writeByte(' ') catch return error.OutOfMemory;
1228 shell.escape(writer, arg, false) catch return error.OutOfMemory;
1229 }
1230 return aw.toOwnedSlice();
1231}
1232
11601233test {
11611234 _ = Ast;
11621235 _ = AstRlAnnotate;