Skip to content

Commit 0e8f766

Browse files
committed
feat(Build.Step.Run): addModifyPathArg
1 parent b7d7446 commit 0e8f766

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
@@ -142,6 +142,7 @@ pub const Arg = union(enum) {
142142
bytes: []u8,
143143
output_file: *Output,
144144
output_directory: *Output,
145+
modify_path: *ModifyPath,
145146
};
146147

147148
pub const PrefixedArtifact = struct {
@@ -166,6 +167,11 @@ pub const Output = struct {
166167
basename: []const u8,
167168
};
168169

170+
pub const ModifyPath = struct {
171+
lazy_path: std.Build.LazyPath,
172+
output: Output,
173+
};
174+
169175
pub fn create(owner: *std.Build, name: []const u8) *Run {
170176
const run = owner.allocator.create(Run) catch @panic("OOM");
171177
run.* = .{
@@ -422,6 +428,32 @@ pub fn addPrefixedDepFileOutputArg(run: *Run, prefix: []const u8, basename: []co
422428
return .{ .generated = .{ .file = &dep_file.generated_file } };
423429
}
424430

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

458490
const use_wine = b.enable_wine and b.graph.host.result.os.tag != .windows and use_wine: switch (run.argv.items[0]) {
459491
.artifact => |p| p.artifact.rootModuleTarget().os.tag == .windows,
460-
.lazy_path => |p| {
492+
inline .lazy_path, .modify_path => |p| {
461493
switch (p.lazy_path) {
462494
.generated => |g| if (g.file.step.cast(Step.Compile)) |cs| break :use_wine cs.rootModuleTarget().os.tag == .windows,
463495
else => {},
@@ -604,7 +636,7 @@ fn hasAnyOutputArgs(run: Run) bool {
604636
if (run.captured_stdout != null) return true;
605637
if (run.captured_stderr != null) return true;
606638
for (run.argv.items) |arg| switch (arg) {
607-
.output_file, .output_directory => return true,
639+
.output_file, .output_directory, .modify_path => return true,
608640
else => continue,
609641
};
610642
return false;
@@ -668,6 +700,10 @@ const IndexedOutput = struct {
668700
tag: @typeInfo(Arg).@"union".tag_type.?,
669701
output: *Output,
670702
};
703+
const ModifiedPathOutput = struct {
704+
modify_path: *ModifyPath,
705+
resolved_path: []const u8,
706+
};
671707
fn make(step: *Step, options: Step.MakeOptions) !void {
672708
const prog_node = options.progress_node;
673709
const b = step.owner;
@@ -677,6 +713,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void {
677713

678714
var argv_list = std.ArrayList([]const u8).init(arena);
679715
var output_placeholders = std.ArrayList(IndexedOutput).init(arena);
716+
var modify_paths = std.ArrayList(ModifiedPathOutput).init(arena);
680717

681718
var man = b.graph.cache.obtain();
682719
defer man.deinit();
@@ -757,6 +794,16 @@ fn make(step: *Step, options: Step.MakeOptions) !void {
757794
});
758795
_ = try argv_list.addOne();
759796
},
797+
.modify_path => |modify_path| {
798+
const file_path = modify_path.lazy_path.getPath3(b, step);
799+
const resolved_path = run.convertPathArg(file_path);
800+
man.hash.addBytes(resolved_path);
801+
try argv_list.append(resolved_path);
802+
try modify_paths.append(.{
803+
.modify_path = modify_path,
804+
.resolved_path = resolved_path,
805+
});
806+
},
760807
}
761808
}
762809

@@ -797,6 +844,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void {
797844
try populateGeneratedPaths(
798845
arena,
799846
output_placeholders.items,
847+
modify_paths.items,
800848
run.captured_stdout,
801849
run.captured_stderr,
802850
b.cache_root,
@@ -817,6 +865,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void {
817865
try populateGeneratedPaths(
818866
arena,
819867
output_placeholders.items,
868+
modify_paths.items,
820869
run.captured_stdout,
821870
run.captured_stderr,
822871
b.cache_root,
@@ -931,6 +980,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void {
931980
try populateGeneratedPaths(
932981
arena,
933982
output_placeholders.items,
983+
modify_paths.items,
934984
run.captured_stdout,
935985
run.captured_stderr,
936986
b.cache_root,
@@ -972,7 +1022,7 @@ pub fn rerunInFuzzMode(
9721022
run.convertPathArg(.{ .root_dir = .cwd(), .sub_path = file_path }),
9731023
}));
9741024
},
975-
.output_file, .output_directory => unreachable,
1025+
.output_file, .output_directory, .modify_path => unreachable,
9761026
}
9771027
}
9781028
const has_side_effects = false;
@@ -987,6 +1037,7 @@ pub fn rerunInFuzzMode(
9871037
fn populateGeneratedPaths(
9881038
arena: std.mem.Allocator,
9891039
output_placeholders: []const IndexedOutput,
1040+
modify_paths: []const ModifiedPathOutput,
9901041
captured_stdout: ?*Output,
9911042
captured_stderr: ?*Output,
9921043
cache_root: Build.Cache.Directory,
@@ -998,6 +1049,10 @@ fn populateGeneratedPaths(
9981049
});
9991050
}
10001051

1052+
for (modify_paths) |modify_path| {
1053+
modify_path.modify_path.output.generated_file.path = modify_path.resolved_path;
1054+
}
1055+
10011056
if (captured_stdout) |output| {
10021057
output.generated_file.path = try cache_root.join(arena, &.{
10031058
"o", digest, output.basename,

0 commit comments

Comments
 (0)