From 2ceeade99a40c4c15798bc2878ae3318c5a3710f Mon Sep 17 00:00:00 2001 From: Sahnvour Date: Sat, 12 Aug 2023 13:15:05 +0200 Subject: [PATCH] std.Build: add support for deps .d file in Step.Run --- lib/std/Build/Cache.zig | 15 +++------------ lib/std/Build/Step/Run.zig | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 12 deletions(-) diff --git a/lib/std/Build/Cache.zig b/lib/std/Build/Cache.zig index b0db88692c..b4b45d9135 100644 --- a/lib/std/Build/Cache.zig +++ b/lib/std/Build/Cache.zig @@ -778,20 +778,11 @@ pub const Manifest = struct { var it: DepTokenizer = .{ .bytes = dep_file_contents }; - // Skip first token: target. - switch (it.next() orelse return) { // Empty dep file OK. - .target, .target_must_resolve, .prereq => {}, - else => |err| { - try err.printError(error_buf.writer()); - log.err("failed parsing {s}: {s}", .{ dep_file_basename, error_buf.items }); - return error.InvalidDepFile; - }, - } - // Process 0+ preqreqs. - // Clang is invoked in single-source mode so we never get more targets. while (true) { switch (it.next() orelse return) { - .target, .target_must_resolve => return, + // We don't care about targets, we only want the prereqs + // Clang is invoked in single-source mode but other programs may not + .target, .target_must_resolve => {}, .prereq => |file_path| try self.addFilePost(file_path), else => |err| { try err.printError(error_buf.writer()); diff --git a/lib/std/Build/Step/Run.zig b/lib/std/Build/Step/Run.zig index 4bb474f4da..02489782b2 100644 --- a/lib/std/Build/Step/Run.zig +++ b/lib/std/Build/Step/Run.zig @@ -77,6 +77,8 @@ max_stdio_size: usize = 10 * 1024 * 1024, captured_stdout: ?*Output = null, captured_stderr: ?*Output = null, +dep_output_file: ?*Output = null, + has_side_effects: bool = false, pub const StdIn = union(enum) { @@ -240,6 +242,33 @@ pub fn addPrefixedDirectoryArg(self: *Run, prefix: []const u8, directory_source: directory_source.addStepDependencies(&self.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(self: *Run, basename: []const u8) std.Build.LazyPath { + return self.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(self: *Run, prefix: []const u8, basename: []const u8) void { + assert(self.dep_output_file == null); + + const b = self.step.owner; + + const dep_file = b.allocator.create(Output) catch @panic("OOM"); + dep_file.* = .{ + .prefix = b.dupe(prefix), + .basename = b.dupe(basename), + .generated_file = .{ .step = &self.step }, + }; + + self.dep_output_file = dep_file; + + self.argv.append(.{ .output = dep_file }) catch @panic("OOM"); +} + pub fn addArg(self: *Run, arg: []const u8) void { self.argv.append(.{ .bytes = self.step.owner.dupe(arg) }) catch @panic("OOM"); } @@ -559,6 +588,9 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { try runCommand(self, argv_list.items, has_side_effects, &digest, prog_node); + if (self.dep_output_file) |dep_output_file| + try man.addDepFilePost(std.fs.cwd(), dep_output_file.generated_file.getPath()); + try step.writeManifest(&man); }