mirror of
https://github.com/ziglang/zig.git
synced 2026-02-13 12:59:04 +00:00
std.Build.Step.Run: fix depfile support
This commit is contained in:
parent
26e27f5f64
commit
65878c16ee
@ -249,7 +249,7 @@ pub fn addDepFileOutputArg(self: *Run, basename: []const u8) std.Build.LazyPath
|
||||
/// 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 {
|
||||
pub fn addPrefixedDepFileOutputArg(self: *Run, prefix: []const u8, basename: []const u8) std.Build.LazyPath {
|
||||
assert(self.dep_output_file == null);
|
||||
|
||||
const b = self.step.owner;
|
||||
@ -264,6 +264,8 @@ pub fn addPrefixedDepFileOutputArg(self: *Run, prefix: []const u8, basename: []c
|
||||
self.dep_output_file = dep_file;
|
||||
|
||||
self.argv.append(.{ .output = dep_file }) catch @panic("OOM");
|
||||
|
||||
return .{ .generated = &dep_file.generated_file };
|
||||
}
|
||||
|
||||
pub fn addArg(self: *Run, arg: []const u8) void {
|
||||
@ -454,6 +456,10 @@ fn checksContainStderr(checks: []const StdIo.Check) bool {
|
||||
return false;
|
||||
}
|
||||
|
||||
const IndexedOutput = struct {
|
||||
index: usize,
|
||||
output: *Output,
|
||||
};
|
||||
fn make(step: *Step, prog_node: *std.Progress.Node) !void {
|
||||
const b = step.owner;
|
||||
const arena = b.allocator;
|
||||
@ -461,10 +467,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
|
||||
const has_side_effects = self.hasSideEffects();
|
||||
|
||||
var argv_list = ArrayList([]const u8).init(arena);
|
||||
var output_placeholders = ArrayList(struct {
|
||||
index: usize,
|
||||
output: *Output,
|
||||
}).init(arena);
|
||||
var output_placeholders = ArrayList(IndexedOutput).init(arena);
|
||||
|
||||
var man = b.cache.obtain();
|
||||
defer man.deinit();
|
||||
@ -546,32 +549,25 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
|
||||
if (try step.cacheHit(&man)) {
|
||||
// cache hit, skip running command
|
||||
const digest = man.final();
|
||||
for (output_placeholders.items) |placeholder| {
|
||||
placeholder.output.generated_file.path = try b.cache_root.join(arena, &.{
|
||||
"o", &digest, placeholder.output.basename,
|
||||
});
|
||||
}
|
||||
|
||||
if (self.captured_stdout) |output| {
|
||||
output.generated_file.path = try b.cache_root.join(arena, &.{
|
||||
"o", &digest, output.basename,
|
||||
});
|
||||
}
|
||||
|
||||
if (self.captured_stderr) |output| {
|
||||
output.generated_file.path = try b.cache_root.join(arena, &.{
|
||||
"o", &digest, output.basename,
|
||||
});
|
||||
}
|
||||
try populateGeneratedPaths(
|
||||
arena,
|
||||
output_placeholders.items,
|
||||
self.captured_stdout,
|
||||
self.captured_stderr,
|
||||
b.cache_root,
|
||||
&digest,
|
||||
);
|
||||
|
||||
step.result_cached = true;
|
||||
return;
|
||||
}
|
||||
|
||||
const digest = man.final();
|
||||
const rand_int = std.crypto.random.int(u64);
|
||||
const tmp_dir_path = "tmp" ++ fs.path.sep_str ++ std.Build.hex64(rand_int);
|
||||
|
||||
for (output_placeholders.items) |placeholder| {
|
||||
const output_components = .{ "o", &digest, placeholder.output.basename };
|
||||
const output_components = .{ tmp_dir_path, placeholder.output.basename };
|
||||
const output_sub_path = try fs.path.join(arena, &output_components);
|
||||
const output_sub_dir_path = fs.path.dirname(output_sub_path).?;
|
||||
b.cache_root.handle.makePath(output_sub_dir_path) catch |err| {
|
||||
@ -588,12 +584,83 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
|
||||
argv_list.items[placeholder.index] = cli_arg;
|
||||
}
|
||||
|
||||
try runCommand(self, argv_list.items, has_side_effects, &digest, prog_node);
|
||||
try runCommand(self, argv_list.items, has_side_effects, tmp_dir_path, prog_node);
|
||||
|
||||
if (self.dep_output_file) |dep_output_file|
|
||||
try man.addDepFilePost(std.fs.cwd(), dep_output_file.generated_file.getPath());
|
||||
|
||||
const digest = man.final();
|
||||
|
||||
const any_output = output_placeholders.items.len > 0 or
|
||||
self.captured_stdout != null or self.captured_stderr != null;
|
||||
|
||||
// Rename into place
|
||||
if (any_output) {
|
||||
const o_sub_path = "o" ++ fs.path.sep_str ++ &digest;
|
||||
|
||||
b.cache_root.handle.rename(tmp_dir_path, o_sub_path) catch |err| {
|
||||
if (err == error.PathAlreadyExists) {
|
||||
b.cache_root.handle.deleteTree(o_sub_path) catch |del_err| {
|
||||
return step.fail("unable to remove dir '{}'{s}: {s}", .{
|
||||
b.cache_root,
|
||||
tmp_dir_path,
|
||||
@errorName(del_err),
|
||||
});
|
||||
};
|
||||
b.cache_root.handle.rename(tmp_dir_path, o_sub_path) catch |retry_err| {
|
||||
return step.fail("unable to rename dir '{}{s}' to '{}{s}': {s}", .{
|
||||
b.cache_root, tmp_dir_path,
|
||||
b.cache_root, o_sub_path,
|
||||
@errorName(retry_err),
|
||||
});
|
||||
};
|
||||
} else {
|
||||
return step.fail("unable to rename dir '{}{s}' to '{}{s}': {s}", .{
|
||||
b.cache_root, tmp_dir_path,
|
||||
b.cache_root, o_sub_path,
|
||||
@errorName(err),
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
try step.writeManifest(&man);
|
||||
|
||||
try populateGeneratedPaths(
|
||||
arena,
|
||||
output_placeholders.items,
|
||||
self.captured_stdout,
|
||||
self.captured_stderr,
|
||||
b.cache_root,
|
||||
&digest,
|
||||
);
|
||||
}
|
||||
|
||||
fn populateGeneratedPaths(
|
||||
arena: std.mem.Allocator,
|
||||
output_placeholders: []const IndexedOutput,
|
||||
captured_stdout: ?*Output,
|
||||
captured_stderr: ?*Output,
|
||||
cache_root: Build.Cache.Directory,
|
||||
digest: *const Build.Cache.HexDigest,
|
||||
) !void {
|
||||
for (output_placeholders) |placeholder| {
|
||||
placeholder.output.generated_file.path = try cache_root.join(arena, &.{
|
||||
"o", digest, placeholder.output.basename,
|
||||
});
|
||||
}
|
||||
|
||||
if (captured_stdout) |output| {
|
||||
output.generated_file.path = try cache_root.join(arena, &.{
|
||||
"o", digest, output.basename,
|
||||
});
|
||||
}
|
||||
|
||||
if (captured_stderr) |output| {
|
||||
output.generated_file.path = try cache_root.join(arena, &.{
|
||||
"o", digest, output.basename,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
fn formatTerm(
|
||||
@ -645,7 +712,7 @@ fn runCommand(
|
||||
self: *Run,
|
||||
argv: []const []const u8,
|
||||
has_side_effects: bool,
|
||||
digest: ?*const [std.Build.Cache.hex_digest_len]u8,
|
||||
tmp_dir_path: ?[]const u8,
|
||||
prog_node: *std.Progress.Node,
|
||||
) !void {
|
||||
const step = &self.step;
|
||||
@ -816,7 +883,7 @@ fn runCommand(
|
||||
},
|
||||
}) |stream| {
|
||||
if (stream.captured) |output| {
|
||||
const output_components = .{ "o", digest.?, output.basename };
|
||||
const output_components = .{ tmp_dir_path.?, output.basename };
|
||||
const output_path = try b.cache_root.join(arena, &output_components);
|
||||
output.generated_file.path = output_path;
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user