| author | |
| committer | |
| log | 7cef4755c33ca77137fb7e4d83146e27b5703685 |
| tree | d64ebc4cf10a4728a631649dc78266dc95e10f10 |
| parent | 5b9147ed59b22edf7f891cf30e8b77223121da4f |
| parent | 480e3f89b227c6c1d5daeb8ae8f7af46c9301637 |
Reviewed-on: https://codeberg.org/ziglang/zig/pulls/3694715 files changed, 434 insertions(+), 168 deletions(-)
lib/compiler/Maker.zig+274-14| ... | @@ -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 more | 49 | /// 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. |
| 51 | steps: []Step, | 51 | steps: []Step, |
| 52 | generated_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. | ||
| 58 | generated_files: []GeneratedFile, | ||
| 53 | run_args: ?[]const []const u8, | 59 | run_args: ?[]const []const u8, |
| 54 | 60 | ||
| 55 | available_rss: u64, | 61 | available_rss: u64, |
| ... | @@ -121,6 +127,38 @@ const MultilineErrors = enum { indent, newline, none }; | ... | @@ -121,6 +127,38 @@ const MultilineErrors = enum { indent, newline, none }; |
| 121 | const Summary = enum { all, new, failures, line, none }; | 127 | const Summary = enum { all, new, failures, line, none }; |
| 122 | const PrintConfiguration = enum { none, zon, path }; | 128 | const PrintConfiguration = enum { none, zon, path }; |
| 123 | 129 | ||
| 130 | const 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. |
| 125 | pub const CliModule = struct { | 163 | pub 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 placeholder | 2382 | // 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 }); | ||
| 2348 | 2387 | ||
| 2349 | // The last element is a reserved special pseudostep which contains the | 2388 | // 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); |
| 2793 | 2834 | ||
| ... | @@ -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 | } |
| 2809 | 2847 | ||
| 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,11 +3429,13 @@ fn serveBuildStepCompleted( | ... | @@ -3391,11 +3429,13 @@ 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; |
| 3398 | 3436 | ||
| 3437 | const gf_size = countGeneratedFiles(maker.generated_files, step_index, &maker.scanned_config.configuration); | ||
| 3438 | |||
| 3399 | const body: Server.Message.BuildStepCompleted = .{ | 3439 | const body: Server.Message.BuildStepCompleted = .{ |
| 3400 | .step_index = step_index, | 3440 | .step_index = step_index, |
| 3401 | .status = status, | 3441 | .status = status, |
| ... | @@ -3403,19 +3443,172 @@ fn serveBuildStepCompleted( | ... | @@ -3403,19 +3443,172 @@ fn serveBuildStepCompleted( |
| 3403 | .extra_len = @intCast(error_bundle.extra.len), | 3443 | .extra_len = @intCast(error_bundle.extra.len), |
| 3404 | .string_bytes_len = @intCast(error_bundle.string_bytes.len), | 3444 | .string_bytes_len = @intCast(error_bundle.string_bytes.len), |
| 3405 | }, | 3445 | }, |
| 3446 | .generated_files_len = gf_size.count, | ||
| 3406 | }; | 3447 | }; |
| 3407 | const eb_bytes_len = @sizeOf(u32) * error_bundle.extra.len + error_bundle.string_bytes.len; | 3448 | const eb_bytes_len = @sizeOf(u32) * error_bundle.extra.len + error_bundle.string_bytes.len; |
| 3408 | const bytes_len = @sizeOf(Server.Message.BuildStepCompleted) + eb_bytes_len; | 3449 | const bytes_len = @sizeOf(Server.Message.BuildStepCompleted) + eb_bytes_len + |
| 3450 | (gf_size.count * @sizeOf(Server.Message.GeneratedFile)) + gf_size.size; | ||
| 3409 | try s.serveMessageHeader(.{ | 3451 | try s.serveMessageHeader(.{ |
| 3410 | .tag = .bsp_step_completed, | 3452 | .tag = .bsp_step_completed, |
| 3411 | .bytes_len = @intCast(bytes_len), | 3453 | .bytes_len = @intCast(bytes_len), |
| 3412 | }); | 3454 | }); |
| 3413 | try s.out.writeStruct(body, .little); | 3455 | try s.out.writeStruct(body, .little); |
| 3456 | |||
| 3414 | try s.out.writeSliceEndian(u32, error_bundle.extra, .little); | 3457 | try s.out.writeSliceEndian(u32, error_bundle.extra, .little); |
| 3415 | try s.out.writeAll(error_bundle.string_bytes); | 3458 | try s.out.writeAll(error_bundle.string_bytes); |
| 3459 | |||
| 3460 | try writeGeneratedFiles(maker.generated_files, step_index, &maker.scanned_config.configuration, s.out); | ||
| 3461 | try writeGeneratedFilesData(maker.generated_files, step_index, &maker.scanned_config.configuration, s.out); | ||
| 3462 | |||
| 3416 | try s.out.flush(); | 3463 | try s.out.flush(); |
| 3417 | } | 3464 | } |
| 3418 | 3465 | ||
| 3466 | fn walkGeneratedFiles( | ||
| 3467 | step_index: Configuration.Step.Index, | ||
| 3468 | conf: *const Configuration, | ||
| 3469 | comptime Context: type, | ||
| 3470 | context: Context, | ||
| 3471 | ) void { | ||
| 3472 | const conf_step = step_index.ptr(conf); | ||
| 3473 | switch (conf_step.extended.get(conf.extra)) { | ||
| 3474 | .check_file, | ||
| 3475 | .fail, | ||
| 3476 | .fmt, | ||
| 3477 | .install_artifact, | ||
| 3478 | .install_dir, | ||
| 3479 | .install_file, | ||
| 3480 | .top_level, | ||
| 3481 | .update_source_files, | ||
| 3482 | => {}, | ||
| 3483 | |||
| 3484 | .compile => |compile| { | ||
| 3485 | walkGeneratedFilesOne(context, compile.emit_directory.value); | ||
| 3486 | walkGeneratedFilesOne(context, compile.generated_docs.value); | ||
| 3487 | walkGeneratedFilesOne(context, compile.generated_asm.value); | ||
| 3488 | walkGeneratedFilesOne(context, compile.generated_bin.value); | ||
| 3489 | walkGeneratedFilesOne(context, compile.generated_pdb.value); | ||
| 3490 | walkGeneratedFilesOne(context, compile.generated_implib.value); | ||
| 3491 | walkGeneratedFilesOne(context, compile.generated_llvm_bc.value); | ||
| 3492 | walkGeneratedFilesOne(context, compile.generated_llvm_ir.value); | ||
| 3493 | walkGeneratedFilesOne(context, compile.generated_h.value); | ||
| 3494 | }, | ||
| 3495 | .config_header => |config_header| { | ||
| 3496 | walkGeneratedFilesOne(context, config_header.generated_dir); | ||
| 3497 | }, | ||
| 3498 | .find_program => |find_program| { | ||
| 3499 | walkGeneratedFilesOne(context, find_program.found_path); | ||
| 3500 | }, | ||
| 3501 | .obj_copy => |obj_copy| { | ||
| 3502 | walkGeneratedFilesOne(context, obj_copy.output_file); | ||
| 3503 | walkGeneratedFilesOne(context, obj_copy.debug_file.value); | ||
| 3504 | }, | ||
| 3505 | .options => |options| { | ||
| 3506 | walkGeneratedFilesOne(context, options.generated_file); | ||
| 3507 | }, | ||
| 3508 | .run => |run| { | ||
| 3509 | if (run.captured_stdout.value) |v| walkGeneratedFilesOne(context, v.generated_file); | ||
| 3510 | if (run.captured_stderr.value) |v| walkGeneratedFilesOne(context, v.generated_file); | ||
| 3511 | for (run.args.slice) |arg| | ||
| 3512 | walkGeneratedFilesOne(context, arg.get(conf).generated.value); | ||
| 3513 | }, | ||
| 3514 | .translate_c => |translate_c| { | ||
| 3515 | walkGeneratedFilesOne(context, translate_c.output_file); | ||
| 3516 | }, | ||
| 3517 | .write_file => |write_file| { | ||
| 3518 | walkGeneratedFilesOne(context, write_file.generated_directory); | ||
| 3519 | }, | ||
| 3520 | } | ||
| 3521 | } | ||
| 3522 | |||
| 3523 | fn walkGeneratedFilesOne( | ||
| 3524 | context: anytype, | ||
| 3525 | opt: ?Configuration.GeneratedFileIndex, | ||
| 3526 | ) void { | ||
| 3527 | context.visit(opt orelse return); | ||
| 3528 | } | ||
| 3529 | |||
| 3530 | fn countGeneratedFiles( | ||
| 3531 | generated_files: []const GeneratedFile, | ||
| 3532 | step_index: Configuration.Step.Index, | ||
| 3533 | conf: *const Configuration, | ||
| 3534 | ) struct { count: u32, size: u32 } { | ||
| 3535 | const Visitor = struct { | ||
| 3536 | generated_files: []const GeneratedFile, | ||
| 3537 | count: u32, | ||
| 3538 | size: u32, | ||
| 3539 | |||
| 3540 | fn visit(this: *@This(), i: Configuration.GeneratedFileIndex) void { | ||
| 3541 | const data = this.generated_files[@backingInt(i)].data orelse return; | ||
| 3542 | this.count += 1; | ||
| 3543 | this.size = @intCast(this.size + data.len); | ||
| 3544 | } | ||
| 3545 | }; | ||
| 3546 | var v: Visitor = .{ | ||
| 3547 | .generated_files = generated_files, | ||
| 3548 | .count = 0, | ||
| 3549 | .size = 0, | ||
| 3550 | }; | ||
| 3551 | walkGeneratedFiles(step_index, conf, *Visitor, &v); | ||
| 3552 | return .{ | ||
| 3553 | .count = v.count, | ||
| 3554 | .size = v.size, | ||
| 3555 | }; | ||
| 3556 | } | ||
| 3557 | |||
| 3558 | fn writeGeneratedFiles( | ||
| 3559 | generated_files: []const GeneratedFile, | ||
| 3560 | step_index: Configuration.Step.Index, | ||
| 3561 | conf: *const Configuration, | ||
| 3562 | writer: *Io.Writer, | ||
| 3563 | ) Io.Writer.Error!void { | ||
| 3564 | const Visitor = struct { | ||
| 3565 | generated_files: []const GeneratedFile, | ||
| 3566 | writer: *Io.Writer, | ||
| 3567 | result: Io.Writer.Error!void, | ||
| 3568 | |||
| 3569 | fn visit(this: *@This(), i: Configuration.GeneratedFileIndex) void { | ||
| 3570 | const unpacked = this.generated_files[@backingInt(i)].unpack() orelse return; | ||
| 3571 | const payload: Server.Message.GeneratedFile = .{ | ||
| 3572 | .index = i, | ||
| 3573 | .path_len = @intCast(unpacked.sub_path.len), | ||
| 3574 | }; | ||
| 3575 | this.result = this.writer.writeAll(@ptrCast((&payload)[0..1])); | ||
| 3576 | } | ||
| 3577 | }; | ||
| 3578 | var v: Visitor = .{ | ||
| 3579 | .generated_files = generated_files, | ||
| 3580 | .writer = writer, | ||
| 3581 | .result = {}, | ||
| 3582 | }; | ||
| 3583 | walkGeneratedFiles(step_index, conf, *Visitor, &v); | ||
| 3584 | return v.result; | ||
| 3585 | } | ||
| 3586 | |||
| 3587 | fn writeGeneratedFilesData( | ||
| 3588 | generated_files: []const GeneratedFile, | ||
| 3589 | step_index: Configuration.Step.Index, | ||
| 3590 | conf: *const Configuration, | ||
| 3591 | writer: *Io.Writer, | ||
| 3592 | ) Io.Writer.Error!void { | ||
| 3593 | const Visitor = struct { | ||
| 3594 | generated_files: []const GeneratedFile, | ||
| 3595 | writer: *Io.Writer, | ||
| 3596 | result: Io.Writer.Error!void, | ||
| 3597 | |||
| 3598 | fn visit(this: *@This(), i: Configuration.GeneratedFileIndex) void { | ||
| 3599 | const data = this.generated_files[@backingInt(i)].data orelse return; | ||
| 3600 | this.result = this.writer.writeAll(data); | ||
| 3601 | } | ||
| 3602 | }; | ||
| 3603 | var v: Visitor = .{ | ||
| 3604 | .generated_files = generated_files, | ||
| 3605 | .writer = writer, | ||
| 3606 | .result = {}, | ||
| 3607 | }; | ||
| 3608 | walkGeneratedFiles(step_index, conf, *Visitor, &v); | ||
| 3609 | return v.result; | ||
| 3610 | } | ||
| 3611 | |||
| 3419 | fn initStdoutWriter(io: Io) *Writer { | 3612 | fn initStdoutWriter(io: Io) *Writer { |
| 3420 | stdout_writer_allocation = Io.File.stdout().writerStreaming(io, &stdio_buffer_allocation); | 3613 | stdout_writer_allocation = Io.File.stdout().writerStreaming(io, &stdio_buffer_allocation); |
| 3421 | return &stdout_writer_allocation.interface; | 3614 | return &stdout_writer_allocation.interface; |
| ... | @@ -3434,7 +3627,7 @@ pub fn resolveLazyPath( | ... | @@ -3434,7 +3627,7 @@ pub fn resolveLazyPath( |
| 3434 | .source_path => |sp| try packagePath(maker, arena, sp.owner, sp.sub_path.slice(c)), | 3627 | .source_path => |sp| try packagePath(maker, arena, sp.owner, sp.sub_path.slice(c)), |
| 3435 | .relative => |relative| relativePath(maker, arena, relative), | 3628 | .relative => |relative| relativePath(maker, arena, relative), |
| 3436 | .generated => |gen| { | 3629 | .generated => |gen| { |
| 3437 | const base = generatedPath(maker, gen.index).*; | 3630 | const base = generatedPath(maker, gen.index); |
| 3438 | var file_path = base; | 3631 | var file_path = base; |
| 3439 | for (0..gen.flags.up) |_| { | 3632 | for (0..gen.flags.up) |_| { |
| 3440 | file_path.sub_path = Dir.path.dirname(file_path.sub_path) orelse { | 3633 | file_path.sub_path = Dir.path.dirname(file_path.sub_path) orelse { |
| ... | @@ -3485,10 +3678,67 @@ pub fn resolveLazyPathIndexAbs( | ... | @@ -3485,10 +3678,67 @@ pub fn resolveLazyPathIndexAbs( |
| 3485 | return resolveLazyPathAbs(maker, arena, lazy_path_index.get(c), asking_step_index); | 3678 | return resolveLazyPathAbs(maker, arena, lazy_path_index.get(c), asking_step_index); |
| 3486 | } | 3679 | } |
| 3487 | 3680 | ||
| 3488 | pub fn generatedPath(maker: *const Maker, index: Configuration.GeneratedFileIndex) *Path { | 3681 | pub fn generatedFile(maker: *const Maker, index: Configuration.GeneratedFileIndex) *GeneratedFile { |
| 3489 | return &maker.generated_files[@backingInt(index)]; | 3682 | return &maker.generated_files[@backingInt(index)]; |
| 3490 | } | 3683 | } |
| 3491 | 3684 | ||
| 3685 | pub fn generatedPath(maker: *const Maker, index: Configuration.GeneratedFileIndex) Path { | ||
| 3686 | return generatedFile(maker, index).toPath(maker.graph).?; | ||
| 3687 | } | ||
| 3688 | |||
| 3689 | pub fn setGeneratedPath( | ||
| 3690 | maker: *Maker, | ||
| 3691 | index: Configuration.GeneratedFileIndex, | ||
| 3692 | prefix: Server.Message.PathPrefix, | ||
| 3693 | sub_paths: []const []const u8, | ||
| 3694 | ) Allocator.Error!Path { | ||
| 3695 | const gpa = maker.gpa; | ||
| 3696 | const graph = maker.graph; | ||
| 3697 | assert(sub_paths.len != 0); | ||
| 3698 | |||
| 3699 | var buffer: std.ArrayList(u8) = .empty; | ||
| 3700 | defer buffer.deinit(gpa); | ||
| 3701 | try buffer.append(gpa, @backingInt(prefix)); | ||
| 3702 | for (sub_paths) |sub_path| { | ||
| 3703 | try buffer.ensureUnusedCapacity(gpa, sub_path.len + 1); | ||
| 3704 | buffer.appendSliceAssumeCapacity(sub_path); | ||
| 3705 | while (Dir.path.isSep(buffer.items[buffer.items.len - 1])) | ||
| 3706 | buffer.items.len -= 1; | ||
| 3707 | buffer.appendAssumeCapacity(Dir.path.sep); | ||
| 3708 | } | ||
| 3709 | assert(buffer.pop().? == Dir.path.sep); | ||
| 3710 | try buffer.shrinkToLen(gpa); | ||
| 3711 | |||
| 3712 | const sub_path = buffer.toOwnedSliceAssert(); | ||
| 3713 | const ptr = generatedFile(maker, index); | ||
| 3714 | ptr.clear(gpa); | ||
| 3715 | ptr.* = .{ .data = sub_path }; | ||
| 3716 | return .{ | ||
| 3717 | .root_dir = prefixToDirectory(graph, prefix), | ||
| 3718 | .sub_path = sub_path[1..], | ||
| 3719 | }; | ||
| 3720 | } | ||
| 3721 | |||
| 3722 | /// Prefer to use `setGeneratedPath` where possible to keep parent directory information intact. | ||
| 3723 | pub fn setGeneratedPathPath( | ||
| 3724 | maker: *Maker, | ||
| 3725 | index: Configuration.GeneratedFileIndex, | ||
| 3726 | path: Path, | ||
| 3727 | ) Allocator.Error!Path { | ||
| 3728 | const graph = maker.graph; | ||
| 3729 | if (path.root_dir.eql(graph.local_cache_root)) { | ||
| 3730 | return setGeneratedPath(maker, index, .local_cache, &.{path.sub_path}); | ||
| 3731 | } else if (path.root_dir.eql(graph.global_cache_root)) { | ||
| 3732 | return setGeneratedPath(maker, index, .global_cache, &.{path.sub_path}); | ||
| 3733 | } else if (path.root_dir.eql(graph.zig_lib_directory)) { | ||
| 3734 | return setGeneratedPath(maker, index, .zig_lib, &.{path.sub_path}); | ||
| 3735 | } else if (path.root_dir.eql(graph.build_root_directory)) { | ||
| 3736 | return setGeneratedPath(maker, index, .build_root, &.{path.sub_path}); | ||
| 3737 | } else { | ||
| 3738 | return setGeneratedPath(maker, index, .cwd, &.{path.sub_path}); | ||
| 3739 | } | ||
| 3740 | } | ||
| 3741 | |||
| 3492 | pub fn packagePath( | 3742 | pub fn packagePath( |
| 3493 | maker: *const Maker, | 3743 | maker: *const Maker, |
| 3494 | arena: Allocator, | 3744 | arena: Allocator, |
| ... | @@ -3600,7 +3850,7 @@ pub fn installGenerated( | ... | @@ -3600,7 +3850,7 @@ pub fn installGenerated( |
| 3600 | dest_dir: Configuration.InstallDestDir, | 3850 | dest_dir: Configuration.InstallDestDir, |
| 3601 | asking_step_index: Configuration.Step.Index, | 3851 | asking_step_index: Configuration.Step.Index, |
| 3602 | ) !Dir.PrevStatus { | 3852 | ) !Dir.PrevStatus { |
| 3603 | const src_path = generatedPath(maker, source).*; | 3853 | const src_path = generatedPath(maker, source); |
| 3604 | const dest_dir_path = try resolveInstallDir(maker, arena, dest_dir); | 3854 | const dest_dir_path = try resolveInstallDir(maker, arena, dest_dir); |
| 3605 | const dest_path = try dest_dir_path.join(arena, src_path.basename()); | 3855 | const dest_path = try dest_dir_path.join(arena, src_path.basename()); |
| 3606 | return installPath(maker, arena, src_path, dest_path, asking_step_index); | 3856 | return installPath(maker, arena, src_path, dest_path, asking_step_index); |
| ... | @@ -4170,3 +4420,13 @@ fn nextEnumArg(args: []const []const u8, i: *usize, comptime E: type) E { | ... | @@ -4170,3 +4420,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); | 4420 | const next_arg = nextArg(args, i) orelse fatalEnumHint(E, arg, null); |
| 4171 | return stringToEnum(E, next_arg) orelse fatalEnumHint(E, arg, next_arg); | 4421 | return stringToEnum(E, next_arg) orelse fatalEnumHint(E, arg, next_arg); |
| 4172 | } | 4422 | } |
| 4423 | |||
| 4424 | fn prefixToDirectory(graph: *const Graph, prefix: Server.Message.PathPrefix) Cache.Directory { | ||
| 4425 | return switch (prefix) { | ||
| 4426 | .cwd => .cwd(), | ||
| 4427 | .zig_lib => graph.zig_lib_directory, | ||
| 4428 | .local_cache => graph.local_cache_root, | ||
| 4429 | .global_cache => graph.global_cache_root, | ||
| 4430 | .build_root => graph.build_root_directory, | ||
| 4431 | }; | ||
| 4432 | } |
lib/compiler/Maker/Fuzz.zig+8-2| ... | @@ -161,6 +161,7 @@ pub fn deinit(fuzz: *Fuzz) void { | ... | @@ -161,6 +161,7 @@ pub fn deinit(fuzz: *Fuzz) void { |
| 161 | fuzz.group.cancel(io); | 161 | fuzz.group.cancel(io); |
| 162 | fuzz.prog_node.end(); | 162 | fuzz.prog_node.end(); |
| 163 | gpa.free(fuzz.run_steps); | 163 | gpa.free(fuzz.run_steps); |
| 164 | fuzz.msg_queue.deinit(gpa); | ||
| 164 | } | 165 | } |
| 165 | 166 | ||
| 166 | fn rebuildTestsWorkerRun( | 167 | fn rebuildTestsWorkerRun( |
| ... | @@ -212,7 +213,7 @@ fn rebuildTestsWorkerRunFallible( | ... | @@ -212,7 +213,7 @@ fn rebuildTestsWorkerRunFallible( |
| 212 | maker.printErrorMessages(comp_index, .{}, stderr.terminal(), .verbose, .indent) catch {}; | 213 | maker.printErrorMessages(comp_index, .{}, stderr.terminal(), .verbose, .indent) catch {}; |
| 213 | } | 214 | } |
| 214 | 215 | ||
| 215 | const rebuilt_bin_path = result catch |err| switch (err) { | 216 | const rebuilt_digest = result catch |err| switch (err) { |
| 216 | error.MakeFailed => return, | 217 | error.MakeFailed => return, |
| 217 | else => |other| return other, | 218 | else => |other| return other, |
| 218 | }; | 219 | }; |
| ... | @@ -235,7 +236,12 @@ fn rebuildTestsWorkerRunFallible( | ... | @@ -235,7 +236,12 @@ fn rebuildTestsWorkerRunFallible( |
| 235 | }); | 236 | }); |
| 236 | defer gpa.free(compile_filename); | 237 | defer gpa.free(compile_filename); |
| 237 | 238 | ||
| 238 | run.rebuilt_executable = try rebuilt_bin_path.join(gpa, compile_filename); | 239 | const o_hex_digest = rebuilt_digest.toHex().?; |
| 240 | |||
| 241 | run.rebuilt_executable = .{ | ||
| 242 | .root_dir = graph.local_cache_root, | ||
| 243 | .sub_path = try std.fs.path.join(gpa, &.{ "o", &o_hex_digest, compile_filename }), | ||
| 244 | }; | ||
| 239 | } | 245 | } |
| 240 | 246 | ||
| 241 | fn fuzzWorkerRun(fuzz: *Fuzz, run_index: Configuration.Step.Index) void { | 247 | fn fuzzWorkerRun(fuzz: *Fuzz, run_index: Configuration.Step.Index) void { |
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 | }; |
| 462 | 462 | ||
| 463 | pub 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 spawned | 472 | /// 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()}); |
| 505 | 514 | ||
| 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 | } |
| 580 | 589 | ||
| 581 | fn zigProcessUpdate(step_index: Configuration.Step.Index, maker: *Maker, zp: *ZigProcess, watch: bool) !?Path { | 590 | fn 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); |
| 592 | 601 | ||
| 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 = {}; |
| 595 | 604 | ||
| 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+19-20| ... | @@ -46,7 +46,7 @@ pub fn make( | ... | @@ -46,7 +46,7 @@ pub fn make( |
| 46 | 46 | ||
| 47 | const incremental = conf_comp.flags4.incremental.toBool() orelse graph.incremental == true; | 47 | const incremental = conf_comp.flags4.incremental.toBool() orelse graph.incremental == true; |
| 48 | 48 | ||
| 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); |
| 65 | 65 | ||
| 66 | // Update generated files | 66 | 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 | } |
| 78 | 79 | ||
| 79 | if (conf_comp.flags3.kind == .lib and conf_comp.flags2.linkage == .dynamic and | 80 | 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 | else | 122 | 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 | } |
| 127 | 127 | ||
| 128 | /// List of importable modules in a compilation's module graph, including | 128 | /// List of importable modules in a compilation's module graph, including |
| ... | @@ -943,7 +943,7 @@ pub fn rebuildInFuzzMode( | ... | @@ -943,7 +943,7 @@ pub fn rebuildInFuzzMode( |
| 943 | maker: *Maker, | 943 | maker: *Maker, |
| 944 | compile_index: Configuration.Step.Index, | 944 | compile_index: Configuration.Step.Index, |
| 945 | progress_node: std.Progress.Node, | 945 | progress_node: std.Progress.Node, |
| 946 | ) !Path { | 946 | ) !Step.OptCacheDigest { |
| 947 | const gpa = maker.gpa; | 947 | const gpa = maker.gpa; |
| 948 | const step = maker.stepByIndex(compile_index); | 948 | const step = maker.stepByIndex(compile_index); |
| 949 | 949 | ||
| ... | @@ -963,8 +963,7 @@ pub fn rebuildInFuzzMode( | ... | @@ -963,8 +963,7 @@ pub fn rebuildInFuzzMode( |
| 963 | defer argv.deinit(gpa); | 963 | defer argv.deinit(gpa); |
| 964 | 964 | ||
| 965 | try lowerZigArgs(arena, compile, compile_index, maker, progress_node, &argv, true); | 965 | 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); | 966 | return Step.evalZigProcess(compile_index, maker, argv.items, progress_node, false); |
| 967 | return maybe_output_bin_path.?; | ||
| 968 | } | 967 | } |
| 969 | 968 | ||
| 970 | fn addBool(gpa: Allocator, args: *std.ArrayList([]const u8), arg: []const u8, opt: bool) !void { | 969 | fn addBool(gpa: Allocator, args: *std.ArrayList([]const u8), arg: []const u8, opt: bool) !void { |
| ... | @@ -1380,7 +1379,7 @@ pub fn appendIncludeDirFlags( | ... | @@ -1380,7 +1379,7 @@ pub fn appendIncludeDirFlags( |
| 1380 | }, | 1379 | }, |
| 1381 | .config_header_step => |ch_index| { | 1380 | .config_header_step => |ch_index| { |
| 1382 | const conf_ch = ch_index.ptr(conf).extended.get(conf.extra).config_header; | 1381 | const conf_ch = ch_index.ptr(conf).extended.get(conf.extra).config_header; |
| 1383 | const path = maker.generatedPath(conf_ch.generated_dir).*; | 1382 | const path = maker.generatedPath(conf_ch.generated_dir); |
| 1384 | zig_args.appendAssumeCapacity("-I"); | 1383 | zig_args.appendAssumeCapacity("-I"); |
| 1385 | zig_args.appendAssumeCapacity(try path.toString(arena)); | 1384 | zig_args.appendAssumeCapacity(try path.toString(arena)); |
| 1386 | }, | 1385 | }, |
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; | ||
| 38 | 37 | ||
| 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( |
| 138 | 137 | ||
| 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 | } |
| 147 | 143 | ||
| ... | @@ -152,22 +148,16 @@ pub fn make( | ... | @@ -152,22 +148,16 @@ pub fn make( |
| 152 | // output_path is libavutil/avconfig.h | 148 | // 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 include | 150 | // 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().?; |
| 160 | 155 | ||
| 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 }); |
| 163 | 158 | ||
| 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 | }; | ||
| 171 | 161 | ||
| 172 | try step.finalizeManifest(maker, &man); | 162 | try step.finalizeManifest(maker, &man); |
| 173 | } | 163 | } |
lib/compiler/Maker/Step/FindProgram.zig+2-2| ... | @@ -77,7 +77,7 @@ fn checkCandidate( | ... | @@ -77,7 +77,7 @@ fn checkCandidate( |
| 77 | const io = graph.io; | 77 | const io = graph.io; |
| 78 | 78 | ||
| 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, |
| ... | @@ -96,7 +96,7 @@ fn checkCandidate( | ... | @@ -96,7 +96,7 @@ fn checkCandidate( |
| 96 | const extended_path = try std.mem.concat(arena, u8, &.{ full_path, ext }); | 96 | const extended_path = try std.mem.concat(arena, u8, &.{ full_path, ext }); |
| 97 | 97 | ||
| 98 | if (Io.Dir.cwd().access(io, extended_path, .{ .execute = true })) |_| { | 98 | if (Io.Dir.cwd().access(io, extended_path, .{ .execute = true })) |_| { |
| 99 | maker.generatedPath(found_path).* = .initCwd(extended_path); | 99 | _ = try maker.setGeneratedPath(found_path, .cwd, &.{extended_path}); |
| 100 | return true; | 100 | return true; |
| 101 | } else |err| switch (err) { | 101 | } else |err| switch (err) { |
| 102 | error.Canceled => |e| return e, | 102 | 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; |
| 56 | 56 |
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 can | 61 | // 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 | } |
| 117 | 106 | ||
| 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 | }; |
| 165 | 154 | ||
| 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 arena | 22 | 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( |
| 80 | 79 | ||
| 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 | } |
| 90 | 86 | ||
| 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 | }; | ||
| 96 | 91 | ||
| 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 | }; |
| 122 | 117 | ||
| 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+29-50| ... | @@ -18,14 +18,13 @@ const Step = @import("../Step.zig"); | ... | @@ -18,14 +18,13 @@ const Step = @import("../Step.zig"); |
| 18 | const Maker = @import("../../Maker.zig"); | 18 | const Maker = @import("../../Maker.zig"); |
| 19 | const Fuzz = @import("../../Maker/Fuzz.zig"); | 19 | const Fuzz = @import("../../Maker/Fuzz.zig"); |
| 20 | 20 | ||
| 21 | /// If this is a Zig unit test binary, this tracks the names of the unit | 21 | /// If this is a Zig unit test binary, this tracks the names of the unit tests that are also fuzz tests. |
| 22 | /// tests that are also fuzz tests. Indexes cannot be used as they may | 22 | /// Indexes cannot be used as they may change between reruns. Memory owned by `Maker.gpa`. |
| 23 | /// change between reruns. | ||
| 24 | fuzz_tests: std.ArrayList([]const u8) = .empty, | 23 | fuzz_tests: std.ArrayList([]const u8) = .empty, |
| 25 | cached_test_metadata: ?CachedTestMetadata = null, | 24 | cached_test_metadata: ?CachedTestMetadata = null, |
| 26 | 25 | ||
| 27 | /// Populated during the fuzz phase if this run step corresponds to a unit test | 26 | /// Populated during the fuzz phase if this run step corresponds to a unit test executable that contains fuzz |
| 28 | /// executable that contains fuzz tests. | 27 | /// tests. `Path.sub_path` owned by `Maker.gpa`. |
| 29 | rebuilt_executable: ?Path = null, | 28 | rebuilt_executable: ?Path = null, |
| 30 | 29 | ||
| 31 | pub fn make( | 30 | pub fn make( |
| ... | @@ -146,7 +145,8 @@ pub fn make( | ... | @@ -146,7 +145,8 @@ pub fn make( |
| 146 | const producer_make_comp_step = maker.stepByIndex(producer_index); | 145 | const producer_make_comp_step = maker.stepByIndex(producer_index); |
| 147 | const producer_make_comp = &producer_make_comp_step.extended.compile; | 146 | const producer_make_comp = &producer_make_comp_step.extended.compile; |
| 148 | 147 | ||
| 149 | const file_path = producer_make_comp.installed_path orelse maker.generatedPath(producer.generated_bin.value.?).*; | 148 | const file_path = producer_make_comp.installed_path orelse |
| 149 | maker.generatedPath(producer.generated_bin.value.?); | ||
| 150 | 150 | ||
| 151 | argv_list.appendAssumeCapacity(try mem.concat(arena, u8, &.{ | 151 | argv_list.appendAssumeCapacity(try mem.concat(arena, u8, &.{ |
| 152 | prefix, try convertPathArg(arena, run_index, maker, file_path, arg.flags.make_absolute), suffix, | 152 | prefix, try convertPathArg(arena, run_index, maker, file_path, arg.flags.make_absolute), suffix, |
| ... | @@ -262,8 +262,8 @@ pub fn make( | ... | @@ -262,8 +262,8 @@ pub fn make( |
| 262 | if (!has_side_effects and try step.cacheHitWatched(maker, &man, progress_node)) { | 262 | if (!has_side_effects and try step.cacheHitWatched(maker, &man, progress_node)) { |
| 263 | // Cache hit; skip running command. | 263 | // Cache hit; skip running command. |
| 264 | const digest = man.hitDigestHex(); | 264 | const digest = man.hitDigestHex(); |
| 265 | try populateGeneratedStdIo(maker, &conf_run, cache_root, &digest); | 265 | try populateGeneratedStdIo(maker, &conf_run, &digest); |
| 266 | try populateGeneratedPaths(maker, output_placeholders.items, cache_root, &digest); | 266 | try populateGeneratedPaths(maker, output_placeholders.items, &digest); |
| 267 | step.result_cached = true; | 267 | step.result_cached = true; |
| 268 | return; | 268 | return; |
| 269 | } | 269 | } |
| ... | @@ -272,7 +272,7 @@ pub fn make( | ... | @@ -272,7 +272,7 @@ pub fn make( |
| 272 | // We already know the final output paths; use them directly. | 272 | // We already know the final output paths; use them directly. |
| 273 | const digest = if (has_side_effects) man.hash.final() else man.missDigestHex(); | 273 | const digest = if (has_side_effects) man.hash.final() else man.missDigestHex(); |
| 274 | const output_dir_path = "o" ++ Dir.path.sep_str ++ &digest; | 274 | const output_dir_path = "o" ++ Dir.path.sep_str ++ &digest; |
| 275 | try populateGeneratedStdIo(maker, &conf_run, cache_root, &digest); | 275 | try populateGeneratedStdIo(maker, &conf_run, &digest); |
| 276 | try populateGeneratedPathsCreateDirs(arena, run_index, maker, output_dir_path, output_placeholders.items, argv_list.items); | 276 | 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); | 277 | 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); | 278 | if (!has_side_effects) try step.finalizeManifestAndWatch(maker, &man); |
| ... | @@ -291,7 +291,7 @@ pub fn make( | ... | @@ -291,7 +291,7 @@ pub fn make( |
| 291 | const arg = placeholder.arg_index.get(conf); | 291 | const arg = placeholder.arg_index.get(conf); |
| 292 | switch (arg.flags.tag) { | 292 | switch (arg.flags.tag) { |
| 293 | .output_file => if (arg.flags.dep_file) { | 293 | .output_file => if (arg.flags.dep_file) { |
| 294 | const generated_path = maker.generatedPath(arg.generated.value.?).*; | 294 | const generated_path = maker.generatedPath(arg.generated.value.?); |
| 295 | if (has_side_effects) { | 295 | if (has_side_effects) { |
| 296 | var diagnostic: Cache.DepTokenizer.Token = undefined; | 296 | var diagnostic: Cache.DepTokenizer.Token = undefined; |
| 297 | man.addInputDepFile(generated_path, &diagnostic) catch |err| switch (err) { | 297 | man.addInputDepFile(generated_path, &diagnostic) catch |err| switch (err) { |
| ... | @@ -362,8 +362,8 @@ pub fn make( | ... | @@ -362,8 +362,8 @@ pub fn make( |
| 362 | 362 | ||
| 363 | if (!has_side_effects) try step.finalizeManifestAndWatch(maker, &man); | 363 | if (!has_side_effects) try step.finalizeManifestAndWatch(maker, &man); |
| 364 | 364 | ||
| 365 | try populateGeneratedStdIo(maker, &conf_run, cache_root, &digest); | 365 | try populateGeneratedStdIo(maker, &conf_run, &digest); |
| 366 | try populateGeneratedPaths(maker, output_placeholders.items, cache_root, &digest); | 366 | try populateGeneratedPaths(maker, output_placeholders.items, &digest); |
| 367 | 367 | ||
| 368 | // The utility functions that spawn the child process must unconditionally allocate | 368 | // 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 will | 369 | // the failed command because at that point it is not known whether the step will |
| ... | @@ -375,6 +375,7 @@ pub fn make( | ... | @@ -375,6 +375,7 @@ pub fn make( |
| 375 | pub fn deinit(run: *Run, gpa: Allocator, io: Io) void { | 375 | pub fn deinit(run: *Run, gpa: Allocator, io: Io) void { |
| 376 | _ = io; | 376 | _ = io; |
| 377 | run.fuzz_tests.deinit(gpa); | 377 | run.fuzz_tests.deinit(gpa); |
| 378 | if (run.rebuilt_executable) |p| gpa.free(p.sub_path); | ||
| 378 | } | 379 | } |
| 379 | 380 | ||
| 380 | fn thirdPartyToggle( | 381 | fn thirdPartyToggle( |
| ... | @@ -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 | else | 1578 | else |
| 1578 | producer_make_comp.installed_path orelse | 1579 | 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( |
| 1615 | fn populateGeneratedPaths( | 1615 | fn 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; | ||
| 1623 | 1621 | ||
| 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 | } |
| 1634 | 1629 | ||
| ... | @@ -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); |
| 1654 | 1649 | ||
| 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 }); |
| 1669 | 1663 | ||
| 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( |
| 1677 | fn populateGeneratedStdIo( | 1669 | fn 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; | ||
| 1685 | 1675 | ||
| 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 | } |
| 1694 | 1681 | ||
| 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 | } |
| 1704 | 1688 | ||
| ... | @@ -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; | ||
| 1999 | 1978 | ||
| 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); |
| 144 | 144 | ||
| 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().?; | ||
| 150 | 151 | ||
| 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}); |
| 153 | 154 | ||
| 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; |
| 29 | 28 | ||
| 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( |
| 106 | 105 | ||
| 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 | } |
| 116 | 112 | ||
| 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 | }; | ||
| 122 | 115 | ||
| 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); |
| 135 | 126 | ||
| 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 | }; | ||
| 140 | 130 | ||
| 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 | } |
lib/std/zig/ErrorBundle.zig+18| ... | @@ -197,6 +197,24 @@ pub fn renderToTerminal(eb: ErrorBundle, options: RenderOptions, t: Io.Terminal) | ... | @@ -197,6 +197,24 @@ pub fn renderToTerminal(eb: ErrorBundle, options: RenderOptions, t: Io.Terminal) |
| 197 | } | 197 | } |
| 198 | } | 198 | } |
| 199 | 199 | ||
| 200 | pub fn readAlloc( | ||
| 201 | r: *Io.Reader, | ||
| 202 | gpa: Allocator, | ||
| 203 | extra_len: u32, | ||
| 204 | string_bytes_len: u32, | ||
| 205 | ) Io.Reader.ReadAllocError!ErrorBundle { | ||
| 206 | const extra = try r.readSliceEndianAlloc(gpa, u32, extra_len, .little); | ||
| 207 | errdefer gpa.free(extra); | ||
| 208 | |||
| 209 | const string_bytes = try r.readAlloc(gpa, string_bytes_len); | ||
| 210 | errdefer gpa.free(string_bytes); | ||
| 211 | |||
| 212 | return .{ | ||
| 213 | .extra = extra, | ||
| 214 | .string_bytes = string_bytes, | ||
| 215 | }; | ||
| 216 | } | ||
| 217 | |||
| 200 | fn renderErrorMessage( | 218 | fn renderErrorMessage( |
| 201 | eb: ErrorBundle, | 219 | eb: ErrorBundle, |
| 202 | options: RenderOptions, | 220 | options: RenderOptions, |
lib/std/zig/Server.zig+13-1| ... | @@ -8,6 +8,7 @@ const OutMessage = std.zig.Server.Message; | ... | @@ -8,6 +8,7 @@ const OutMessage = std.zig.Server.Message; |
| 8 | const InMessage = std.zig.Client.Message; | 8 | const InMessage = std.zig.Client.Message; |
| 9 | const Reader = std.Io.Reader; | 9 | const Reader = std.Io.Reader; |
| 10 | const Writer = std.Io.Writer; | 10 | const Writer = std.Io.Writer; |
| 11 | const Configuration = std.Build.Configuration; | ||
| 11 | 12 | ||
| 12 | in: *Reader, | 13 | in: *Reader, |
| 13 | out: *Writer, | 14 | out: *Writer, |
| ... | @@ -113,10 +114,15 @@ pub const Message = struct { | ... | @@ -113,10 +114,15 @@ pub const Message = struct { |
| 113 | 114 | ||
| 114 | /// Trailing: | 115 | /// Trailing: |
| 115 | /// * error_bundle: ErrorBundle, | 116 | /// * error_bundle: ErrorBundle, |
| 117 | /// * generated_file: [generated_files_len]GeneratedFile, | ||
| 118 | /// * path_bytes: [_]u8, // for each GeneratedFile | ||
| 119 | /// - PathPrefix | ||
| 120 | /// - sub_path: [_]u8, | ||
| 116 | pub const BuildStepCompleted = extern struct { | 121 | pub const BuildStepCompleted = extern struct { |
| 117 | step_index: std.Build.Configuration.Step.Index, | 122 | step_index: Configuration.Step.Index, |
| 118 | status: Status, | 123 | status: Status, |
| 119 | error_bundle: ErrorBundle, | 124 | error_bundle: ErrorBundle, |
| 125 | generated_files_len: u32, | ||
| 120 | // TODO result_error_msgs | 126 | // TODO result_error_msgs |
| 121 | // TODO result_stderr | 127 | // TODO result_stderr |
| 122 | // TODO result_peak_rss | 128 | // TODO result_peak_rss |
| ... | @@ -130,6 +136,12 @@ pub const Message = struct { | ... | @@ -130,6 +136,12 @@ pub const Message = struct { |
| 130 | }; | 136 | }; |
| 131 | }; | 137 | }; |
| 132 | 138 | ||
| 139 | pub const GeneratedFile = extern struct { | ||
| 140 | index: Configuration.GeneratedFileIndex, | ||
| 141 | /// Includes only the path bytes, not the prefix or null byte. | ||
| 142 | path_len: u32, | ||
| 143 | }; | ||
| 144 | |||
| 133 | pub const PathPrefix = enum(u8) { | 145 | pub const PathPrefix = enum(u8) { |
| 134 | cwd, | 146 | cwd, |
| 135 | zig_lib, | 147 | zig_lib, |
tools/bsp.zig+29-1| ... | @@ -184,7 +184,35 @@ pub fn main(init: std.process.Init) !void { | ... | @@ -184,7 +184,35 @@ pub fn main(init: std.process.Init) !void { |
| 184 | .bsp_build_started => {}, | 184 | .bsp_build_started => {}, |
| 185 | .bsp_build_completed => if (!watch) break, | 185 | .bsp_build_completed => if (!watch) break, |
| 186 | .bsp_step_started => {}, | 186 | .bsp_step_started => {}, |
| 187 | .bsp_step_completed => {}, | 187 | .bsp_step_completed => { |
| 188 | var reader: Io.Reader = .fixed(body); | ||
| 189 | const bsc = try reader.takeStruct(Server.Message.BuildStepCompleted, .little); | ||
| 190 | log.info("step {q} {t}: ({d} generated files)", .{ | ||
| 191 | bsc.step_index.ptr(c).name.slice(c), | ||
| 192 | bsc.status, | ||
| 193 | bsc.generated_files_len, | ||
| 194 | }); | ||
| 195 | |||
| 196 | var eb = try std.zig.ErrorBundle.readAlloc( | ||
| 197 | &reader, | ||
| 198 | gpa, | ||
| 199 | bsc.error_bundle.extra_len, | ||
| 200 | bsc.error_bundle.string_bytes_len, | ||
| 201 | ); | ||
| 202 | defer eb.deinit(gpa); | ||
| 203 | try eb.renderToStderr(io, .{}, .auto); | ||
| 204 | |||
| 205 | const modified_files: []align(1) Server.Message.GeneratedFile = @ptrCast( | ||
| 206 | try reader.take(bsc.generated_files_len * @sizeOf(Server.Message.GeneratedFile)), | ||
| 207 | ); | ||
| 208 | for (modified_files) |modified_file| { | ||
| 209 | const prefix = try reader.takeEnum(Server.Message.PathPrefix, .little); | ||
| 210 | const sub_path = try reader.take(modified_file.path_len); | ||
| 211 | log.info("generated file: {d} {t} {q}", .{ | ||
| 212 | modified_file.index, prefix, sub_path, | ||
| 213 | }); | ||
| 214 | } | ||
| 215 | }, | ||
| 188 | .bsp_configuration => @panic("TODO"), | 216 | .bsp_configuration => @panic("TODO"), |
| 189 | else => std.debug.panic("received unexpected message: {f}", .{fmtEnum(header.tag)}), | 217 | else => std.debug.panic("received unexpected message: {f}", .{fmtEnum(header.tag)}), |
| 190 | } | 218 | } |