authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-04-30 11:39:28-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-05-25 18:54:35-07:00
log0d95b44a1c9e483beb82f7b70515185159d79bdc
treee9755eaff750cefd0d9ba388f3d59cf130f437c3
parenta23050bf733793c40428bb77a8cd08bd1781306e

build system: implement cli positionals


6 files changed, 69 insertions(+), 27 deletions(-)

BRANCH_TODO+23-10
...@@ -1,21 +1,21 @@...@@ -1,21 +1,21 @@
1* make more stuff use IndexType
2* make addExtra return Index using reflection
3* remove Cache from configurer1* remove Cache from configurer
4* implement the build options2* implement the build options
5* get zig init template working
6* finish migrating the rest of the build steps3* finish migrating the rest of the build steps
4* inspect b4ffb402c082605c4b324e88120306fc8fb3cf32 diff and apply changes as needed (merge conflict)
7* make zig-pkg path root configurable in maker (make sure --system still works)5* make zig-pkg path root configurable in maker (make sure --system still works)
8* eliminate calls to getPath, getPath2, getPath36* eliminate calls to getPath, getPath2, getPath3
7* [build system compile step data races with getGraph function](https://codeberg.org/ziglang/zig/issues/31397)
9* solve the TODOs added in this branch8* solve the TODOs added in this branch
10* get zig tests passing9* get zig tests passing
11* test a bunch of third party projects / help people migrate10* test a bunch of third party projects / help people migrate
12* refactor with DefaultingEnum11
13* inspect b4ffb402c082605c4b324e88120306fc8fb3cf32 diff and apply changes as needed (merge conflict)
14* https://codeberg.org/ziglang/zig/issues/31397
15* restore the generated_compiler_rt_dyn_lib hack?
16* run args
17* https://codeberg.org/ziglang/zig/pulls/30762
18* get the target from the parent process instead12* get the target from the parent process instead
13* [handle missing cache hits when chaining two run steps](https://codeberg.org/ziglang/zig/pulls/30762)
14* [Absolute and cwd-relative paths in build cache](https://codeberg.org/ziglang/zig/issues/32097)
15
16* make more stuff use IndexType
17* make addExtra return Index using reflection
18* refactor with DefaultingEnum
1919
20## Followup Issues20## Followup Issues
21* reduce the size of Maker.Step.Extended (make Run smaller) probably by using an arena per make21* reduce the size of Maker.Step.Extended (make Run smaller) probably by using an arena per make
...@@ -28,4 +28,17 @@...@@ -28,4 +28,17 @@
2828
2929
30## Release Notes30## Release Notes
31* run args are all together now, not observable in configure phase whether run args are provided31
32run args are all together now, not observable in configure phase whether run args are provided.
33
34```zig
35if (b.args) |args| {
36 run_cmd.addArgs(args);
37}
38```
39
40⬇️
41
42```zig
43run_cmd.addBuildPositionals();
44```
lib/compiler/Maker/Step/Run.zig+13-10
...@@ -72,6 +72,7 @@ pub fn make(...@@ -72,6 +72,7 @@ pub fn make(
7272
73 var any_dep_files = false;73 var any_dep_files = false;
74 var any_output_args = false;74 var any_output_args = false;
75 var any_cli_positionals = false;
7576
76 for (conf_run.args.slice) |arg_index| {77 for (conf_run.args.slice) |arg_index| {
77 const arg = arg_index.get(conf);78 const arg = arg_index.get(conf);
...@@ -176,10 +177,11 @@ pub fn make(...@@ -176,10 +177,11 @@ pub fn make(
176 });177 });
177 argv_list.items.len += 1;178 argv_list.items.len += 1;
178 },179 },
179 .cli_rest_positionals => {180 .cli_positionals => {
181 any_cli_positionals = true;
180 if (maker.run_args) |run_args| {182 if (maker.run_args) |run_args| {
181 try argv_list.appendSlice(gpa, run_args);183 try argv_list.appendSlice(gpa, run_args);
182 for (run_args) |s| man.hash.addBytes(s);184 man.hash.addListOfBytes(run_args);
183 }185 }
184 },186 },
185 }187 }
...@@ -236,13 +238,14 @@ pub fn make(...@@ -236,13 +238,14 @@ pub fn make(
236 }238 }
237239
238 // Whether the Run step has side effects *other than* updating the output arguments.240 // Whether the Run step has side effects *other than* updating the output arguments.
239 const has_side_effects = conf_run.flags.has_side_effects or switch (conf_run.flags.stdio) {241 const has_side_effects = conf_run.flags.has_side_effects or any_cli_positionals or
240 .infer_from_args => !any_output_args and242 switch (conf_run.flags.stdio) {
241 conf_run.captured_stdout.value == null and243 .infer_from_args => !any_output_args and
242 conf_run.captured_stderr.value == null,244 conf_run.captured_stdout.value == null and
243 .inherit => true,245 conf_run.captured_stderr.value == null,
244 .check, .zig_test => false,246 .inherit => true,
245 };247 .check, .zig_test => false,
248 };
246249
247 if (!has_side_effects and try step.cacheHitAndWatch(maker, &man)) {250 if (!has_side_effects and try step.cacheHitAndWatch(maker, &man)) {
248 // Cache hit; skip running command.251 // Cache hit; skip running command.
...@@ -1596,7 +1599,7 @@ pub fn rerunInFuzzMode(...@@ -1596,7 +1599,7 @@ pub fn rerunInFuzzMode(
1596 },1599 },
1597 .output_file => unreachable,1600 .output_file => unreachable,
1598 .output_directory => unreachable,1601 .output_directory => unreachable,
1599 .cli_rest_positionals => unreachable,1602 .cli_positionals => unreachable,
1600 }1603 }
1601 }1604 }
16021605
lib/compiler/configurer.zig+2-2
...@@ -492,9 +492,9 @@ const Serialize = struct {...@@ -492,9 +492,9 @@ const Serialize = struct {
492 .producer = .{ .value = null },492 .producer = .{ .value = null },
493 .generated = .{ .value = a.generated_file },493 .generated = .{ .value = a.generated_file },
494 },494 },
495 .cli_rest_positionals => .{495 .cli_positionals => .{
496 .flags = .{496 .flags = .{
497 .tag = .cli_rest_positionals,497 .tag = .cli_positionals,
498 .prefix = false,498 .prefix = false,
499 .suffix = false,499 .suffix = false,
500 .basename = false,500 .basename = false,
lib/init/build.zig+1-3
...@@ -111,9 +111,7 @@ pub fn build(b: *std.Build) void {...@@ -111,9 +111,7 @@ pub fn build(b: *std.Build) void {
111111
112 // This allows the user to pass arguments to the application in the build112 // This allows the user to pass arguments to the application in the build
113 // command itself, like this: `zig build run -- arg1 arg2 etc`113 // command itself, like this: `zig build run -- arg1 arg2 etc`
114 if (b.args) |args| {114 run_cmd.addCliPositionals();
115 run_cmd.addArgs(args);
116 }
117115
118 // Creates an executable that will run `test` blocks from the provided module.116 // Creates an executable that will run `test` blocks from the provided module.
119 // Here `mod` needs to define a target, which is why earlier we made sure to117 // Here `mod` needs to define a target, which is why earlier we made sure to
lib/std/Build/Configuration.zig+1-1
...@@ -567,7 +567,7 @@ pub const Step = extern struct {...@@ -567,7 +567,7 @@ pub const Step = extern struct {
567 file_content,567 file_content,
568 output_file,568 output_file,
569 output_directory,569 output_directory,
570 cli_rest_positionals,570 cli_positionals,
571 };571 };
572572
573 pub const Index = IndexType(@This());573 pub const Index = IndexType(@This());
lib/std/Build/Step/Run.zig+29-1
...@@ -142,7 +142,7 @@ pub const Arg = union(enum) {...@@ -142,7 +142,7 @@ pub const Arg = union(enum) {
142 output_file_dep: *Output,142 output_file_dep: *Output,
143 output_directory: *Output,143 output_directory: *Output,
144 /// The arguments passed after "--" on the "zig build" CLI.144 /// The arguments passed after "--" on the "zig build" CLI.
145 cli_rest_positionals,145 cli_positionals,
146};146};
147147
148pub const PrefixedArtifact = struct {148pub const PrefixedArtifact = struct {
...@@ -491,16 +491,44 @@ pub fn addPrefixedDepFileOutputArg(run: *Run, prefix: []const u8, basename: []co...@@ -491,16 +491,44 @@ pub fn addPrefixedDepFileOutputArg(run: *Run, prefix: []const u8, basename: []co
491 return .{ .generated = .{ .index = dep_file.generated_file } };491 return .{ .generated = .{ .index = dep_file.generated_file } };
492}492}
493493
494/// Appends the contents of `arg`, verbatim, to the command line that will be
495/// passed to the process being run.
496///
497/// If `arg` is an input file, `addFileInput` (or related function) must be
498/// used instead to ensure correct cache behavior.
499///
500/// If `arg` is an output file, `addOutputFileArg` (or related function) must
501/// be used instead to ensure correct cache behavior.
494pub fn addArg(run: *Run, arg: []const u8) void {502pub fn addArg(run: *Run, arg: []const u8) void {
495 const graph = run.step.owner.graph;503 const graph = run.step.owner.graph;
496 const arena = graph.arena;504 const arena = graph.arena;
497 run.argv.append(arena, .{ .bytes = graph.dupeString(arg) }) catch @panic("OOM");505 run.argv.append(arena, .{ .bytes = graph.dupeString(arg) }) catch @panic("OOM");
498}506}
499507
508/// Appends each of `args`, verbatim, to the command line that will be passed
509/// to the process being run.
510///
511/// If any element of `args` is an input file, `addFileInput` must be used
512/// instead to ensure correct cache behavior.
513///
514/// If any element of `args` is an output file, `addOutputFileArg` (or related
515/// function) must be used instead to ensure correct cache behavior.
500pub fn addArgs(run: *Run, args: []const []const u8) void {516pub fn addArgs(run: *Run, args: []const []const u8) void {
501 for (args) |arg| run.addArg(arg);517 for (args) |arg| run.addArg(arg);
502}518}
503519
520/// Any extra positional args are provided to the `zig build` command, they are
521/// appended here. This causes the step to be considered to have side effects,
522/// disabling caching.
523///
524/// In the example command `zig build run -- arg1 arg2`, "arg1" and "arg2" will
525/// be passed to the process being run.
526pub fn addCliPositionals(run: *Run) void {
527 const graph = run.step.owner.graph;
528 const arena = graph.arena;
529 run.argv.append(arena, .cli_positionals) catch @panic("OOM");
530}
531
504pub fn setStdIn(run: *Run, stdin: StdIn) void {532pub fn setStdIn(run: *Run, stdin: StdIn) void {
505 switch (stdin) {533 switch (stdin) {
506 .lazy_path => |lazy_path| lazy_path.addStepDependencies(&run.step),534 .lazy_path => |lazy_path| lazy_path.addStepDependencies(&run.step),