Skip to content

Commit fd59400

Browse files
committed
feat(Build.Step.Run): addModifyPathArg
1 parent fd9cfc3 commit fd59400

File tree

1 file changed

+58
-3
lines changed

1 file changed

+58
-3
lines changed

lib/std/Build/Step/Run.zig

Lines changed: 58 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ pub const Arg = union(enum) {
145145
bytes: []u8,
146146
output_file: *Output,
147147
output_directory: *Output,
148+
modify_path: *ModifyPath,
148149
};
149150

150151
pub const PrefixedArtifact = struct {
@@ -169,6 +170,11 @@ pub const Output = struct {
169170
basename: []const u8,
170171
};
171172

173+
pub const ModifyPath = struct {
174+
lazy_path: std.Build.LazyPath,
175+
output: Output,
176+
};
177+
172178
pub fn create(owner: *std.Build, name: []const u8) *Run {
173179
const run = owner.allocator.create(Run) catch @panic("OOM");
174180
run.* = .{
@@ -426,6 +432,32 @@ pub fn addPrefixedDepFileOutputArg(run: *Run, prefix: []const u8, basename: []co
426432
return .{ .generated = .{ .file = &dep_file.generated_file } };
427433
}
428434

435+
/// Add a path argument for the child process to modify. The returned path is
436+
/// the same as the input path, but has a step dependency on this run step for
437+
/// use in other steps.
438+
///
439+
/// Related:
440+
/// * `addFileArg` - only serves as an input file for the child process.
441+
/// * `addOutputFileArg` - only serves as an output file for the child process.
442+
pub fn addModifyPathArg(run: *Run, lp: std.Build.LazyPath) std.Build.LazyPath {
443+
const b = run.step.owner;
444+
445+
const modify_path = b.allocator.create(ModifyPath) catch @panic("OOM");
446+
modify_path.* = .{
447+
.lazy_path = lp,
448+
.output = .{
449+
.prefix = "",
450+
.basename = "",
451+
.generated_file = .{ .step = &run.step },
452+
},
453+
};
454+
455+
run.has_side_effects = true;
456+
run.argv.append(b.allocator, .{ .modify_path = modify_path }) catch @panic("OOM");
457+
lp.addStepDependencies(&run.step);
458+
return .{ .generated = .{ .file = &modify_path.output.generated_file } };
459+
}
460+
429461
pub fn addArg(run: *Run, arg: []const u8) void {
430462
const b = run.step.owner;
431463
run.argv.append(b.allocator, .{ .bytes = b.dupe(arg) }) catch @panic("OOM");
@@ -461,7 +493,7 @@ pub fn addPathDir(run: *Run, search_path: []const u8) void {
461493

462494
const use_wine = b.enable_wine and b.graph.host.result.os.tag != .windows and use_wine: switch (run.argv.items[0]) {
463495
.artifact => |p| p.artifact.rootModuleTarget().os.tag == .windows,
464-
.lazy_path => |p| {
496+
inline .lazy_path, .modify_path => |p| {
465497
switch (p.lazy_path) {
466498
.generated => |g| if (g.file.step.cast(Step.Compile)) |cs| break :use_wine cs.rootModuleTarget().os.tag == .windows,
467499
else => {},
@@ -608,7 +640,7 @@ fn hasAnyOutputArgs(run: Run) bool {
608640
if (run.captured_stdout != null) return true;
609641
if (run.captured_stderr != null) return true;
610642
for (run.argv.items) |arg| switch (arg) {
611-
.output_file, .output_directory => return true,
643+
.output_file, .output_directory, .modify_path => return true,
612644
else => continue,
613645
};
614646
return false;
@@ -672,6 +704,10 @@ const IndexedOutput = struct {
672704
tag: @typeInfo(Arg).@"union".tag_type.?,
673705
output: *Output,
674706
};
707+
const ModifiedPathOutput = struct {
708+
modify_path: *ModifyPath,
709+
resolved_path: []const u8,
710+
};
675711
fn make(step: *Step, options: Step.MakeOptions) !void {
676712
const prog_node = options.progress_node;
677713
const b = step.owner;
@@ -681,6 +717,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void {
681717

682718
var argv_list = std.ArrayList([]const u8).init(arena);
683719
var output_placeholders = std.ArrayList(IndexedOutput).init(arena);
720+
var modify_paths = std.ArrayList(ModifiedPathOutput).init(arena);
684721

685722
var man = b.graph.cache.obtain();
686723
defer man.deinit();
@@ -761,6 +798,16 @@ fn make(step: *Step, options: Step.MakeOptions) !void {
761798
});
762799
_ = try argv_list.addOne();
763800
},
801+
.modify_path => |modify_path| {
802+
const file_path = modify_path.lazy_path.getPath3(b, step);
803+
const resolved_path = run.convertPathArg(file_path);
804+
man.hash.addBytes(resolved_path);
805+
try argv_list.append(resolved_path);
806+
try modify_paths.append(.{
807+
.modify_path = modify_path,
808+
.resolved_path = resolved_path,
809+
});
810+
},
764811
}
765812
}
766813

@@ -801,6 +848,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void {
801848
try populateGeneratedPaths(
802849
arena,
803850
output_placeholders.items,
851+
modify_paths.items,
804852
run.captured_stdout,
805853
run.captured_stderr,
806854
b.cache_root,
@@ -821,6 +869,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void {
821869
try populateGeneratedPaths(
822870
arena,
823871
output_placeholders.items,
872+
modify_paths.items,
824873
run.captured_stdout,
825874
run.captured_stderr,
826875
b.cache_root,
@@ -935,6 +984,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void {
935984
try populateGeneratedPaths(
936985
arena,
937986
output_placeholders.items,
987+
modify_paths.items,
938988
run.captured_stdout,
939989
run.captured_stderr,
940990
b.cache_root,
@@ -976,7 +1026,7 @@ pub fn rerunInFuzzMode(
9761026
run.convertPathArg(.{ .root_dir = .cwd(), .sub_path = file_path }),
9771027
}));
9781028
},
979-
.output_file, .output_directory => unreachable,
1029+
.output_file, .output_directory, .modify_path => unreachable,
9801030
}
9811031
}
9821032
const has_side_effects = false;
@@ -991,6 +1041,7 @@ pub fn rerunInFuzzMode(
9911041
fn populateGeneratedPaths(
9921042
arena: std.mem.Allocator,
9931043
output_placeholders: []const IndexedOutput,
1044+
modify_paths: []const ModifiedPathOutput,
9941045
captured_stdout: ?*Output,
9951046
captured_stderr: ?*Output,
9961047
cache_root: Build.Cache.Directory,
@@ -1002,6 +1053,10 @@ fn populateGeneratedPaths(
10021053
});
10031054
}
10041055

1056+
for (modify_paths) |modify_path| {
1057+
modify_path.modify_path.output.generated_file.path = modify_path.resolved_path;
1058+
}
1059+
10051060
if (captured_stdout) |output| {
10061061
output.generated_file.path = try cache_root.join(arena, &.{
10071062
"o", digest, output.basename,

0 commit comments

Comments
 (0)