This commit is contained in:
Lee Cannon 2025-11-25 12:29:56 +01:00 committed by GitHub
commit 4121ddb621
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
20 changed files with 254 additions and 348 deletions

View file

@ -600,8 +600,8 @@ pub fn build(b: *std.Build) !void {
}),
});
const update_mingw_run = b.addRunArtifact(update_mingw_exe);
update_mingw_run.addDirectoryArg(b.path("lib"));
update_mingw_run.addDirectoryArg(.{ .cwd_relative = mingw_src_path });
update_mingw_run.addDirectoryArg(.{ .lazy_path = b.path("lib") });
update_mingw_run.addDirectoryArg(.{ .lazy_path = .{ .cwd_relative = mingw_src_path } });
update_mingw_step.dependOn(&update_mingw_run.step);
} else {
@ -677,9 +677,9 @@ fn addWasiUpdateStep(b: *std.Build, version: [:0]const u8) !void {
"--enable-nontrapping-float-to-int",
"--enable-sign-ext",
});
run_opt.addArtifactArg(exe);
run_opt.addArtifactArg(.{ .artifact = exe });
run_opt.addArg("-o");
const optimized_wasm = run_opt.addOutputFileArg("zig1.wasm");
const optimized_wasm = run_opt.addOutputFileArg(.{ .basename = "zig1.wasm" });
const update_zig1 = b.addUpdateSourceFiles();
update_zig1.addCopyFileToSource(optimized_wasm, "stage1/zig1.wasm");
@ -1437,10 +1437,10 @@ fn generateLangRef(b: *std.Build) std.Build.LazyPath {
});
cmd.addArgs(&.{ "--zig-lib-dir", b.fmt("{f}", .{b.graph.zig_lib_directory}) });
cmd.addArgs(&.{"-i"});
cmd.addFileArg(b.path(b.fmt("doc/langref/{s}", .{entry.name})));
cmd.addFileArg(.{ .lazy_path = b.path(b.fmt("doc/langref/{s}", .{entry.name})) });
cmd.addArgs(&.{"-o"});
_ = wf.addCopyFile(cmd.addOutputFileArg(out_basename), out_basename);
_ = wf.addCopyFile(cmd.addOutputFileArg(.{ .basename = out_basename }), out_basename);
}
const docgen_exe = b.addExecutable(.{
@ -1454,17 +1454,17 @@ fn generateLangRef(b: *std.Build) std.Build.LazyPath {
const docgen_cmd = b.addRunArtifact(docgen_exe);
docgen_cmd.addArgs(&.{"--code-dir"});
docgen_cmd.addDirectoryArg(wf.getDirectory());
docgen_cmd.addDirectoryArg(.{ .lazy_path = wf.getDirectory() });
docgen_cmd.addFileArg(b.path("doc/langref.html.in"));
return docgen_cmd.addOutputFileArg("langref.html");
docgen_cmd.addFileArg(.{ .lazy_path = b.path("doc/langref.html.in") });
return docgen_cmd.addOutputFileArg(.{ .basename = "langref.html" });
}
fn superHtmlCheck(b: *std.Build, html_file: std.Build.LazyPath) *std.Build.Step {
const run_superhtml = b.addSystemCommand(&.{
"superhtml", "check",
});
run_superhtml.addFileArg(html_file);
run_superhtml.addFileArg(.{ .lazy_path = html_file });
run_superhtml.expectExitCode(0);
return &run_superhtml.step;
}

View file

@ -944,11 +944,11 @@ pub fn addRunArtifact(b: *Build, exe: *Step.Compile) *Step.Run {
if (cmd_arg) |arg| {
run_step.addArg(arg);
} else {
run_step.addArtifactArg(exe);
run_step.addArtifactArg(.{ .artifact = exe });
}
}
} else {
run_step.addArtifactArg(exe);
run_step.addArtifactArg(.{ .artifact = exe });
}
const test_server_mode: bool = s: {
@ -983,7 +983,7 @@ pub fn addRunArtifact(b: *Build, exe: *Step.Compile) *Step.Run {
run_step.expectExitCode(0);
}
} else {
run_step.addArtifactArg(exe);
run_step.addArtifactArg(.{ .artifact = exe });
}
return run_step;

View file

@ -154,34 +154,31 @@ pub const StdIo = union(enum) {
};
pub const Arg = union(enum) {
artifact: PrefixedArtifact,
lazy_path: PrefixedLazyPath,
decorated_directory: DecoratedLazyPath,
file_content: PrefixedLazyPath,
artifact: DecoratedArtifact,
file: DecoratedLazyPath,
directory: DecoratedLazyPath,
file_content: DecoratedLazyPath,
bytes: []u8,
output_file: *Output,
output_directory: *Output,
};
pub const PrefixedArtifact = struct {
prefix: []const u8,
pub const DecoratedArtifact = struct {
artifact: *Step.Compile,
};
pub const PrefixedLazyPath = struct {
prefix: []const u8,
lazy_path: std.Build.LazyPath,
prefix: []const u8 = "",
suffix: []const u8 = "",
};
pub const DecoratedLazyPath = struct {
prefix: []const u8,
lazy_path: std.Build.LazyPath,
suffix: []const u8,
prefix: []const u8 = "",
suffix: []const u8 = "",
};
};
pub const Output = struct {
generated_file: std.Build.GeneratedFile,
prefix: []const u8,
suffix: []const u8,
basename: []const u8,
};
@ -244,277 +241,16 @@ pub fn setName(run: *Run, name: []const u8) void {
pub fn enableTestRunnerMode(run: *Run) void {
const b = run.step.owner;
run.stdio = .zig_test;
run.addPrefixedDirectoryArg("--cache-dir=", .{ .cwd_relative = b.cache_root.path orelse "." });
run.addDirectoryArg(.{
.prefix = "--cache-dir=",
.lazy_path = .{ .cwd_relative = b.cache_root.path orelse "." },
});
run.addArgs(&.{
b.fmt("--seed=0x{x}", .{b.graph.random_seed}),
"--listen=-",
});
}
pub fn addArtifactArg(run: *Run, artifact: *Step.Compile) void {
run.addPrefixedArtifactArg("", artifact);
}
pub fn addPrefixedArtifactArg(run: *Run, prefix: []const u8, artifact: *Step.Compile) void {
const b = run.step.owner;
const prefixed_artifact: PrefixedArtifact = .{
.prefix = b.dupe(prefix),
.artifact = artifact,
};
run.argv.append(b.allocator, .{ .artifact = prefixed_artifact }) catch @panic("OOM");
const bin_file = artifact.getEmittedBin();
bin_file.addStepDependencies(&run.step);
}
/// Provides a file path as a command line argument to the command being run.
///
/// Returns a `std.Build.LazyPath` which can be used as inputs to other APIs
/// throughout the build system.
///
/// Related:
/// * `addPrefixedOutputFileArg` - same thing but prepends a string to the argument
/// * `addFileArg` - for input files given to the child process
pub fn addOutputFileArg(run: *Run, basename: []const u8) std.Build.LazyPath {
return run.addPrefixedOutputFileArg("", basename);
}
/// Provides a file path as a command line argument to the command being run.
/// Asserts `basename` is not empty.
///
/// For example, a prefix of "-o" and basename of "output.txt" will result in
/// the child process seeing something like this: "-ozig-cache/.../output.txt"
///
/// The child process will see a single argument, regardless of whether the
/// prefix or basename have spaces.
///
/// The returned `std.Build.LazyPath` can be used as inputs to other APIs
/// throughout the build system.
///
/// Related:
/// * `addOutputFileArg` - same thing but without the prefix
/// * `addFileArg` - for input files given to the child process
pub fn addPrefixedOutputFileArg(
run: *Run,
prefix: []const u8,
basename: []const u8,
) std.Build.LazyPath {
const b = run.step.owner;
if (basename.len == 0) @panic("basename must not be empty");
const output = b.allocator.create(Output) catch @panic("OOM");
output.* = .{
.prefix = b.dupe(prefix),
.basename = b.dupe(basename),
.generated_file = .{ .step = &run.step },
};
run.argv.append(b.allocator, .{ .output_file = output }) catch @panic("OOM");
if (run.rename_step_with_output_arg) {
run.setName(b.fmt("{s} ({s})", .{ run.step.name, basename }));
}
return .{ .generated = .{ .file = &output.generated_file } };
}
/// Appends an input file to the command line arguments.
///
/// The child process will see a file path. Modifications to this file will be
/// detected as a cache miss in subsequent builds, causing the child process to
/// be re-executed.
///
/// Related:
/// * `addPrefixedFileArg` - same thing but prepends a string to the argument
/// * `addOutputFileArg` - for files generated by the child process
pub fn addFileArg(run: *Run, lp: std.Build.LazyPath) void {
run.addPrefixedFileArg("", lp);
}
/// Appends an input file to the command line arguments prepended with a string.
///
/// For example, a prefix of "-F" will result in the child process seeing something
/// like this: "-Fexample.txt"
///
/// The child process will see a single argument, even if the prefix has
/// spaces. Modifications to this file will be detected as a cache miss in
/// subsequent builds, causing the child process to be re-executed.
///
/// Related:
/// * `addFileArg` - same thing but without the prefix
/// * `addOutputFileArg` - for files generated by the child process
pub fn addPrefixedFileArg(run: *Run, prefix: []const u8, lp: std.Build.LazyPath) void {
const b = run.step.owner;
const prefixed_file_source: PrefixedLazyPath = .{
.prefix = b.dupe(prefix),
.lazy_path = lp.dupe(b),
};
run.argv.append(b.allocator, .{ .lazy_path = prefixed_file_source }) catch @panic("OOM");
lp.addStepDependencies(&run.step);
}
/// Appends the content of an input file to the command line arguments.
///
/// The child process will see a single argument, even if the file contains whitespace.
/// This means that the entire file content up to EOF is rendered as one contiguous
/// string, including escape sequences. Notably, any (trailing) newlines will show up
/// like this: "hello,\nfile world!\n"
///
/// Modifications to the source file will be detected as a cache miss in subsequent
/// builds, causing the child process to be re-executed.
///
/// This function may not be used to supply the first argument of a `Run` step.
///
/// Related:
/// * `addPrefixedFileContentArg` - same thing but prepends a string to the argument
pub fn addFileContentArg(run: *Run, lp: std.Build.LazyPath) void {
run.addPrefixedFileContentArg("", lp);
}
/// Appends the content of an input file to the command line arguments prepended with a string.
///
/// For example, a prefix of "-F" will result in the child process seeing something
/// like this: "-Fmy file content"
///
/// The child process will see a single argument, even if the prefix and/or the file
/// contain whitespace.
/// This means that the entire file content up to EOF is rendered as one contiguous
/// string, including escape sequences. Notably, any (trailing) newlines will show up
/// like this: "hello,\nfile world!\n"
///
/// Modifications to the source file will be detected as a cache miss in subsequent
/// builds, causing the child process to be re-executed.
///
/// This function may not be used to supply the first argument of a `Run` step.
///
/// Related:
/// * `addFileContentArg` - same thing but without the prefix
pub fn addPrefixedFileContentArg(run: *Run, prefix: []const u8, lp: std.Build.LazyPath) void {
const b = run.step.owner;
// Some parts of this step's configure phase API rely on the first argument being somewhat
// transparent/readable, but the content of the file specified by `lp` remains completely
// opaque until its path can be resolved during the make phase.
if (run.argv.items.len == 0) {
@panic("'addFileContentArg'/'addPrefixedFileContentArg' cannot be first argument");
}
const prefixed_file_source: PrefixedLazyPath = .{
.prefix = b.dupe(prefix),
.lazy_path = lp.dupe(b),
};
run.argv.append(b.allocator, .{ .file_content = prefixed_file_source }) catch @panic("OOM");
lp.addStepDependencies(&run.step);
}
/// Provides a directory path as a command line argument to the command being run.
///
/// Returns a `std.Build.LazyPath` which can be used as inputs to other APIs
/// throughout the build system.
///
/// Related:
/// * `addPrefixedOutputDirectoryArg` - same thing but prepends a string to the argument
/// * `addDirectoryArg` - for input directories given to the child process
pub fn addOutputDirectoryArg(run: *Run, basename: []const u8) std.Build.LazyPath {
return run.addPrefixedOutputDirectoryArg("", basename);
}
/// Provides a directory path as a command line argument to the command being run.
/// Asserts `basename` is not empty.
///
/// For example, a prefix of "-o" and basename of "output_dir" will result in
/// the child process seeing something like this: "-ozig-cache/.../output_dir"
///
/// The child process will see a single argument, regardless of whether the
/// prefix or basename have spaces.
///
/// The returned `std.Build.LazyPath` can be used as inputs to other APIs
/// throughout the build system.
///
/// Related:
/// * `addOutputDirectoryArg` - same thing but without the prefix
/// * `addDirectoryArg` - for input directories given to the child process
pub fn addPrefixedOutputDirectoryArg(
run: *Run,
prefix: []const u8,
basename: []const u8,
) std.Build.LazyPath {
if (basename.len == 0) @panic("basename must not be empty");
const b = run.step.owner;
const output = b.allocator.create(Output) catch @panic("OOM");
output.* = .{
.prefix = b.dupe(prefix),
.basename = b.dupe(basename),
.generated_file = .{ .step = &run.step },
};
run.argv.append(b.allocator, .{ .output_directory = output }) catch @panic("OOM");
if (run.rename_step_with_output_arg) {
run.setName(b.fmt("{s} ({s})", .{ run.step.name, basename }));
}
return .{ .generated = .{ .file = &output.generated_file } };
}
pub fn addDirectoryArg(run: *Run, lazy_directory: std.Build.LazyPath) void {
run.addDecoratedDirectoryArg("", lazy_directory, "");
}
pub fn addPrefixedDirectoryArg(run: *Run, prefix: []const u8, lazy_directory: std.Build.LazyPath) void {
const b = run.step.owner;
run.argv.append(b.allocator, .{ .decorated_directory = .{
.prefix = b.dupe(prefix),
.lazy_path = lazy_directory.dupe(b),
.suffix = "",
} }) catch @panic("OOM");
lazy_directory.addStepDependencies(&run.step);
}
pub fn addDecoratedDirectoryArg(
run: *Run,
prefix: []const u8,
lazy_directory: std.Build.LazyPath,
suffix: []const u8,
) void {
const b = run.step.owner;
run.argv.append(b.allocator, .{ .decorated_directory = .{
.prefix = b.dupe(prefix),
.lazy_path = lazy_directory.dupe(b),
.suffix = b.dupe(suffix),
} }) catch @panic("OOM");
lazy_directory.addStepDependencies(&run.step);
}
/// Add a path argument to a dep file (.d) for the child process to write its
/// discovered additional dependencies.
/// Only one dep file argument is allowed by instance.
pub fn addDepFileOutputArg(run: *Run, basename: []const u8) std.Build.LazyPath {
return run.addPrefixedDepFileOutputArg("", basename);
}
/// Add a prefixed path argument to a dep file (.d) for the child process to
/// write its discovered additional dependencies.
/// Only one dep file argument is allowed by instance.
pub fn addPrefixedDepFileOutputArg(run: *Run, prefix: []const u8, basename: []const u8) std.Build.LazyPath {
const b = run.step.owner;
assert(run.dep_output_file == null);
const dep_file = b.allocator.create(Output) catch @panic("OOM");
dep_file.* = .{
.prefix = b.dupe(prefix),
.basename = b.dupe(basename),
.generated_file = .{ .step = &run.step },
};
run.dep_output_file = dep_file;
run.argv.append(b.allocator, .{ .output_file = dep_file }) catch @panic("OOM");
return .{ .generated = .{ .file = &dep_file.generated_file } };
}
pub fn addArg(run: *Run, arg: []const u8) void {
const b = run.step.owner;
run.argv.append(b.allocator, .{ .bytes = b.dupe(arg) }) catch @panic("OOM");
@ -524,6 +260,154 @@ pub fn addArgs(run: *Run, args: []const []const u8) void {
for (args) |arg| run.addArg(arg);
}
/// Provides an input file path to the provided artifact as a command line argument to the command being run.
///
/// For example, a prefix of "-F" and suffix of ",pack" will result in the child process seeing something like
/// this: "-Fzig-cache/.../binary.exe,pack"
///
/// The child process will see a single argument, even if the prefix or suffix has spaces.
pub fn addArtifactArg(run: *Run, artifact_arg: Arg.DecoratedArtifact) void {
const b = run.step.owner;
run.argv.append(b.allocator, .{ .artifact = .{
.artifact = artifact_arg.artifact,
.prefix = if (artifact_arg.prefix.len != 0) b.dupe(artifact_arg.prefix) else "",
.suffix = if (artifact_arg.suffix.len != 0) b.dupe(artifact_arg.suffix) else "",
} }) catch @panic("OOM");
const bin_file = artifact_arg.artifact.getEmittedBin();
bin_file.addStepDependencies(&run.step);
}
/// Provides an input file path as a command line argument to the command being run.
///
/// For example, a prefix of "-F" and suffix of ",raw" will result in the child process seeing something like
/// this: "-Fzig-cache/.../example.hdd,raw"
///
/// The child process will see a single argument, even if the prefix or suffix has spaces.
pub fn addFileArg(run: *Run, input_file: Arg.DecoratedLazyPath) void {
const b = run.step.owner;
run.argv.append(
b.allocator,
.{
.file = .{
.lazy_path = input_file.lazy_path,
.prefix = if (input_file.prefix.len != 0) b.dupe(input_file.prefix) else "",
.suffix = if (input_file.suffix.len != 0) b.dupe(input_file.suffix) else "",
},
},
) catch @panic("OOM");
input_file.lazy_path.addStepDependencies(&run.step);
}
/// Provides an input directory path as a command line argument to the command being run.
///
/// For example, a prefix of "-i" and suffix of ",recurse" will result in the child process seeing something like
/// this: "-izig-cache/.../input_dir,recurse"
///
/// The child process will see a single argument, even if the prefix or suffix has spaces.
pub fn addDirectoryArg(run: *Run, input_dir: Arg.DecoratedLazyPath) void {
const b = run.step.owner;
run.argv.append(
b.allocator,
.{
.directory = .{
.lazy_path = input_dir.lazy_path,
.prefix = if (input_dir.prefix.len != 0) b.dupe(input_dir.prefix) else "",
.suffix = if (input_dir.suffix.len != 0) b.dupe(input_dir.suffix) else "",
},
},
) catch @panic("OOM");
input_dir.lazy_path.addStepDependencies(&run.step);
}
pub const OutputArgOptions = struct {
prefix: []const u8 = "",
suffix: []const u8 = "",
basename: []const u8,
};
/// Provides an output file path as a command line argument to the command being run.
///
/// Asserts `basename` is not empty.
///
/// For example, a prefix of "-o", suffix of ",format" and basename of "output.txt" will result in the child process
/// seeing something like this: "-ozig-cache/.../output.txt,format"
///
/// The child process will see a single argument, regardless of whether the prefix, suffix or basename have spaces.
pub fn addOutputFileArg(run: *Run, output_file_arg: OutputArgOptions) std.Build.LazyPath {
const b = run.step.owner;
if (output_file_arg.basename.len == 0) @panic("basename must not be empty");
const output = b.allocator.create(Output) catch @panic("OOM");
output.* = .{
.prefix = if (output_file_arg.prefix.len != 0) b.dupe(output_file_arg.prefix) else "",
.suffix = if (output_file_arg.suffix.len != 0) b.dupe(output_file_arg.suffix) else "",
.basename = b.dupe(output_file_arg.basename),
.generated_file = .{ .step = &run.step },
};
run.argv.append(b.allocator, .{ .output_file = output }) catch @panic("OOM");
if (run.rename_step_with_output_arg) {
run.setName(b.fmt("{s} ({s})", .{ run.step.name, output.basename }));
}
return .{ .generated = .{ .file = &output.generated_file } };
}
/// Provides an output directory path as a command line argument to the command being run.
///
/// Asserts `basename` is not empty.
///
/// For example, a prefix of "-o", suffix of ",force" and basename of "output_dir" will result in the child process
/// seeing something like this: "-ozig-cache/.../output_dir,force"
///
/// The child process will see a single argument, regardless of whether the prefix, suffix or basename have spaces.
pub fn addOutputDirectoryArg(run: *Run, output_dir_arg: OutputArgOptions) std.Build.LazyPath {
const b = run.step.owner;
if (output_dir_arg.basename.len == 0) @panic("basename must not be empty");
const output = b.allocator.create(Output) catch @panic("OOM");
output.* = .{
.prefix = if (output_dir_arg.prefix.len != 0) b.dupe(output_dir_arg.prefix) else "",
.suffix = if (output_dir_arg.suffix.len != 0) b.dupe(output_dir_arg.suffix) else "",
.basename = b.dupe(output_dir_arg.basename),
.generated_file = .{ .step = &run.step },
};
run.argv.append(b.allocator, .{ .output_directory = output }) catch @panic("OOM");
if (run.rename_step_with_output_arg) {
run.setName(b.fmt("{s} ({s})", .{ run.step.name, output.basename }));
}
return .{ .generated = .{ .file = &output.generated_file } };
}
/// Provides a file path to a dep file (.d) as a command line argument to the command being run to write its discovered
/// additional dependencies.
///
/// Only one dep file argument is allowed per `std.Build.Step.Run` instance.
///
/// The child process will see a single argument, regardless of whether the prefix, suffix or basename have spaces.
pub fn addDepFileOutputArg(run: *Run, output_dep_arg: OutputArgOptions) std.Build.LazyPath {
const b = run.step.owner;
assert(run.dep_output_file == null);
const output = b.allocator.create(Output) catch @panic("OOM");
output.* = .{
.prefix = if (output_dep_arg.prefix.len != 0) b.dupe(output_dep_arg.prefix) else "",
.suffix = if (output_dep_arg.suffix.len != 0) b.dupe(output_dep_arg.suffix) else "",
.basename = b.dupe(output_dep_arg.basename),
.generated_file = .{ .step = &run.step },
};
run.dep_output_file = output;
run.argv.append(b.allocator, .{ .output_file = output }) catch @panic("OOM");
return .{ .generated = .{ .file = &output.generated_file } };
}
pub fn setStdIn(run: *Run, stdin: StdIn) void {
switch (stdin) {
.lazy_path => |lazy_path| lazy_path.addStepDependencies(&run.step),
@ -550,14 +434,14 @@ pub fn addPathDir(run: *Run, search_path: []const u8) void {
const use_wine = b.enable_wine and b.graph.host.result.os.tag != .windows and use_wine: switch (run.argv.items[0]) {
.artifact => |p| p.artifact.rootModuleTarget().os.tag == .windows,
.lazy_path => |p| {
.file => |p| {
switch (p.lazy_path) {
.generated => |g| if (g.file.step.cast(Step.Compile)) |cs| break :use_wine cs.rootModuleTarget().os.tag == .windows,
else => {},
}
break :use_wine std.mem.endsWith(u8, p.lazy_path.basename(b, &run.step), ".exe");
},
.decorated_directory => false,
.directory => false,
.file_content => unreachable, // not allowed as first arg
.bytes => |bytes| std.mem.endsWith(u8, bytes, ".exe"),
.output_file, .output_directory => false,
@ -655,6 +539,7 @@ pub fn captureStdErr(run: *Run, options: CapturedStdIo.Options) std.Build.LazyPa
captured.* = .{
.output = .{
.prefix = "",
.suffix = "",
.basename = if (options.basename) |basename| b.dupe(basename) else "stderr",
.generated_file = .{ .step = &run.step },
},
@ -830,15 +715,22 @@ fn make(step: *Step, options: Step.MakeOptions) !void {
try argv_list.append(bytes);
man.hash.addBytes(bytes);
},
.lazy_path => |file| {
.file => |file| {
const file_path = file.lazy_path.getPath3(b, step);
try argv_list.append(b.fmt("{s}{s}", .{ file.prefix, run.convertPathArg(file_path) }));
try argv_list.append(b.fmt(
"{s}{s}{s}",
.{ file.prefix, run.convertPathArg(file_path), file.suffix },
));
man.hash.addBytes(file.prefix);
_ = try man.addFilePath(file_path, null);
man.hash.addBytes(file.suffix);
},
.decorated_directory => |dd| {
const file_path = dd.lazy_path.getPath3(b, step);
const resolved_arg = b.fmt("{s}{s}{s}", .{ dd.prefix, run.convertPathArg(file_path), dd.suffix });
.directory => |dir| {
const file_path = dir.lazy_path.getPath3(b, step);
const resolved_arg = b.fmt(
"{s}{s}{s}",
.{ dir.prefix, run.convertPathArg(file_path), dir.suffix },
);
try argv_list.append(resolved_arg);
man.hash.addBytes(resolved_arg);
},
@ -880,16 +772,19 @@ fn make(step: *Step, options: Step.MakeOptions) !void {
}
const file_path = artifact.installed_path orelse artifact.generated_bin.?.path.?;
try argv_list.append(b.fmt("{s}{s}", .{
try argv_list.append(b.fmt("{s}{s}{s}", .{
pa.prefix,
run.convertPathArg(.{ .root_dir = .cwd(), .sub_path = file_path }),
pa.suffix,
}));
man.hash.addBytes(pa.prefix);
_ = try man.addFile(file_path, null);
man.hash.addBytes(pa.suffix);
},
.output_file, .output_directory => |output| {
man.hash.addBytes(output.prefix);
man.hash.addBytes(output.basename);
man.hash.addBytes(output.suffix);
// Add a placeholder into the argument list because we need the
// manifest hash to be updated with all arguments before the
// object directory is computed.
@ -988,7 +883,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void {
argv_list.items[placeholder.index] = if (placeholder.output.prefix.len == 0)
arg_output_path
else
b.fmt("{s}{s}", .{ placeholder.output.prefix, arg_output_path });
b.fmt("{s}{s}{s}", .{ placeholder.output.prefix, arg_output_path, placeholder.output.suffix });
}
try runCommand(run, argv_list.items, has_side_effects, output_dir_path, options, null);
@ -1018,9 +913,10 @@ fn make(step: *Step, options: Step.MakeOptions) !void {
.sub_path = b.pathJoin(&output_components),
};
placeholder.output.generated_file.path = raw_output_path.toString(b.graph.arena) catch @panic("OOM");
argv_list.items[placeholder.index] = b.fmt("{s}{s}", .{
argv_list.items[placeholder.index] = b.fmt("{s}{s}{s}", .{
placeholder.output.prefix,
run.convertPathArg(raw_output_path),
placeholder.output.suffix,
});
}
@ -1099,13 +995,19 @@ pub fn rerunInFuzzMode(
.bytes => |bytes| {
try argv_list.append(arena, bytes);
},
.lazy_path => |file| {
.file => |file| {
const file_path = file.lazy_path.getPath3(b, step);
try argv_list.append(arena, b.fmt("{s}{s}", .{ file.prefix, run.convertPathArg(file_path) }));
try argv_list.append(
arena,
b.fmt("{s}{s}{s}", .{ file.prefix, run.convertPathArg(file_path), file.suffix }),
);
},
.decorated_directory => |dd| {
.directory => |dd| {
const file_path = dd.lazy_path.getPath3(b, step);
try argv_list.append(arena, b.fmt("{s}{s}{s}", .{ dd.prefix, run.convertPathArg(file_path), dd.suffix }));
try argv_list.append(
arena,
b.fmt("{s}{s}{s}", .{ dd.prefix, run.convertPathArg(file_path), dd.suffix }),
);
},
.file_content => |file_plp| {
const file_path = file_plp.lazy_path.getPath3(b, step);
@ -1132,9 +1034,10 @@ pub fn rerunInFuzzMode(
if (artifact == run.producer.?) break :p b.fmt("{f}", .{run.rebuilt_executable.?});
break :p artifact.installed_path orelse artifact.generated_bin.?.path.?;
};
try argv_list.append(arena, b.fmt("{s}{s}", .{
try argv_list.append(arena, b.fmt("{s}{s}{s}", .{
pa.prefix,
run.convertPathArg(.{ .root_dir = .cwd(), .sub_path = file_path }),
pa.suffix,
}));
},
.output_file, .output_directory => unreachable,

View file

@ -611,7 +611,7 @@ pub fn lowerToBuildSteps(
"-target",
triple_txt,
});
run_c.addArtifactArg(artifact);
run_c.addArtifactArg(.{ .artifact = artifact });
break :run_step run_c;
} else b.addRunArtifact(artifact);
run.skip_foreign_checks = true;

View file

@ -2299,12 +2299,12 @@ fn addTest(
const commands_wf = db.b.addWriteFiles();
const run = std.Build.Step.Run.create(db.b, db.b.fmt("run {s} {s}", .{ name, target.test_name_suffix }));
run.addArgs(db_argv1);
run.addFileArg(commands_wf.add(
run.addFileArg(.{ .lazy_path = commands_wf.add(
db.b.fmt("{s}.cmd", .{name}),
db.b.fmt("{s}\n\n{s}\n\nquit {d}\n", .{ db_commands, commands, success }),
));
) });
run.addArgs(db_argv2);
run.addArtifactArg(exe);
run.addArtifactArg(.{ .artifact = exe });
for (expected_output) |expected| run.addCheck(.{ .expect_stdout_match = db.b.fmt("{s}\n", .{expected}) });
run.addCheck(.{ .expect_term = .{ .Exited = success } });
run.setStdIn(.{ .bytes = "" });

View file

@ -117,7 +117,7 @@ fn addCaseConfig(
const check_run = b.addRunArtifact(self.convert_exe);
check_run.setName(annotated_case_name);
check_run.addFileArg(run.captureStdErr(.{}));
check_run.addFileArg(.{ .lazy_path = run.captureStdErr(.{}) });
check_run.expectStdOutEqual(expected_stderr);
self.step.dependOn(&check_run.step);

View file

@ -201,7 +201,7 @@ fn addCaseInstance(
const check_run = b.addRunArtifact(self.convert_exe);
check_run.setName(annotated_case_name);
check_run.addFileArg(run.captureStdErr(.{}));
check_run.addFileArg(.{ .lazy_path = run.captureStdErr(.{}) });
check_run.expectExitCode(0);
check_run.addCheck(.{ .expect_stdout_match = expect_stderr });

View file

@ -28,16 +28,16 @@ pub fn build(b: *std.Build) void {
}),
});
const run = b.addRunArtifact(main);
run.addArtifactArg(child);
run.addArtifactArg(.{ .artifact = child });
run.expectExitCode(0);
// Use a temporary directory within the cache as the CWD to test
// spawning the child using a path that contains a leading `..` component.
const run_relative = b.addRunArtifact(main);
run_relative.addArtifactArg(child);
run_relative.addArtifactArg(.{ .artifact = child });
const write_tmp_dir = b.addWriteFiles();
const tmp_cwd = write_tmp_dir.getDirectory();
run_relative.addDirectoryArg(tmp_cwd);
run_relative.addDirectoryArg(.{ .lazy_path = tmp_cwd });
run_relative.setCwd(tmp_cwd);
run_relative.expectExitCode(0);

View file

@ -98,8 +98,8 @@ fn addCheck(
const expected_path = b.fmt("expected_{s}", .{ch.include_path});
const run_check = b.addRunArtifact(check_exe);
run_check.addFileArg(ch.getOutputFile());
run_check.addFileArg(b.path(expected_path));
run_check.addFileArg(.{ .lazy_path = ch.getOutputFile() });
run_check.addFileArg(.{ .lazy_path = b.path(expected_path) });
return &run_check.step;
}

View file

@ -16,7 +16,9 @@ pub fn build(b: *std.Build) void {
.target = target,
}),
});
const generated = b.addRunArtifact(touch).addOutputFileArg("subdir" ++ std.fs.path.sep_str ++ "generated.txt");
const generated = b.addRunArtifact(touch).addOutputFileArg(
.{ .basename = "subdir" ++ std.fs.path.sep_str ++ "generated.txt" },
);
const exists_in = b.addExecutable(.{
.name = "exists_in",
@ -81,7 +83,7 @@ fn addTestRun(
args: []const []const u8,
) void {
const run = test_step.owner.addRunArtifact(exe);
run.addDirectoryArg(dirname);
run.addDirectoryArg(.{ .lazy_path = dirname });
run.addArgs(args);
run.expectExitCode(0);
test_step.dependOn(&run.step);

View file

@ -35,8 +35,8 @@ pub fn build(b: *std.Build) !void {
});
const diff_cmd = b.addRunArtifact(check_differ_exe);
diff_cmd.addFileArg(exe_foo.getEmittedBin());
diff_cmd.addFileArg(exe_bar.getEmittedBin());
diff_cmd.addFileArg(.{ .lazy_path = exe_foo.getEmittedBin() });
diff_cmd.addFileArg(.{ .lazy_path = exe_bar.getEmittedBin() });
diff_cmd.expectExitCode(0);
const test_step = b.step("test", "Test it");

View file

@ -31,7 +31,7 @@ pub fn build(b: *std.Build) void {
});
const run = b.addRunArtifact(main);
run.addArtifactArg(lib);
run.addArtifactArg(.{ .artifact = lib });
run.skip_foreign_checks = true;
run.expectExitCode(0);

View file

@ -21,7 +21,7 @@ pub fn build(b: *Build) void {
fn addCheck(b: *Build, exe: *Build.Step.Compile, cwd_name: []const u8, opt_cwd: ?Build.LazyPath) *Build.Step {
const run = b.addRunArtifact(exe);
if (opt_cwd) |cwd| run.setCwd(cwd);
run.addFileArg(b.path("file_that_exists.txt"));
run.addFileArg(.{ .lazy_path = b.path("file_that_exists.txt") });
run.setName(b.fmt("check in '{s}'", .{cwd_name}));
run.expectExitCode(0);
return &run.step;

View file

@ -28,8 +28,8 @@ pub fn build(b: *std.Build) void {
// ensure that "second" runs after "first"
run_random_with_sideeffects_second.step.dependOn(&run_random_with_sideeffects_first.step);
const first_output = run_random_with_sideeffects_first.addOutputFileArg("a.txt");
const second_output = run_random_with_sideeffects_second.addOutputFileArg("a.txt");
const first_output = run_random_with_sideeffects_first.addOutputFileArg(.{ .basename = "a.txt" });
const second_output = run_random_with_sideeffects_second.addOutputFileArg(.{ .basename = "a.txt" });
const expect_uncached_dependencies = CheckOutputCaching.init(b, false, &.{ first_output, second_output });
test_step.dependOn(&expect_uncached_dependencies.step);
@ -52,8 +52,8 @@ pub fn build(b: *std.Build) void {
run_random_without_sideeffects_2.step.dependOn(&run_random_without_sideeffects_1.step);
const first_output = run_random_without_sideeffects_1.addOutputFileArg("a.txt");
const second_output = run_random_without_sideeffects_2.addOutputFileArg("a.txt");
const first_output = run_random_without_sideeffects_1.addOutputFileArg(.{ .basename = "a.txt" });
const second_output = run_random_without_sideeffects_2.addOutputFileArg(.{ .basename = "a.txt" });
const expect_cached_dependencies = CheckOutputCaching.init(b, true, &.{second_output});
test_step.dependOn(&expect_cached_dependencies.step);

View file

@ -17,7 +17,7 @@ pub fn build(b: *std.Build) void {
});
const create_first = b.addRunArtifact(create_file_exe);
const first_dir = create_first.addOutputDirectoryArg("first");
const first_dir = create_first.addOutputDirectoryArg(.{ .basename = "first" });
create_first.addArg("hello1.txt");
test_step.dependOn(&b.addCheckFile(first_dir.path(b, "hello1.txt"), .{ .expected_matches = &.{
std.fs.path.sep_str ++
@ -29,7 +29,7 @@ pub fn build(b: *std.Build) void {
} }).step);
const create_second = b.addRunArtifact(create_file_exe);
const second_dir = create_second.addPrefixedOutputDirectoryArg("--dir=", "second");
const second_dir = create_second.addOutputDirectoryArg(.{ .prefix = "--dir=", .basename = "second" });
create_second.addArg("hello2.txt");
test_step.dependOn(&b.addCheckFile(second_dir.path(b, "hello2.txt"), .{ .expected_matches = &.{
std.fs.path.sep_str ++

View file

@ -32,13 +32,13 @@ pub fn build(b: *std.Build) void {
});
var run_create_symlink = b.addRunArtifact(create_symlink_exe);
run_create_symlink.addArtifactArg(main);
const symlink_path = run_create_symlink.addOutputFileArg("main-symlink");
run_create_symlink.addArtifactArg(.{ .artifact = main });
const symlink_path = run_create_symlink.addOutputFileArg(.{ .basename = "main-symlink" });
run_create_symlink.expectExitCode(0);
run_create_symlink.skip_foreign_checks = true;
var run_from_symlink = std.Build.Step.Run.create(b, "run symlink");
run_from_symlink.addFileArg(symlink_path);
run_from_symlink.addFileArg(.{ .lazy_path = symlink_path });
run_from_symlink.expectExitCode(0);
run_from_symlink.skip_foreign_checks = true;
run_from_symlink.step.dependOn(&run_create_symlink.step);

View file

@ -59,7 +59,7 @@ pub fn build(b: *std.Build) !void {
const run_gnu = b.addRunArtifact(fuzz);
run_gnu.setName("fuzz-gnu");
run_gnu.addArtifactArg(verify_gnu);
run_gnu.addArtifactArg(.{ .artifact = verify_gnu });
run_gnu.addArgs(&.{ fuzz_iterations_arg, fuzz_seed_arg });
run_gnu.expectExitCode(0);
@ -105,7 +105,7 @@ pub fn build(b: *std.Build) !void {
const run_msvc = b.addRunArtifact(fuzz);
run_msvc.setName("fuzz-msvc");
run_msvc.addArtifactArg(verify_msvc);
run_msvc.addArtifactArg(.{ .artifact = verify_msvc });
run_msvc.addArgs(&.{ fuzz_iterations_arg, fuzz_seed_arg });
run_msvc.expectExitCode(0);

View file

@ -29,7 +29,7 @@ pub fn build(b: *std.Build) !void {
});
const run = b.addRunArtifact(test_exe);
run.addArtifactArg(echo_args);
run.addArtifactArg(.{ .artifact = echo_args });
run.expectExitCode(0);
run.skip_foreign_checks = true;
@ -55,7 +55,7 @@ pub fn build(b: *std.Build) !void {
const fuzz_seed_arg = std.fmt.allocPrint(b.allocator, "{}", .{fuzz_seed}) catch @panic("oom");
const fuzz_run = b.addRunArtifact(fuzz);
fuzz_run.addArtifactArg(echo_args);
fuzz_run.addArtifactArg(.{ .artifact = echo_args });
fuzz_run.addArgs(&.{ fuzz_iterations_arg, fuzz_seed_arg });
fuzz_run.expectExitCode(0);
fuzz_run.skip_foreign_checks = true;

View file

@ -29,7 +29,7 @@ pub fn build(b: *std.Build) void {
});
const run = b.addRunArtifact(main);
run.addArtifactArg(hello);
run.addArtifactArg(.{ .artifact = hello });
run.expectExitCode(0);
run.skip_foreign_checks = true;

View file

@ -2107,8 +2107,8 @@ pub fn addCliTests(b: *std.Build) *Step {
"-fno-emit-bin", "-fno-emit-h",
"-fstrip", "-OReleaseFast",
});
run.addFileArg(example_zig);
const example_s = run.addPrefixedOutputFileArg("-femit-asm=", "example.s");
run.addFileArg(.{ .lazy_path = example_zig });
const example_s = run.addOutputFileArg(.{ .prefix = "-femit-asm=", .basename = "example.s" });
const checkfile = b.addCheckFile(example_s, .{
.expected_matches = &.{
@ -2223,9 +2223,10 @@ pub fn addCliTests(b: *std.Build) *Step {
"-Dstring=hello",
});
run_test.addArg("--build-file");
run_test.addFileArg(b.path("test/cli/options/build.zig"));
run_test.addFileArg(.{ .lazy_path = b.path("test/cli/options/build.zig") });
run_test.addArg("--cache-dir");
run_test.addFileArg(.{ .cwd_relative = b.cache_root.join(b.allocator, &.{}) catch @panic("OOM") });
run_test.addFileArg(.{ .lazy_path = .{ .cwd_relative = b.cache_root.join(b.allocator, &.{}) catch @panic("OOM") } });
run_test.setName("test build options");
step.dependOn(&run_test.step);
@ -2687,7 +2688,7 @@ pub fn addIncrementalTests(b: *std.Build, test_step: *Step) !void {
run.setName(b.fmt("incr-check '{s}'", .{entry.basename}));
run.addArg(b.graph.zig_exe);
run.addFileArg(b.path("test/incremental/").path(b, entry.path));
run.addFileArg(.{ .lazy_path = b.path("test/incremental/").path(b, entry.path) });
run.addArgs(&.{ "--zig-lib-dir", b.fmt("{f}", .{b.graph.zig_lib_directory}) });
run.addCheck(.{ .expect_term = .{ .Exited = 0 } });