authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-09-24 18:06:21-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-09-24 23:10:27-07:00
log4853ea1bda1131d4d57a50eaa8209d90b71c8537
treee6af587aa13af0dca95a7bb553ee3dd4706a0738
parent5b9147ed59b22edf7f891cf30e8b77223121da4f

Maker: store generated files differently

in preparation for sending them over the build server protocol (#36403), they are now stored in the same format in memory: one byte for prefix followed by the relative path.

11 files changed, 209 insertions(+), 156 deletions(-)

lib/compiler/Maker.zig+118-13
...@@ -49,7 +49,13 @@ scanned_config: *const ScannedConfig,...@@ -49,7 +49,13 @@ scanned_config: *const ScannedConfig,
49/// system watching does not need to make any special cases, and to avoid more49/// system watching does not need to make any special cases, and to avoid more
50/// OS-specific logic in file system watching implementation.50/// OS-specific logic in file system watching implementation.
51steps: []Step,51steps: []Step,
52generated_files: []Path,52/// Reserved space for all the file paths that are determined at runtime when the associated Step logic runs.
53/// Each element is individually allocated so that steps can access the data without synchronization, and so
54/// that steps can be arbitrarily re-run independently from each other.
55/// Each element is optional because a step might populate any number of generated file paths before ultimately
56/// failing. An element being non-null does not imply that the generated file was successfully generated. Only
57/// the Step success state indicates that information.
58generated_files: []GeneratedFile,
53run_args: ?[]const []const u8,59run_args: ?[]const []const u8,
5460
55available_rss: u64,61available_rss: u64,
...@@ -121,6 +127,38 @@ const MultilineErrors = enum { indent, newline, none };...@@ -121,6 +127,38 @@ const MultilineErrors = enum { indent, newline, none };
121const Summary = enum { all, new, failures, line, none };127const Summary = enum { all, new, failures, line, none };
122const PrintConfiguration = enum { none, zon, path };128const PrintConfiguration = enum { none, zon, path };
123129
130const GeneratedFile = struct {
131 data: ?[]const u8,
132
133 const Unpacked = struct {
134 prefix: Server.Message.PathPrefix,
135 sub_path: []const u8,
136 };
137
138 fn unpack(gf: GeneratedFile) ?Unpacked {
139 const slice = gf.data orelse return null;
140 return .{
141 .prefix = @fromBackingInt(slice[0]),
142 .sub_path = slice[1..],
143 };
144 }
145
146 fn toPath(gf: GeneratedFile, graph: *const Graph) ?Path {
147 const unpacked = unpack(gf) orelse return null;
148 return .{
149 .root_dir = prefixToDirectory(graph, unpacked.prefix),
150 .sub_path = unpacked.sub_path,
151 };
152 }
153
154 fn clear(gf: *GeneratedFile, gpa: Allocator) void {
155 if (gf.data) |data| {
156 gpa.free(data);
157 gf.data = null;
158 }
159 }
160};
161
124/// Used to build the -M flags to pass to build-exe.162/// Used to build the -M flags to pass to build-exe.
125pub const CliModule = struct {163pub const CliModule = struct {
126 name: []const u8,164 name: []const u8,
...@@ -2344,7 +2382,8 @@ fn prepare(...@@ -2344,7 +2382,8 @@ fn prepare(
2344 // Extra step at the end which is the autogenerated placeholder2382 // Extra step at the end which is the autogenerated placeholder
2345 // step which indicates that we need to reconfigure.2383 // step which indicates that we need to reconfigure.
2346 maker.steps = try arena.alloc(Step, c.steps.len + 1);2384 maker.steps = try arena.alloc(Step, c.steps.len + 1);
2347 maker.generated_files = try arena.alloc(Path, c.generated_files_len);2385 maker.generated_files = try arena.alloc(GeneratedFile, c.generated_files_len);
2386 @memset(maker.generated_files, .{ .data = null });
23482387
2349 // The last element is a reserved special pseudostep which contains the2388 // The last element is a reserved special pseudostep which contains the
2350 // watch inputs for the configurer executable.2389 // watch inputs for the configurer executable.
...@@ -2676,6 +2715,7 @@ fn deinit(maker: *Maker) void {...@@ -2676,6 +2715,7 @@ fn deinit(maker: *Maker) void {
2676 const gpa = maker.gpa;2715 const gpa = maker.gpa;
2677 const io = maker.graph.io;2716 const io = maker.graph.io;
2678 for (maker.steps) |*step| step.deinit(gpa, io);2717 for (maker.steps) |*step| step.deinit(gpa, io);
2718 for (maker.generated_files) |*gf| gf.clear(gpa);
2679 maker.memory_blocked_steps.deinit(gpa);2719 maker.memory_blocked_steps.deinit(gpa);
2680 maker.initial_steps.deinit(gpa);2720 maker.initial_steps.deinit(gpa);
2681 maker.step_stack.deinit(gpa);2721 maker.step_stack.deinit(gpa);
...@@ -2787,7 +2827,8 @@ fn makeStep(...@@ -2787,7 +2827,8 @@ fn makeStep(
2787 if (maker.web_server) |ws| {2827 if (maker.web_server) |ws| {
2788 ws.updateStepStatus(step_index, if (success) .success else .failure);2828 ws.updateStepStatus(step_index, if (success) .success else .failure);
2789 }2829 }
2790 if (maker.protocol_server != null) {2830 if (maker.protocol_server) |s| {
2831 // https://codeberg.org/ziglang/zig/issues/36938
2791 maker.protocol_server_mutex.lockUncancelable(io);2832 maker.protocol_server_mutex.lockUncancelable(io);
2792 defer maker.protocol_server_mutex.unlock(io);2833 defer maker.protocol_server_mutex.unlock(io);
27932834
...@@ -2800,11 +2841,8 @@ fn makeStep(...@@ -2800,11 +2841,8 @@ fn makeStep(
2800 .dependency_skipped, .skipped => .skipped,2841 .dependency_skipped, .skipped => .skipped,
2801 .skipped_oom => .skipped_oom,2842 .skipped_oom => .skipped_oom,
2802 };2843 };
2803 serveBuildStepCompleted(2844 serveBuildStepCompleted(maker, step_index, status, s) catch |err|
2804 maker,2845 std.debug.panic("TODO propagate error when failing to send protocol message: {t}", .{err});
2805 step_index,
2806 status,
2807 ) catch |err| std.debug.panic("TODO propagate error when failing to send protocol message: {t}", .{err});
2808 }2846 }
28092847
2810 if (!success) std.Progress.setStatus(.failure_working);2848 if (!success) std.Progress.setStatus(.failure_working);
...@@ -3366,7 +3404,7 @@ fn cleanTmpFiles(maker: *Maker, steps: []const Configuration.Step.Index) void {...@@ -3366,7 +3404,7 @@ fn cleanTmpFiles(maker: *Maker, steps: []const Configuration.Step.Index) void {
3366 if (wf.flags.mode != .tmp) continue;3404 if (wf.flags.mode != .tmp) continue;
3367 const step = maker.stepByIndex(step_index);3405 const step = maker.stepByIndex(step_index);
3368 if (step.state != .success) continue;3406 if (step.state != .success) continue;
3369 const tmp_path = generatedPath(maker, wf.generated_directory).*;3407 const tmp_path = generatedPath(maker, wf.generated_directory);
3370 tmp_path.root_dir.handle.deleteTree(io, tmp_path.subPathOrDot()) catch |err|3408 tmp_path.root_dir.handle.deleteTree(io, tmp_path.subPathOrDot()) catch |err|
3371 log.warn("failed to delete temporary path {f}: {t}", .{ tmp_path, err });3409 log.warn("failed to delete temporary path {f}: {t}", .{ tmp_path, err });
3372 }3410 }
...@@ -3391,8 +3429,8 @@ fn serveBuildStepCompleted(...@@ -3391,8 +3429,8 @@ fn serveBuildStepCompleted(
3391 maker: *Maker,3429 maker: *Maker,
3392 step_index: Configuration.Step.Index,3430 step_index: Configuration.Step.Index,
3393 status: Server.Message.BuildStepCompleted.Status,3431 status: Server.Message.BuildStepCompleted.Status,
3432 s: *Server,
3394) !void {3433) !void {
3395 const s: *Server = maker.protocol_server.?;
3396 const step = maker.stepByIndex(step_index);3434 const step = maker.stepByIndex(step_index);
3397 const error_bundle = step.result_error_bundle;3435 const error_bundle = step.result_error_bundle;
33983436
...@@ -3434,7 +3472,7 @@ pub fn resolveLazyPath(...@@ -3434,7 +3472,7 @@ pub fn resolveLazyPath(
3434 .source_path => |sp| try packagePath(maker, arena, sp.owner, sp.sub_path.slice(c)),3472 .source_path => |sp| try packagePath(maker, arena, sp.owner, sp.sub_path.slice(c)),
3435 .relative => |relative| relativePath(maker, arena, relative),3473 .relative => |relative| relativePath(maker, arena, relative),
3436 .generated => |gen| {3474 .generated => |gen| {
3437 const base = generatedPath(maker, gen.index).*;3475 const base = generatedPath(maker, gen.index);
3438 var file_path = base;3476 var file_path = base;
3439 for (0..gen.flags.up) |_| {3477 for (0..gen.flags.up) |_| {
3440 file_path.sub_path = Dir.path.dirname(file_path.sub_path) orelse {3478 file_path.sub_path = Dir.path.dirname(file_path.sub_path) orelse {
...@@ -3485,10 +3523,67 @@ pub fn resolveLazyPathIndexAbs(...@@ -3485,10 +3523,67 @@ pub fn resolveLazyPathIndexAbs(
3485 return resolveLazyPathAbs(maker, arena, lazy_path_index.get(c), asking_step_index);3523 return resolveLazyPathAbs(maker, arena, lazy_path_index.get(c), asking_step_index);
3486}3524}
34873525
3488pub fn generatedPath(maker: *const Maker, index: Configuration.GeneratedFileIndex) *Path {3526pub fn generatedFile(maker: *const Maker, index: Configuration.GeneratedFileIndex) *GeneratedFile {
3489 return &maker.generated_files[@backingInt(index)];3527 return &maker.generated_files[@backingInt(index)];
3490}3528}
34913529
3530pub fn generatedPath(maker: *const Maker, index: Configuration.GeneratedFileIndex) Path {
3531 return generatedFile(maker, index).toPath(maker.graph).?;
3532}
3533
3534pub fn setGeneratedPath(
3535 maker: *Maker,
3536 index: Configuration.GeneratedFileIndex,
3537 prefix: Server.Message.PathPrefix,
3538 sub_paths: []const []const u8,
3539) Allocator.Error!Path {
3540 const gpa = maker.gpa;
3541 const graph = maker.graph;
3542 assert(sub_paths.len != 0);
3543
3544 var buffer: std.ArrayList(u8) = .empty;
3545 defer buffer.deinit(gpa);
3546 try buffer.append(gpa, @backingInt(prefix));
3547 for (sub_paths) |sub_path| {
3548 try buffer.ensureUnusedCapacity(gpa, sub_path.len + 1);
3549 buffer.appendSliceAssumeCapacity(sub_path);
3550 while (Dir.path.isSep(buffer.items[buffer.items.len - 1]))
3551 buffer.items.len -= 1;
3552 buffer.appendAssumeCapacity(Dir.path.sep);
3553 }
3554 assert(buffer.pop().? == Dir.path.sep);
3555 try buffer.shrinkToLen(gpa);
3556
3557 const sub_path = buffer.toOwnedSliceAssert();
3558 const ptr = generatedFile(maker, index);
3559 ptr.clear(gpa);
3560 ptr.* = .{ .data = sub_path };
3561 return .{
3562 .root_dir = prefixToDirectory(graph, prefix),
3563 .sub_path = sub_path[1..],
3564 };
3565}
3566
3567/// Prefer to use `setGeneratedPath` where possible to keep parent directory information intact.
3568pub fn setGeneratedPathPath(
3569 maker: *Maker,
3570 index: Configuration.GeneratedFileIndex,
3571 path: Path,
3572) Allocator.Error!Path {
3573 const graph = maker.graph;
3574 if (path.root_dir.eql(graph.local_cache_root)) {
3575 return setGeneratedPath(maker, index, .local_cache, &.{path.sub_path});
3576 } else if (path.root_dir.eql(graph.global_cache_root)) {
3577 return setGeneratedPath(maker, index, .global_cache, &.{path.sub_path});
3578 } else if (path.root_dir.eql(graph.zig_lib_directory)) {
3579 return setGeneratedPath(maker, index, .zig_lib, &.{path.sub_path});
3580 } else if (path.root_dir.eql(graph.build_root_directory)) {
3581 return setGeneratedPath(maker, index, .build_root, &.{path.sub_path});
3582 } else {
3583 return setGeneratedPath(maker, index, .cwd, &.{path.sub_path});
3584 }
3585}
3586
3492pub fn packagePath(3587pub fn packagePath(
3493 maker: *const Maker,3588 maker: *const Maker,
3494 arena: Allocator,3589 arena: Allocator,
...@@ -3600,7 +3695,7 @@ pub fn installGenerated(...@@ -3600,7 +3695,7 @@ pub fn installGenerated(
3600 dest_dir: Configuration.InstallDestDir,3695 dest_dir: Configuration.InstallDestDir,
3601 asking_step_index: Configuration.Step.Index,3696 asking_step_index: Configuration.Step.Index,
3602) !Dir.PrevStatus {3697) !Dir.PrevStatus {
3603 const src_path = generatedPath(maker, source).*;3698 const src_path = generatedPath(maker, source);
3604 const dest_dir_path = try resolveInstallDir(maker, arena, dest_dir);3699 const dest_dir_path = try resolveInstallDir(maker, arena, dest_dir);
3605 const dest_path = try dest_dir_path.join(arena, src_path.basename());3700 const dest_path = try dest_dir_path.join(arena, src_path.basename());
3606 return installPath(maker, arena, src_path, dest_path, asking_step_index);3701 return installPath(maker, arena, src_path, dest_path, asking_step_index);
...@@ -4170,3 +4265,13 @@ fn nextEnumArg(args: []const []const u8, i: *usize, comptime E: type) E {...@@ -4170,3 +4265,13 @@ fn nextEnumArg(args: []const []const u8, i: *usize, comptime E: type) E {
4170 const next_arg = nextArg(args, i) orelse fatalEnumHint(E, arg, null);4265 const next_arg = nextArg(args, i) orelse fatalEnumHint(E, arg, null);
4171 return stringToEnum(E, next_arg) orelse fatalEnumHint(E, arg, next_arg);4266 return stringToEnum(E, next_arg) orelse fatalEnumHint(E, arg, next_arg);
4172}4267}
4268
4269fn prefixToDirectory(graph: *const Graph, prefix: Server.Message.PathPrefix) Cache.Directory {
4270 return switch (prefix) {
4271 .cwd => .cwd(),
4272 .zig_lib => graph.zig_lib_directory,
4273 .local_cache => graph.local_cache_root,
4274 .global_cache => graph.global_cache_root,
4275 .build_root => graph.build_root_directory,
4276 };
4277}
lib/compiler/Maker/Step.zig+14-9
...@@ -460,6 +460,15 @@ pub const ZigProcess = struct {...@@ -460,6 +460,15 @@ pub const ZigProcess = struct {
460 }460 }
461};461};
462462
463pub const OptCacheDigest = struct {
464 bin: ?Cache.BinDigest,
465
466 pub fn toHex(ocd: *const OptCacheDigest) ?Cache.HexDigest {
467 const bin = ocd.bin orelse return null;
468 return Cache.binToHex(bin);
469 }
470};
471
463/// Assumes that argv contains `--listen=-` and that the process being spawned472/// Assumes that argv contains `--listen=-` and that the process being spawned
464/// is the zig compiler - the same version that compiled the build runner.473/// is the zig compiler - the same version that compiled the build runner.
465///474///
...@@ -470,7 +479,7 @@ pub fn evalZigProcess(...@@ -470,7 +479,7 @@ pub fn evalZigProcess(
470 argv: []const []const u8,479 argv: []const []const u8,
471 prog_node: std.Progress.Node,480 prog_node: std.Progress.Node,
472 watch: bool,481 watch: bool,
473) (Step.ExtendedMakeError || error{NeedCompileErrorCheck})!?Path {482) (Step.ExtendedMakeError || error{NeedCompileErrorCheck})!OptCacheDigest {
474 const s = maker.stepByIndex(step_index);483 const s = maker.stepByIndex(step_index);
475 const gpa = maker.gpa;484 const gpa = maker.gpa;
476 const graph = maker.graph;485 const graph = maker.graph;
...@@ -503,7 +512,7 @@ pub fn evalZigProcess(...@@ -503,7 +512,7 @@ pub fn evalZigProcess(
503 if (s.result_error_bundle.errorMessageCount() > 0)512 if (s.result_error_bundle.errorMessageCount() > 0)
504 return s.fail(maker, "{d} compilation errors", .{s.result_error_bundle.errorMessageCount()});513 return s.fail(maker, "{d} compilation errors", .{s.result_error_bundle.errorMessageCount()});
505514
506 if (s.result_error_msgs.items.len > 0 and result == null) {515 if (s.result_error_msgs.items.len > 0 and result.bin == null) {
507 // Crash detected.516 // Crash detected.
508 const term = zp.child.wait(io) catch |e| {517 const term = zp.child.wait(io) catch |e| {
509 return s.fail(maker, "unable to wait for {s}: {t}", .{ argv[0], e });518 return s.fail(maker, "unable to wait for {s}: {t}", .{ argv[0], e });
...@@ -578,7 +587,7 @@ pub fn evalZigProcess(...@@ -578,7 +587,7 @@ pub fn evalZigProcess(
578 return result;587 return result;
579}588}
580589
581fn zigProcessUpdate(step_index: Configuration.Step.Index, maker: *Maker, zp: *ZigProcess, watch: bool) !?Path {590fn zigProcessUpdate(step_index: Configuration.Step.Index, maker: *Maker, zp: *ZigProcess, watch: bool) !OptCacheDigest {
582 const s = maker.stepByIndex(step_index);591 const s = maker.stepByIndex(step_index);
583 const gpa = maker.gpa;592 const gpa = maker.gpa;
584 const graph = maker.graph;593 const graph = maker.graph;
...@@ -590,7 +599,7 @@ fn zigProcessUpdate(step_index: Configuration.Step.Index, maker: *Maker, zp: *Zi...@@ -590,7 +599,7 @@ fn zigProcessUpdate(step_index: Configuration.Step.Index, maker: *Maker, zp: *Zi
590 try sendMessage(io, zp.child.stdin.?, .update);599 try sendMessage(io, zp.child.stdin.?, .update);
591 if (!watch) try sendMessage(io, zp.child.stdin.?, .exit);600 if (!watch) try sendMessage(io, zp.child.stdin.?, .exit);
592601
593 var result: ?Path = null;602 var result: OptCacheDigest = .{ .bin = null };
594 var eos_err: error{EndOfStream}!void = {};603 var eos_err: error{EndOfStream}!void = {};
595604
596 var client: std.zig.Client = .{605 var client: std.zig.Client = .{
...@@ -632,11 +641,7 @@ fn zigProcessUpdate(step_index: Configuration.Step.Index, maker: *Maker, zp: *Zi...@@ -632,11 +641,7 @@ fn zigProcessUpdate(step_index: Configuration.Step.Index, maker: *Maker, zp: *Zi
632 const EmitDigest = std.zig.Server.Message.EmitDigest;641 const EmitDigest = std.zig.Server.Message.EmitDigest;
633 const emit_digest: *align(1) const EmitDigest = @ptrCast(body);642 const emit_digest: *align(1) const EmitDigest = @ptrCast(body);
634 s.result_cached = emit_digest.flags.cache_hit;643 s.result_cached = emit_digest.flags.cache_hit;
635 const digest = body[@sizeOf(EmitDigest)..][0..Cache.bin_digest_len];644 result = .{ .bin = body[@sizeOf(EmitDigest)..][0..Cache.bin_digest_len].* };
636 result = .{
637 .root_dir = graph.local_cache_root,
638 .sub_path = try arena.dupe(u8, "o" ++ Dir.path.sep_str ++ Cache.binToHex(digest.*)),
639 };
640 },645 },
641 .file_system_inputs => {646 .file_system_inputs => {
642 clearWatchInputs(s, maker);647 clearWatchInputs(s, maker);
lib/compiler/Maker/Step/Compile.zig+24-19
...@@ -46,7 +46,7 @@ pub fn make(...@@ -46,7 +46,7 @@ pub fn make(
4646
47 const incremental = conf_comp.flags4.incremental.toBool() orelse graph.incremental == true;47 const incremental = conf_comp.flags4.incremental.toBool() orelse graph.incremental == true;
4848
49 const maybe_output_dir = Step.evalZigProcess(49 const opt_cache_digest = Step.evalZigProcess(
50 compile_index,50 compile_index,
51 maker,51 maker,
52 argv.items,52 argv.items,
...@@ -63,24 +63,25 @@ pub fn make(...@@ -63,24 +63,25 @@ pub fn make(
63 const root_module = conf_comp.root_module.get(conf);63 const root_module = conf_comp.root_module.get(conf);
64 const target = root_module.resolved_target.get(conf).?.result.get(conf);64 const target = root_module.resolved_target.get(conf).?.result.get(conf);
6565
66 // Update generated files66 if (opt_cache_digest.toHex()) |o_hex_digest| {
67 if (maybe_output_dir) |output_dir| {67 if (conf_comp.emit_directory.value) |gf| {
68 if (conf_comp.emit_directory.value) |gf| maker.generatedPath(gf).* = output_dir;68 _ = try maker.setGeneratedPath(gf, .local_cache, &.{ "o", &o_hex_digest });
69 try updateGeneratedFile(maker, arena, &conf_comp, output_dir, &target, conf_comp.generated_bin.value, .bin);69 }
70 try updateGeneratedFile(maker, arena, &conf_comp, output_dir, &target, conf_comp.generated_pdb.value, .pdb);70 try updateGeneratedFile(maker, arena, &conf_comp, &o_hex_digest, &target, conf_comp.generated_bin.value, .bin);
71 try updateGeneratedFile(maker, arena, &conf_comp, output_dir, &target, conf_comp.generated_implib.value, .implib);71 try updateGeneratedFile(maker, arena, &conf_comp, &o_hex_digest, &target, conf_comp.generated_pdb.value, .pdb);
72 try updateGeneratedFile(maker, arena, &conf_comp, output_dir, &target, conf_comp.generated_h.value, .h);72 try updateGeneratedFile(maker, arena, &conf_comp, &o_hex_digest, &target, conf_comp.generated_implib.value, .implib);
73 try updateGeneratedFile(maker, arena, &conf_comp, output_dir, &target, conf_comp.generated_docs.value, .docs);73 try updateGeneratedFile(maker, arena, &conf_comp, &o_hex_digest, &target, conf_comp.generated_h.value, .h);
74 try updateGeneratedFile(maker, arena, &conf_comp, output_dir, &target, conf_comp.generated_asm.value, .@"asm");74 try updateGeneratedFile(maker, arena, &conf_comp, &o_hex_digest, &target, conf_comp.generated_docs.value, .docs);
75 try updateGeneratedFile(maker, arena, &conf_comp, output_dir, &target, conf_comp.generated_llvm_ir.value, .llvm_ir);75 try updateGeneratedFile(maker, arena, &conf_comp, &o_hex_digest, &target, conf_comp.generated_asm.value, .@"asm");
76 try updateGeneratedFile(maker, arena, &conf_comp, output_dir, &target, conf_comp.generated_llvm_bc.value, .llvm_bc);76 try updateGeneratedFile(maker, arena, &conf_comp, &o_hex_digest, &target, conf_comp.generated_llvm_ir.value, .llvm_ir);
77 try updateGeneratedFile(maker, arena, &conf_comp, &o_hex_digest, &target, conf_comp.generated_llvm_bc.value, .llvm_bc);
77 }78 }
7879
79 if (conf_comp.flags3.kind == .lib and conf_comp.flags2.linkage == .dynamic and80 if (conf_comp.flags3.kind == .lib and conf_comp.flags2.linkage == .dynamic and
80 conf_comp.version.value != null and target.flags.os_tag != .windows)81 conf_comp.version.value != null and target.flags.os_tag != .windows)
81 {82 {
82 if (conf_comp.generated_bin.value) |generated_bin| {83 if (conf_comp.generated_bin.value) |generated_bin| {
83 const full_dest_path = maker.generatedPath(generated_bin).*;84 const full_dest_path = maker.generatedPath(generated_bin);
84 try maker.installSymLinks(arena, full_dest_path, compile_index, compile_index);85 try maker.installSymLinks(arena, full_dest_path, compile_index, compile_index);
85 }86 }
86 }87 }
...@@ -97,13 +98,12 @@ fn updateGeneratedFile(...@@ -97,13 +98,12 @@ fn updateGeneratedFile(
97 maker: *Maker,98 maker: *Maker,
98 arena: Allocator,99 arena: Allocator,
99 conf_comp: *const Configuration.Step.Compile,100 conf_comp: *const Configuration.Step.Compile,
100 out_path: std.Build.Cache.Path,101 o_hex_digest: *const std.Build.Cache.HexDigest,
101 target: *const Configuration.TargetQuery,102 target: *const Configuration.TargetQuery,
102 opt_gf: ?Configuration.GeneratedFileIndex,103 opt_gf: ?Configuration.GeneratedFileIndex,
103 ea: std.zig.EmitArtifact,104 ea: std.zig.EmitArtifact,
104) Allocator.Error!void {105) Allocator.Error!void {
105 const gf = opt_gf orelse return;106 const gf = opt_gf orelse return;
106 const graph = maker.graph;
107 const conf = &maker.scanned_config.configuration;107 const conf = &maker.scanned_config.configuration;
108 const name = try ea.cacheName(arena, .{108 const name = try ea.cacheName(arena, .{
109 .root_name = conf_comp.root_name.slice(conf),109 .root_name = conf_comp.root_name.slice(conf),
...@@ -122,7 +122,7 @@ fn updateGeneratedFile(...@@ -122,7 +122,7 @@ fn updateGeneratedFile(
122 else122 else
123 null,123 null,
124 });124 });
125 maker.generatedPath(gf).* = try out_path.join(graph.arena, name);125 _ = try maker.setGeneratedPath(gf, .local_cache, &.{ "o", o_hex_digest, name });
126}126}
127127
128/// List of importable modules in a compilation's module graph, including128/// List of importable modules in a compilation's module graph, including
...@@ -945,6 +945,7 @@ pub fn rebuildInFuzzMode(...@@ -945,6 +945,7 @@ pub fn rebuildInFuzzMode(
945 progress_node: std.Progress.Node,945 progress_node: std.Progress.Node,
946) !Path {946) !Path {
947 const gpa = maker.gpa;947 const gpa = maker.gpa;
948 const graph = maker.graph;
948 const step = maker.stepByIndex(compile_index);949 const step = maker.stepByIndex(compile_index);
949950
950 var arena_allocator: std.heap.ArenaAllocator = .init(gpa);951 var arena_allocator: std.heap.ArenaAllocator = .init(gpa);
...@@ -963,8 +964,12 @@ pub fn rebuildInFuzzMode(...@@ -963,8 +964,12 @@ pub fn rebuildInFuzzMode(
963 defer argv.deinit(gpa);964 defer argv.deinit(gpa);
964965
965 try lowerZigArgs(arena, compile, compile_index, maker, progress_node, &argv, true);966 try lowerZigArgs(arena, compile, compile_index, maker, progress_node, &argv, true);
966 const maybe_output_bin_path = try Step.evalZigProcess(compile_index, maker, argv.items, progress_node, false);967 const opt_cache_digest = try Step.evalZigProcess(compile_index, maker, argv.items, progress_node, false);
967 return maybe_output_bin_path.?;968 const o_hex_digest = opt_cache_digest.toHex().?;
969 return .{
970 .root_dir = graph.local_cache_root,
971 .sub_path = try Dir.path.join(arena, &.{ "o", &o_hex_digest }),
972 };
968}973}
969974
970fn addBool(gpa: Allocator, args: *std.ArrayList([]const u8), arg: []const u8, opt: bool) !void {975fn addBool(gpa: Allocator, args: *std.ArrayList([]const u8), arg: []const u8, opt: bool) !void {
...@@ -1380,7 +1385,7 @@ pub fn appendIncludeDirFlags(...@@ -1380,7 +1385,7 @@ pub fn appendIncludeDirFlags(
1380 },1385 },
1381 .config_header_step => |ch_index| {1386 .config_header_step => |ch_index| {
1382 const conf_ch = ch_index.ptr(conf).extended.get(conf.extra).config_header;1387 const conf_ch = ch_index.ptr(conf).extended.get(conf.extra).config_header;
1383 const path = maker.generatedPath(conf_ch.generated_dir).*;1388 const path = maker.generatedPath(conf_ch.generated_dir);
1384 zig_args.appendAssumeCapacity("-I");1389 zig_args.appendAssumeCapacity("-I");
1385 zig_args.appendAssumeCapacity(try path.toString(arena));1390 zig_args.appendAssumeCapacity(try path.toString(arena));
1386 },1391 },
lib/compiler/Maker/Step/ConfigHeader.zig+6-16
...@@ -34,7 +34,6 @@ pub fn make(...@@ -34,7 +34,6 @@ pub fn make(
34 const conf = &maker.scanned_config.configuration;34 const conf = &maker.scanned_config.configuration;
35 const conf_step = step_index.ptr(conf);35 const conf_step = step_index.ptr(conf);
36 const conf_ch = conf_step.extended.get(conf.extra).config_header;36 const conf_ch = conf_step.extended.get(conf.extra).config_header;
37 const cache_root = graph.local_cache_root;
3837
39 const input_size_limit: Io.Limit = if (conf_ch.input_size_limit.value) |x| .limited64(x) else .unlimited;38 const input_size_limit: Io.Limit = if (conf_ch.input_size_limit.value) |x| .limited64(x) else .unlimited;
40 const include_guard_override: ?[]const u8 = if (conf_ch.include_guard.value) |s| s.slice(conf) else null;39 const include_guard_override: ?[]const u8 = if (conf_ch.include_guard.value) |s| s.slice(conf) else null;
...@@ -138,10 +137,7 @@ pub fn make(...@@ -138,10 +137,7 @@ pub fn make(
138137
139 if (try step.cacheHit(maker, &man, progress_node)) {138 if (try step.cacheHit(maker, &man, progress_node)) {
140 const digest = man.hitDigestHex();139 const digest = man.hitDigestHex();
141 maker.generatedPath(conf_ch.generated_dir).* = .{140 _ = try maker.setGeneratedPath(conf_ch.generated_dir, .local_cache, &.{ "o", &digest });
142 .root_dir = cache_root,
143 .sub_path = try Io.Dir.path.join(arena, &.{ "o", &digest }),
144 };
145 return;141 return;
146 }142 }
147143
...@@ -152,22 +148,16 @@ pub fn make(...@@ -152,22 +148,16 @@ pub fn make(
152 // output_path is libavutil/avconfig.h148 // output_path is libavutil/avconfig.h
153 // We want to open directory zig-cache/o/HASH/libavutil/149 // We want to open directory zig-cache/o/HASH/libavutil/
154 // but keep output_dir as zig-cache/o/HASH for -I include150 // but keep output_dir as zig-cache/o/HASH for -I include
155 const out_path: Path = .{151
156 .root_dir = cache_root,152 const artifact_path = try maker.setGeneratedPath(conf_ch.generated_dir, .local_cache, &.{ "o", &digest });
157 .sub_path = try Io.Dir.path.join(arena, &.{ "o", &digest, conf_ch.include_path.slice(conf) }),153 const out_path = try artifact_path.join(arena, conf_ch.include_path.slice(conf));
158 };
159 const out_path_dirname = out_path.dirname().?;154 const out_path_dirname = out_path.dirname().?;
160155
161 out_path_dirname.root_dir.handle.createDirPath(io, out_path_dirname.sub_path) catch |err|156 out_path_dirname.root_dir.handle.createDirPath(io, out_path_dirname.sub_path) catch |err|
162 return step.fail(maker, "unable to make path {f}: {t}", .{ out_path_dirname, err });157 return step.fail(maker, "failed to make path {qf}: {t}", .{ out_path_dirname, err });
163158
164 out_path.root_dir.handle.writeFile(io, .{ .sub_path = out_path.sub_path, .data = output }) catch |err|159 out_path.root_dir.handle.writeFile(io, .{ .sub_path = out_path.sub_path, .data = output }) catch |err|
165 return step.fail(maker, "unable to write file {f}: {t}", .{ out_path, err });160 return step.fail(maker, "failed to write file {qf}: {t}", .{ out_path, err });
166
167 maker.generatedPath(conf_ch.generated_dir).* = .{
168 .root_dir = cache_root,
169 .sub_path = try Io.Dir.path.join(arena, &.{ "o", &digest }),
170 };
171161
172 try step.finalizeManifest(maker, &man);162 try step.finalizeManifest(maker, &man);
173}163}
lib/compiler/Maker/Step/FindProgram.zig+1-1
...@@ -77,7 +77,7 @@ fn checkCandidate(...@@ -77,7 +77,7 @@ fn checkCandidate(
77 const io = graph.io;77 const io = graph.io;
7878
79 if (Io.Dir.cwd().access(io, full_path, .{ .execute = true })) |_| {79 if (Io.Dir.cwd().access(io, full_path, .{ .execute = true })) |_| {
80 maker.generatedPath(found_path).* = .initCwd(full_path);80 _ = try maker.setGeneratedPath(found_path, .cwd, &.{full_path});
81 return true;81 return true;
82 } else |err| switch (err) {82 } else |err| switch (err) {
83 error.Canceled => |e| return e,83 error.Canceled => |e| return e,
lib/compiler/Maker/Step/InstallArtifact.zig+1-1
...@@ -50,7 +50,7 @@ pub fn make(...@@ -50,7 +50,7 @@ pub fn make(
50 });50 });
51 const dest_dir = try maker.resolveInstallDir(arena, bin_dir);51 const dest_dir = try maker.resolveInstallDir(arena, bin_dir);
52 const dest_path = try dest_dir.join(arena, bin_sub_path);52 const dest_path = try dest_dir.join(arena, bin_sub_path);
53 const src_path = maker.generatedPath(generated_bin).*;53 const src_path = maker.generatedPath(generated_bin);
54 const p = try maker.installPath(arena, src_path, dest_path, step_index);54 const p = try maker.installPath(arena, src_path, dest_path, step_index);
55 all_cached = all_cached and p == .fresh;55 all_cached = all_cached and p == .fresh;
5656
lib/compiler/Maker/Step/ObjCopy.zig+7-20
...@@ -22,7 +22,6 @@ pub fn make(...@@ -22,7 +22,6 @@ pub fn make(
22 const conf = &maker.scanned_config.configuration;22 const conf = &maker.scanned_config.configuration;
23 const conf_step = step_index.ptr(conf);23 const conf_step = step_index.ptr(conf);
24 const conf_oc = conf_step.extended.get(conf.extra).obj_copy;24 const conf_oc = conf_step.extended.get(conf.extra).obj_copy;
25 const cache_root = graph.local_cache_root;
26 const input_lazy_path = conf_oc.input_file.get(conf);25 const input_lazy_path = conf_oc.input_file.get(conf);
27 const only_section: ?[]const u8 = if (conf_oc.only_section.value) |s| s.slice(conf) else null;26 const only_section: ?[]const u8 = if (conf_oc.only_section.value) |s| s.slice(conf) else null;
28 const opt_basename: ?[]const u8 = if (conf_oc.basename.value) |s| s.slice(conf) else null;27 const opt_basename: ?[]const u8 = if (conf_oc.basename.value) |s| s.slice(conf) else null;
...@@ -49,18 +48,12 @@ pub fn make(...@@ -49,18 +48,12 @@ pub fn make(
49 if (try step.cacheHit(maker, &man, progress_node)) {48 if (try step.cacheHit(maker, &man, progress_node)) {
50 // Cache hit, skip subprocess execution.49 // Cache hit, skip subprocess execution.
51 const digest = man.hitDigestHex();50 const digest = man.hitDigestHex();
52 maker.generatedPath(conf_oc.output_file).* = .{51 _ = try maker.setGeneratedPath(conf_oc.output_file, .local_cache, &.{ "o", &digest, basename });
53 .root_dir = cache_root,
54 .sub_path = try Io.Dir.path.join(arena, &.{ "o", &digest, basename }),
55 };
56 if (conf_oc.debug_file.value) |debug_file| {52 if (conf_oc.debug_file.value) |debug_file| {
57 const debug_basename = opt_debug_basename orelse try arena.print("{s}.debug", .{53 const debug_basename = opt_debug_basename orelse try arena.print("{s}.debug", .{
58 Io.Dir.path.basename(input_path.sub_path),54 Io.Dir.path.basename(input_path.sub_path),
59 });55 });
60 maker.generatedPath(debug_file).* = .{56 _ = try maker.setGeneratedPath(debug_file, .local_cache, &.{ "o", &digest, debug_basename });
61 .root_dir = cache_root,
62 .sub_path = try Io.Dir.path.join(arena, &.{ "o", &digest, debug_basename }),
63 };
64 }57 }
65 return;58 return;
66 }59 }
...@@ -68,10 +61,8 @@ pub fn make(...@@ -68,10 +61,8 @@ pub fn make(
68 // We don't find out more input files while executing objcopy so we can61 // We don't find out more input files while executing objcopy so we can
69 // already obtain the digest and use it directly as the output path.62 // already obtain the digest and use it directly as the output path.
70 const digest = man.missDigestHex();63 const digest = man.missDigestHex();
71 const dest_path: Path = .{64 const dest_path = try maker.setGeneratedPath(conf_oc.output_file, .local_cache, &.{ "o", &digest, basename });
72 .root_dir = cache_root,65
73 .sub_path = try Io.Dir.path.join(arena, &.{ "o", &digest, basename }),
74 };
75 const dest_dirname = dest_path.dirname().?;66 const dest_dirname = dest_path.dirname().?;
76 dest_dirname.root_dir.handle.createDirPath(io, dest_dirname.sub_path) catch |err|67 dest_dirname.root_dir.handle.createDirPath(io, dest_dirname.sub_path) catch |err|
77 return step.fail(maker, "failed to create path {f}: {t}", .{ dest_dirname, err });68 return step.fail(maker, "failed to create path {f}: {t}", .{ dest_dirname, err });
...@@ -107,12 +98,10 @@ pub fn make(...@@ -107,12 +98,10 @@ pub fn make(
107 const debug_basename = opt_debug_basename orelse try arena.print("{s}.debug", .{98 const debug_basename = opt_debug_basename orelse try arena.print("{s}.debug", .{
108 Io.Dir.path.basename(input_path.sub_path),99 Io.Dir.path.basename(input_path.sub_path),
109 });100 });
110 const debug_dest_path: Path = .{101 const debug_dest_path = try maker.setGeneratedPath(debug_file, .local_cache, &.{
111 .root_dir = cache_root,102 "o", &digest, debug_basename,
112 .sub_path = try Io.Dir.path.join(arena, &.{ "o", &digest, debug_basename }),103 });
113 };
114 argv.appendAssumeCapacity(try arena.print("--extract-to={f}", .{debug_dest_path}));104 argv.appendAssumeCapacity(try arena.print("--extract-to={f}", .{debug_dest_path}));
115 maker.generatedPath(debug_file).* = debug_dest_path;
116 }105 }
117106
118 try argv.ensureUnusedCapacity(arena, conf_oc.add_section.slice.len * 2);107 try argv.ensureUnusedCapacity(arena, conf_oc.add_section.slice.len * 2);
...@@ -163,8 +152,6 @@ pub fn make(...@@ -163,8 +152,6 @@ pub fn make(
163 else => |e| return e,152 else => |e| return e,
164 };153 };
165154
166 maker.generatedPath(conf_oc.output_file).* = dest_path;
167
168 step.finalizeManifest(maker, &man) catch |err| switch (err) {155 step.finalizeManifest(maker, &man) catch |err| switch (err) {
169 error.Canceled => |e| return e,156 error.Canceled => |e| return e,
170 else => |e| try step.addError(maker, "failed writing cache manifest: {t}", .{e}),157 else => |e| try step.addError(maker, "failed writing cache manifest: {t}", .{e}),
lib/compiler/Maker/Step/Options.zig+4-11
...@@ -19,7 +19,6 @@ pub fn make(...@@ -19,7 +19,6 @@ pub fn make(
19 const graph = maker.graph;19 const graph = maker.graph;
20 const step = maker.stepByIndex(step_index);20 const step = maker.stepByIndex(step_index);
21 const io = graph.io;21 const io = graph.io;
22 const cache_root = graph.local_cache_root;
23 const arena = graph.arena; // TODO don't leak into the process arena22 const arena = graph.arena; // TODO don't leak into the process arena
24 const conf = &maker.scanned_config.configuration;23 const conf = &maker.scanned_config.configuration;
25 const conf_step = step_index.ptr(conf);24 const conf_step = step_index.ptr(conf);
...@@ -80,19 +79,15 @@ pub fn make(...@@ -80,19 +79,15 @@ pub fn make(
8079
81 if (try step.cacheHitWatched(maker, &man, progress_node)) {80 if (try step.cacheHitWatched(maker, &man, progress_node)) {
82 const digest = man.hitDigestHex();81 const digest = man.hitDigestHex();
83 maker.generatedPath(conf_options.generated_file).* = .{82 _ = try maker.setGeneratedPath(conf_options.generated_file, .local_cache, &.{ "o", &digest, basename });
84 .root_dir = cache_root,
85 .sub_path = try Io.Dir.path.join(arena, &.{ "o", &digest, basename }),
86 };
87 step.result_cached = true;83 step.result_cached = true;
88 return;84 return;
89 }85 }
9086
91 const digest = man.missDigestHex();87 const digest = man.missDigestHex();
92 const out_path: Cache.Path = .{88 const out_path = try maker.setGeneratedPath(conf_options.generated_file, .local_cache, &.{
93 .root_dir = cache_root,89 "o", &digest, basename,
94 .sub_path = try Io.Dir.path.join(arena, &.{ "o", &digest, basename }),90 });
95 };
9691
97 var file: Io.File = out_path.root_dir.handle.createFile(io, out_path.sub_path, .{}) catch |err| switch (err) {92 var file: Io.File = out_path.root_dir.handle.createFile(io, out_path.sub_path, .{}) catch |err| switch (err) {
98 error.Canceled => |e| return e,93 error.Canceled => |e| return e,
...@@ -121,6 +116,4 @@ pub fn make(...@@ -121,6 +116,4 @@ pub fn make(
121 };116 };
122117
123 try step.finalizeManifestAndWatch(maker, &man);118 try step.finalizeManifestAndWatch(maker, &man);
124
125 maker.generatedPath(conf_options.generated_file).* = out_path;
126}119}
lib/compiler/Maker/Step/Run.zig+24-45
...@@ -146,7 +146,8 @@ pub fn make(...@@ -146,7 +146,8 @@ pub fn make(
146 const producer_make_comp_step = maker.stepByIndex(producer_index);146 const producer_make_comp_step = maker.stepByIndex(producer_index);
147 const producer_make_comp = &producer_make_comp_step.extended.compile;147 const producer_make_comp = &producer_make_comp_step.extended.compile;
148148
149 const file_path = producer_make_comp.installed_path orelse maker.generatedPath(producer.generated_bin.value.?).*;149 const file_path = producer_make_comp.installed_path orelse
150 maker.generatedPath(producer.generated_bin.value.?);
150151
151 argv_list.appendAssumeCapacity(try mem.concat(arena, u8, &.{152 argv_list.appendAssumeCapacity(try mem.concat(arena, u8, &.{
152 prefix, try convertPathArg(arena, run_index, maker, file_path, arg.flags.make_absolute), suffix,153 prefix, try convertPathArg(arena, run_index, maker, file_path, arg.flags.make_absolute), suffix,
...@@ -262,8 +263,8 @@ pub fn make(...@@ -262,8 +263,8 @@ pub fn make(
262 if (!has_side_effects and try step.cacheHitWatched(maker, &man, progress_node)) {263 if (!has_side_effects and try step.cacheHitWatched(maker, &man, progress_node)) {
263 // Cache hit; skip running command.264 // Cache hit; skip running command.
264 const digest = man.hitDigestHex();265 const digest = man.hitDigestHex();
265 try populateGeneratedStdIo(maker, &conf_run, cache_root, &digest);266 try populateGeneratedStdIo(maker, &conf_run, &digest);
266 try populateGeneratedPaths(maker, output_placeholders.items, cache_root, &digest);267 try populateGeneratedPaths(maker, output_placeholders.items, &digest);
267 step.result_cached = true;268 step.result_cached = true;
268 return;269 return;
269 }270 }
...@@ -272,7 +273,7 @@ pub fn make(...@@ -272,7 +273,7 @@ pub fn make(
272 // We already know the final output paths; use them directly.273 // We already know the final output paths; use them directly.
273 const digest = if (has_side_effects) man.hash.final() else man.missDigestHex();274 const digest = if (has_side_effects) man.hash.final() else man.missDigestHex();
274 const output_dir_path = "o" ++ Dir.path.sep_str ++ &digest;275 const output_dir_path = "o" ++ Dir.path.sep_str ++ &digest;
275 try populateGeneratedStdIo(maker, &conf_run, cache_root, &digest);276 try populateGeneratedStdIo(maker, &conf_run, &digest);
276 try populateGeneratedPathsCreateDirs(arena, run_index, maker, output_dir_path, output_placeholders.items, argv_list.items);277 try populateGeneratedPathsCreateDirs(arena, run_index, maker, output_dir_path, output_placeholders.items, argv_list.items);
277 try runCommand(arena, run, run_index, maker, progress_node, argv_list.items, has_side_effects, output_dir_path, null);278 try runCommand(arena, run, run_index, maker, progress_node, argv_list.items, has_side_effects, output_dir_path, null);
278 if (!has_side_effects) try step.finalizeManifestAndWatch(maker, &man);279 if (!has_side_effects) try step.finalizeManifestAndWatch(maker, &man);
...@@ -291,7 +292,7 @@ pub fn make(...@@ -291,7 +292,7 @@ pub fn make(
291 const arg = placeholder.arg_index.get(conf);292 const arg = placeholder.arg_index.get(conf);
292 switch (arg.flags.tag) {293 switch (arg.flags.tag) {
293 .output_file => if (arg.flags.dep_file) {294 .output_file => if (arg.flags.dep_file) {
294 const generated_path = maker.generatedPath(arg.generated.value.?).*;295 const generated_path = maker.generatedPath(arg.generated.value.?);
295 if (has_side_effects) {296 if (has_side_effects) {
296 var diagnostic: Cache.DepTokenizer.Token = undefined;297 var diagnostic: Cache.DepTokenizer.Token = undefined;
297 man.addInputDepFile(generated_path, &diagnostic) catch |err| switch (err) {298 man.addInputDepFile(generated_path, &diagnostic) catch |err| switch (err) {
...@@ -362,8 +363,8 @@ pub fn make(...@@ -362,8 +363,8 @@ pub fn make(
362363
363 if (!has_side_effects) try step.finalizeManifestAndWatch(maker, &man);364 if (!has_side_effects) try step.finalizeManifestAndWatch(maker, &man);
364365
365 try populateGeneratedStdIo(maker, &conf_run, cache_root, &digest);366 try populateGeneratedStdIo(maker, &conf_run, &digest);
366 try populateGeneratedPaths(maker, output_placeholders.items, cache_root, &digest);367 try populateGeneratedPaths(maker, output_placeholders.items, &digest);
367368
368 // The utility functions that spawn the child process must unconditionally allocate369 // The utility functions that spawn the child process must unconditionally allocate
369 // the failed command because at that point it is not known whether the step will370 // the failed command because at that point it is not known whether the step will
...@@ -1575,8 +1576,7 @@ pub fn rerunInFuzzMode(...@@ -1575,8 +1576,7 @@ pub fn rerunInFuzzMode(
1575 const file_path: Path = if (producer_index == conf_run.producer.value.?)1576 const file_path: Path = if (producer_index == conf_run.producer.value.?)
1576 run.rebuilt_executable.?1577 run.rebuilt_executable.?
1577 else1578 else
1578 producer_make_comp.installed_path orelse1579 producer_make_comp.installed_path orelse maker.generatedPath(producer.generated_bin.value.?);
1579 maker.generatedPath(producer.generated_bin.value.?).*;
1580 argv_list.appendAssumeCapacity(try mem.concat(arena, u8, &.{1580 argv_list.appendAssumeCapacity(try mem.concat(arena, u8, &.{
1581 prefix, try convertPathArg(arena, run_index, maker, file_path, arg.flags.make_absolute), suffix,1581 prefix, try convertPathArg(arena, run_index, maker, file_path, arg.flags.make_absolute), suffix,
1582 }));1582 }));
...@@ -1615,20 +1615,15 @@ pub fn rerunInFuzzMode(...@@ -1615,20 +1615,15 @@ pub fn rerunInFuzzMode(
1615fn populateGeneratedPaths(1615fn populateGeneratedPaths(
1616 maker: *Maker,1616 maker: *Maker,
1617 output_placeholders: []const IndexedOutput,1617 output_placeholders: []const IndexedOutput,
1618 cache_root: Cache.Directory,
1619 digest: *const Cache.HexDigest,1618 digest: *const Cache.HexDigest,
1620) !void {1619) !void {
1621 const conf = &maker.scanned_config.configuration;1620 const conf = &maker.scanned_config.configuration;
1622 const graph = maker.graph;
16231621
1624 for (output_placeholders) |placeholder| {1622 for (output_placeholders) |placeholder| {
1625 const arg = placeholder.arg_index.get(conf);1623 const arg = placeholder.arg_index.get(conf);
1626 maker.generatedPath(arg.generated.value.?).* = .{1624 _ = try maker.setGeneratedPath(arg.generated.value.?, .local_cache, &.{
1627 .root_dir = cache_root,1625 "o", digest, arg.basename.value.?.slice(conf),
1628 .sub_path = try Dir.path.join(graph.arena, &.{1626 });
1629 "o", digest, arg.basename.value.?.slice(conf),
1630 }),
1631 };
1632 }1627 }
1633}1628}
16341629
...@@ -1652,10 +1647,9 @@ fn populateGeneratedPathsCreateDirs(...@@ -1652,10 +1647,9 @@ fn populateGeneratedPathsCreateDirs(
1652 const suffix = if (arg.suffix.value) |p| p.slice(conf) else "";1647 const suffix = if (arg.suffix.value) |p| p.slice(conf) else "";
1653 const basename = arg.basename.value.?.slice(conf);1648 const basename = arg.basename.value.?.slice(conf);
16541649
1655 const generated_path: Path = .{1650 const generated_path = try maker.setGeneratedPath(arg.generated.value.?, .local_cache, &.{
1656 .root_dir = cache_root,1651 output_dir_path, basename,
1657 .sub_path = try Dir.path.join(graph.arena, &.{ output_dir_path, basename }),1652 });
1658 };
1659 const create_path: Path = .{1653 const create_path: Path = .{
1660 .root_dir = cache_root,1654 .root_dir = cache_root,
1661 .sub_path = switch (arg.flags.tag) {1655 .sub_path = switch (arg.flags.tag) {
...@@ -1667,8 +1661,6 @@ fn populateGeneratedPathsCreateDirs(...@@ -1667,8 +1661,6 @@ fn populateGeneratedPathsCreateDirs(
1667 create_path.root_dir.handle.createDirPath(io, create_path.sub_path) catch |err|1661 create_path.root_dir.handle.createDirPath(io, create_path.sub_path) catch |err|
1668 return step.fail(maker, "unable to make path {f}: {t}", .{ create_path, err });1662 return step.fail(maker, "unable to make path {f}: {t}", .{ create_path, err });
16691663
1670 maker.generatedPath(arg.generated.value.?).* = generated_path;
1671
1672 const arg_output_path = try convertPathArg(arena, run_index, maker, generated_path, arg.flags.make_absolute);1664 const arg_output_path = try convertPathArg(arena, run_index, maker, generated_path, arg.flags.make_absolute);
1673 argv[placeholder.index] = try mem.concat(arena, u8, &.{ prefix, arg_output_path, suffix });1665 argv[placeholder.index] = try mem.concat(arena, u8, &.{ prefix, arg_output_path, suffix });
1674 }1666 }
...@@ -1677,28 +1669,20 @@ fn populateGeneratedPathsCreateDirs(...@@ -1677,28 +1669,20 @@ fn populateGeneratedPathsCreateDirs(
1677fn populateGeneratedStdIo(1669fn populateGeneratedStdIo(
1678 maker: *Maker,1670 maker: *Maker,
1679 conf_run: *const Configuration.Step.Run,1671 conf_run: *const Configuration.Step.Run,
1680 cache_root: Cache.Directory,
1681 digest: *const Cache.HexDigest,1672 digest: *const Cache.HexDigest,
1682) !void {1673) !void {
1683 const conf = &maker.scanned_config.configuration;1674 const conf = &maker.scanned_config.configuration;
1684 const graph = maker.graph;
16851675
1686 if (conf_run.captured_stdout.value) |captured| {1676 if (conf_run.captured_stdout.value) |captured| {
1687 maker.generatedPath(captured.generated_file).* = .{1677 _ = try maker.setGeneratedPath(captured.generated_file, .local_cache, &.{
1688 .root_dir = cache_root,1678 "o", digest, captured.basename.slice(conf),
1689 .sub_path = try Dir.path.join(graph.arena, &.{1679 });
1690 "o", digest, captured.basename.slice(conf),
1691 }),
1692 };
1693 }1680 }
16941681
1695 if (conf_run.captured_stderr.value) |captured| {1682 if (conf_run.captured_stderr.value) |captured| {
1696 maker.generatedPath(captured.generated_file).* = .{1683 _ = try maker.setGeneratedPath(captured.generated_file, .local_cache, &.{
1697 .root_dir = cache_root,1684 "o", digest, captured.basename.slice(conf),
1698 .sub_path = try Dir.path.join(graph.arena, &.{1685 });
1699 "o", digest, captured.basename.slice(conf),
1700 }),
1701 };
1702 }1686 }
1703}1687}
17041688
...@@ -1735,7 +1719,6 @@ fn runCommand(...@@ -1735,7 +1719,6 @@ fn runCommand(
1735 const gpa = maker.gpa;1719 const gpa = maker.gpa;
1736 const step = maker.stepByIndex(run_index);1720 const step = maker.stepByIndex(run_index);
1737 const io = graph.io;1721 const io = graph.io;
1738 const cache_root = graph.local_cache_root;
1739 const conf = &maker.scanned_config.configuration;1722 const conf = &maker.scanned_config.configuration;
1740 const conf_step = run_index.ptr(conf);1723 const conf_step = run_index.ptr(conf);
1741 const conf_run = conf_step.extended.get(conf.extra).run;1724 const conf_run = conf_step.extended.get(conf.extra).run;
...@@ -1989,13 +1972,9 @@ fn runCommand(...@@ -1989,13 +1972,9 @@ fn runCommand(
1989 },1972 },
1990 }) |*stream| {1973 }) |*stream| {
1991 if (stream.captured) |captured| {1974 if (stream.captured) |captured| {
1992 const output_path: Path = .{1975 const output_path = try maker.setGeneratedPath(captured.generated_file, .local_cache, &.{
1993 .root_dir = cache_root,1976 output_dir_path, captured.basename.slice(conf),
1994 .sub_path = try Dir.path.join(graph.arena, &.{1977 });
1995 output_dir_path, captured.basename.slice(conf),
1996 }),
1997 };
1998 maker.generatedPath(captured.generated_file).* = output_path;
19991978
2000 const sub_path_parent = output_path.dirname().?;1979 const sub_path_parent = output_path.dirname().?;
2001 sub_path_parent.root_dir.handle.createDirPath(io, sub_path_parent.sub_path) catch |err|1980 sub_path_parent.root_dir.handle.createDirPath(io, sub_path_parent.sub_path) catch |err|
lib/compiler/Maker/Step/TranslateC.zig+4-3
...@@ -143,13 +143,14 @@ pub fn make(...@@ -143,13 +143,14 @@ pub fn make(
143 argv.appendAssumeCapacity(c_source_path);143 argv.appendAssumeCapacity(c_source_path);
144144
145 argv.appendAssumeCapacity("--listen=-");145 argv.appendAssumeCapacity("--listen=-");
146 const output_dir_path = (Step.evalZigProcess(step_index, maker, argv.items, progress_node, false) catch |err| switch (err) {146 const opt_cache_digest = Step.evalZigProcess(step_index, maker, argv.items, progress_node, false) catch |err| switch (err) {
147 error.NeedCompileErrorCheck => unreachable,147 error.NeedCompileErrorCheck => unreachable,
148 else => |e| return e,148 else => |e| return e,
149 }).?;149 };
150 const o_hex_digest = opt_cache_digest.toHex().?;
150151
151 const stem = Io.Dir.path.stem(Io.Dir.path.basename(c_source_path));152 const stem = Io.Dir.path.stem(Io.Dir.path.basename(c_source_path));
152 const out_basename = try arena.print("{s}.zig", .{stem});153 const out_basename = try arena.print("{s}.zig", .{stem});
153154
154 maker.generatedPath(conf_tc.output_file).* = try output_dir_path.join(arena, out_basename);155 _ = try maker.setGeneratedPath(conf_tc.output_file, .local_cache, &.{ "o", &o_hex_digest, out_basename });
155}156}
lib/compiler/Maker/Step/WriteFile.zig+6-18
...@@ -24,7 +24,6 @@ pub fn make(...@@ -24,7 +24,6 @@ pub fn make(
24 const conf = &maker.scanned_config.configuration;24 const conf = &maker.scanned_config.configuration;
25 const conf_step = step_index.ptr(conf);25 const conf_step = step_index.ptr(conf);
26 const conf_wf = conf_step.extended.get(conf.extra).write_file;26 const conf_wf = conf_step.extended.get(conf.extra).write_file;
27 const cache_root = graph.local_cache_root;
28 const directories = conf_wf.directories.slice;27 const directories = conf_wf.directories.slice;
2928
30 const open_dir_cache = try arena.alloc(Io.Dir, directories.len);29 const open_dir_cache = try arena.alloc(Io.Dir, directories.len);
...@@ -106,25 +105,17 @@ pub fn make(...@@ -106,25 +105,17 @@ pub fn make(
106105
107 if (try step.cacheHit(maker, &man, progress_node)) {106 if (try step.cacheHit(maker, &man, progress_node)) {
108 const digest = man.hitDigestHex();107 const digest = man.hitDigestHex();
109 maker.generatedPath(conf_wf.generated_directory).* = .{108 _ = try maker.setGeneratedPath(conf_wf.generated_directory, .local_cache, &.{ "o", &digest });
110 .root_dir = cache_root,
111 .sub_path = try Io.Dir.path.join(arena, &.{ "o", &digest }),
112 };
113 assert(step.result_cached);109 assert(step.result_cached);
114 return;110 return;
115 }111 }
116112
117 const digest = man.missDigestHex();113 const digest = man.missDigestHex();
118 const out_path: Path = .{114 const out_path = try maker.setGeneratedPath(conf_wf.generated_directory, .local_cache, &.{ "o", &digest });
119 .root_dir = cache_root,
120 .sub_path = try Io.Dir.path.join(arena, &.{ "o", &digest }),
121 };
122115
123 progress_node.setEstimatedTotalItems(total_items);116 progress_node.setEstimatedTotalItems(total_items);
124 try operate(maker, step_index, open_dir_cache, out_path, progress_node);117 try operate(maker, step_index, open_dir_cache, out_path, progress_node);
125 try step.finalizeManifest(maker, &man);118 try step.finalizeManifest(maker, &man);
126
127 maker.generatedPath(conf_wf.generated_directory).* = out_path;
128 },119 },
129 .tmp => {120 .tmp => {
130 step.result_cached = false;121 step.result_cached = false;
...@@ -133,20 +124,17 @@ pub fn make(...@@ -133,20 +124,17 @@ pub fn make(
133 io.random(@ptrCast(&rand_int));124 io.random(@ptrCast(&rand_int));
134 const hex_digest = std.fmt.hex(rand_int);125 const hex_digest = std.fmt.hex(rand_int);
135126
136 const out_path: Path = .{127 const out_path = try maker.setGeneratedPath(conf_wf.generated_directory, .local_cache, &.{
137 .root_dir = cache_root,128 "tmp", &hex_digest,
138 .sub_path = try Io.Dir.path.join(arena, &.{ "tmp", &hex_digest }),129 });
139 };
140130
141 try operate(maker, step_index, open_dir_cache, out_path, progress_node);131 try operate(maker, step_index, open_dir_cache, out_path, progress_node);
142
143 maker.generatedPath(conf_wf.generated_directory).* = out_path;
144 },132 },
145 .mutate => {133 .mutate => {
146 step.result_cached = false;134 step.result_cached = false;
147 const root_path = try maker.resolveLazyPathIndex(arena, conf_wf.mutate_path.value.?, step_index);135 const root_path = try maker.resolveLazyPathIndex(arena, conf_wf.mutate_path.value.?, step_index);
148 try operate(maker, step_index, open_dir_cache, root_path, progress_node);136 try operate(maker, step_index, open_dir_cache, root_path, progress_node);
149 maker.generatedPath(conf_wf.generated_directory).* = root_path;137 _ = try maker.setGeneratedPathPath(conf_wf.generated_directory, root_path);
150 },138 },
151 }139 }
152}140}