| 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 | 49 | /// system watching does not need to make any special cases, and to avoid more |
| 50 | 50 | /// OS-specific logic in file system watching implementation. |
| 51 | 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 | 59 | run_args: ?[]const []const u8, |
| 54 | 60 | |
| 55 | 61 | available_rss: u64, |
| ... | ... | @@ -121,6 +127,38 @@ const MultilineErrors = enum { indent, newline, none }; |
| 121 | 127 | const Summary = enum { all, new, failures, line, none }; |
| 122 | 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 | 162 | /// Used to build the -M flags to pass to build-exe. |
| 125 | 163 | pub const CliModule = struct { |
| 126 | 164 | name: []const u8, |
| ... | ... | @@ -2344,7 +2382,8 @@ fn prepare( |
| 2344 | 2382 | // Extra step at the end which is the autogenerated placeholder |
| 2345 | 2383 | // step which indicates that we need to reconfigure. |
| 2346 | 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 | 2388 | // The last element is a reserved special pseudostep which contains the |
| 2350 | 2389 | // watch inputs for the configurer executable. |
| ... | ... | @@ -2676,6 +2715,7 @@ fn deinit(maker: *Maker) void { |
| 2676 | 2715 | const gpa = maker.gpa; |
| 2677 | 2716 | const io = maker.graph.io; |
| 2678 | 2717 | for (maker.steps) |*step| step.deinit(gpa, io); |
| 2718 | for (maker.generated_files) |*gf| gf.clear(gpa); | |
| 2679 | 2719 | maker.memory_blocked_steps.deinit(gpa); |
| 2680 | 2720 | maker.initial_steps.deinit(gpa); |
| 2681 | 2721 | maker.step_stack.deinit(gpa); |
| ... | ... | @@ -2787,7 +2827,8 @@ fn makeStep( |
| 2787 | 2827 | if (maker.web_server) |ws| { |
| 2788 | 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 | 2832 | maker.protocol_server_mutex.lockUncancelable(io); |
| 2792 | 2833 | defer maker.protocol_server_mutex.unlock(io); |
| 2793 | 2834 | |
| ... | ... | @@ -2800,11 +2841,8 @@ fn makeStep( |
| 2800 | 2841 | .dependency_skipped, .skipped => .skipped, |
| 2801 | 2842 | .skipped_oom => .skipped_oom, |
| 2802 | 2843 | }; |
| 2803 | serveBuildStepCompleted( | |
| 2804 | maker, | |
| 2805 | step_index, | |
| 2806 | status, | |
| 2807 | ) catch |err| std.debug.panic("TODO propagate error when failing to send protocol message: {t}", .{err}); | |
| 2844 | serveBuildStepCompleted(maker, step_index, status, s) catch |err| | |
| 2845 | std.debug.panic("TODO propagate error when failing to send protocol message: {t}", .{err}); | |
| 2808 | 2846 | } |
| 2809 | 2847 | |
| 2810 | 2848 | if (!success) std.Progress.setStatus(.failure_working); |
| ... | ... | @@ -3366,7 +3404,7 @@ fn cleanTmpFiles(maker: *Maker, steps: []const Configuration.Step.Index) void { |
| 3366 | 3404 | if (wf.flags.mode != .tmp) continue; |
| 3367 | 3405 | const step = maker.stepByIndex(step_index); |
| 3368 | 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 | 3408 | tmp_path.root_dir.handle.deleteTree(io, tmp_path.subPathOrDot()) catch |err| |
| 3371 | 3409 | log.warn("failed to delete temporary path {f}: {t}", .{ tmp_path, err }); |
| 3372 | 3410 | } |
| ... | ... | @@ -3391,11 +3429,13 @@ fn serveBuildStepCompleted( |
| 3391 | 3429 | maker: *Maker, |
| 3392 | 3430 | step_index: Configuration.Step.Index, |
| 3393 | 3431 | status: Server.Message.BuildStepCompleted.Status, |
| 3432 | s: *Server, | |
| 3394 | 3433 | ) !void { |
| 3395 | const s: *Server = maker.protocol_server.?; | |
| 3396 | 3434 | const step = maker.stepByIndex(step_index); |
| 3397 | 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 | 3439 | const body: Server.Message.BuildStepCompleted = .{ |
| 3400 | 3440 | .step_index = step_index, |
| 3401 | 3441 | .status = status, |
| ... | ... | @@ -3403,19 +3443,172 @@ fn serveBuildStepCompleted( |
| 3403 | 3443 | .extra_len = @intCast(error_bundle.extra.len), |
| 3404 | 3444 | .string_bytes_len = @intCast(error_bundle.string_bytes.len), |
| 3405 | 3445 | }, |
| 3446 | .generated_files_len = gf_size.count, | |
| 3406 | 3447 | }; |
| 3407 | 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 | 3451 | try s.serveMessageHeader(.{ |
| 3410 | 3452 | .tag = .bsp_step_completed, |
| 3411 | 3453 | .bytes_len = @intCast(bytes_len), |
| 3412 | 3454 | }); |
| 3413 | 3455 | try s.out.writeStruct(body, .little); |
| 3456 | ||
| 3414 | 3457 | try s.out.writeSliceEndian(u32, error_bundle.extra, .little); |
| 3415 | 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 | 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 | 3612 | fn initStdoutWriter(io: Io) *Writer { |
| 3420 | 3613 | stdout_writer_allocation = Io.File.stdout().writerStreaming(io, &stdio_buffer_allocation); |
| 3421 | 3614 | return &stdout_writer_allocation.interface; |
| ... | ... | @@ -3434,7 +3627,7 @@ pub fn resolveLazyPath( |
| 3434 | 3627 | .source_path => |sp| try packagePath(maker, arena, sp.owner, sp.sub_path.slice(c)), |
| 3435 | 3628 | .relative => |relative| relativePath(maker, arena, relative), |
| 3436 | 3629 | .generated => |gen| { |
| 3437 | const base = generatedPath(maker, gen.index).*; | |
| 3630 | const base = generatedPath(maker, gen.index); | |
| 3438 | 3631 | var file_path = base; |
| 3439 | 3632 | for (0..gen.flags.up) |_| { |
| 3440 | 3633 | file_path.sub_path = Dir.path.dirname(file_path.sub_path) orelse { |
| ... | ... | @@ -3485,10 +3678,67 @@ pub fn resolveLazyPathIndexAbs( |
| 3485 | 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 | 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 | 3742 | pub fn packagePath( |
| 3493 | 3743 | maker: *const Maker, |
| 3494 | 3744 | arena: Allocator, |
| ... | ... | @@ -3600,7 +3850,7 @@ pub fn installGenerated( |
| 3600 | 3850 | dest_dir: Configuration.InstallDestDir, |
| 3601 | 3851 | asking_step_index: Configuration.Step.Index, |
| 3602 | 3852 | ) !Dir.PrevStatus { |
| 3603 | const src_path = generatedPath(maker, source).*; | |
| 3853 | const src_path = generatedPath(maker, source); | |
| 3604 | 3854 | const dest_dir_path = try resolveInstallDir(maker, arena, dest_dir); |
| 3605 | 3855 | const dest_path = try dest_dir_path.join(arena, src_path.basename()); |
| 3606 | 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 | 4420 | const next_arg = nextArg(args, i) orelse fatalEnumHint(E, arg, null); |
| 4171 | 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 | 161 | fuzz.group.cancel(io); |
| 162 | 162 | fuzz.prog_node.end(); |
| 163 | 163 | gpa.free(fuzz.run_steps); |
| 164 | fuzz.msg_queue.deinit(gpa); | |
| 164 | 165 | } |
| 165 | 166 | |
| 166 | 167 | fn rebuildTestsWorkerRun( |
| ... | ... | @@ -212,7 +213,7 @@ fn rebuildTestsWorkerRunFallible( |
| 212 | 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 | 217 | error.MakeFailed => return, |
| 217 | 218 | else => |other| return other, |
| 218 | 219 | }; |
| ... | ... | @@ -235,7 +236,12 @@ fn rebuildTestsWorkerRunFallible( |
| 235 | 236 | }); |
| 236 | 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 | 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 | 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 | 472 | /// Assumes that argv contains `--listen=-` and that the process being spawned |
| 464 | 473 | /// is the zig compiler - the same version that compiled the build runner. |
| 465 | 474 | /// |
| ... | ... | @@ -470,7 +479,7 @@ pub fn evalZigProcess( |
| 470 | 479 | argv: []const []const u8, |
| 471 | 480 | prog_node: std.Progress.Node, |
| 472 | 481 | watch: bool, |
| 473 | ) (Step.ExtendedMakeError || error{NeedCompileErrorCheck})!?Path { | |
| 482 | ) (Step.ExtendedMakeError || error{NeedCompileErrorCheck})!OptCacheDigest { | |
| 474 | 483 | const s = maker.stepByIndex(step_index); |
| 475 | 484 | const gpa = maker.gpa; |
| 476 | 485 | const graph = maker.graph; |
| ... | ... | @@ -503,7 +512,7 @@ pub fn evalZigProcess( |
| 503 | 512 | if (s.result_error_bundle.errorMessageCount() > 0) |
| 504 | 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 | 516 | // Crash detected. |
| 508 | 517 | const term = zp.child.wait(io) catch |e| { |
| 509 | 518 | return s.fail(maker, "unable to wait for {s}: {t}", .{ argv[0], e }); |
| ... | ... | @@ -578,7 +587,7 @@ pub fn evalZigProcess( |
| 578 | 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 | 591 | const s = maker.stepByIndex(step_index); |
| 583 | 592 | const gpa = maker.gpa; |
| 584 | 593 | const graph = maker.graph; |
| ... | ... | @@ -590,7 +599,7 @@ fn zigProcessUpdate(step_index: Configuration.Step.Index, maker: *Maker, zp: *Zi |
| 590 | 599 | try sendMessage(io, zp.child.stdin.?, .update); |
| 591 | 600 | if (!watch) try sendMessage(io, zp.child.stdin.?, .exit); |
| 592 | 601 | |
| 593 | var result: ?Path = null; | |
| 602 | var result: OptCacheDigest = .{ .bin = null }; | |
| 594 | 603 | var eos_err: error{EndOfStream}!void = {}; |
| 595 | 604 | |
| 596 | 605 | var client: std.zig.Client = .{ |
| ... | ... | @@ -632,11 +641,7 @@ fn zigProcessUpdate(step_index: Configuration.Step.Index, maker: *Maker, zp: *Zi |
| 632 | 641 | const EmitDigest = std.zig.Server.Message.EmitDigest; |
| 633 | 642 | const emit_digest: *align(1) const EmitDigest = @ptrCast(body); |
| 634 | 643 | s.result_cached = emit_digest.flags.cache_hit; |
| 635 | const digest = 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 | }; | |
| 644 | result = .{ .bin = body[@sizeOf(EmitDigest)..][0..Cache.bin_digest_len].* }; | |
| 640 | 645 | }, |
| 641 | 646 | .file_system_inputs => { |
| 642 | 647 | clearWatchInputs(s, maker); |
lib/compiler/Maker/Step/Compile.zig+19-20| ... | ... | @@ -46,7 +46,7 @@ pub fn make( |
| 46 | 46 | |
| 47 | 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 | 50 | compile_index, |
| 51 | 51 | maker, |
| 52 | 52 | argv.items, |
| ... | ... | @@ -63,24 +63,25 @@ pub fn make( |
| 63 | 63 | const root_module = conf_comp.root_module.get(conf); |
| 64 | 64 | const target = root_module.resolved_target.get(conf).?.result.get(conf); |
| 65 | 65 | |
| 66 | // Update generated files | |
| 67 | if (maybe_output_dir) |output_dir| { | |
| 68 | if (conf_comp.emit_directory.value) |gf| maker.generatedPath(gf).* = output_dir; | |
| 69 | try updateGeneratedFile(maker, arena, &conf_comp, output_dir, &target, conf_comp.generated_bin.value, .bin); | |
| 70 | try updateGeneratedFile(maker, arena, &conf_comp, output_dir, &target, conf_comp.generated_pdb.value, .pdb); | |
| 71 | try updateGeneratedFile(maker, arena, &conf_comp, output_dir, &target, conf_comp.generated_implib.value, .implib); | |
| 72 | try updateGeneratedFile(maker, arena, &conf_comp, output_dir, &target, conf_comp.generated_h.value, .h); | |
| 73 | try updateGeneratedFile(maker, arena, &conf_comp, output_dir, &target, conf_comp.generated_docs.value, .docs); | |
| 74 | try updateGeneratedFile(maker, arena, &conf_comp, output_dir, &target, conf_comp.generated_asm.value, .@"asm"); | |
| 75 | try updateGeneratedFile(maker, arena, &conf_comp, output_dir, &target, conf_comp.generated_llvm_ir.value, .llvm_ir); | |
| 76 | try updateGeneratedFile(maker, arena, &conf_comp, output_dir, &target, conf_comp.generated_llvm_bc.value, .llvm_bc); | |
| 66 | if (opt_cache_digest.toHex()) |o_hex_digest| { | |
| 67 | if (conf_comp.emit_directory.value) |gf| { | |
| 68 | _ = try maker.setGeneratedPath(gf, .local_cache, &.{ "o", &o_hex_digest }); | |
| 69 | } | |
| 70 | try updateGeneratedFile(maker, arena, &conf_comp, &o_hex_digest, &target, conf_comp.generated_bin.value, .bin); | |
| 71 | try updateGeneratedFile(maker, arena, &conf_comp, &o_hex_digest, &target, conf_comp.generated_pdb.value, .pdb); | |
| 72 | try updateGeneratedFile(maker, arena, &conf_comp, &o_hex_digest, &target, conf_comp.generated_implib.value, .implib); | |
| 73 | try updateGeneratedFile(maker, arena, &conf_comp, &o_hex_digest, &target, conf_comp.generated_h.value, .h); | |
| 74 | try updateGeneratedFile(maker, arena, &conf_comp, &o_hex_digest, &target, conf_comp.generated_docs.value, .docs); | |
| 75 | try updateGeneratedFile(maker, arena, &conf_comp, &o_hex_digest, &target, conf_comp.generated_asm.value, .@"asm"); | |
| 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 | 80 | if (conf_comp.flags3.kind == .lib and conf_comp.flags2.linkage == .dynamic and |
| 80 | 81 | conf_comp.version.value != null and target.flags.os_tag != .windows) |
| 81 | 82 | { |
| 82 | 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 | 85 | try maker.installSymLinks(arena, full_dest_path, compile_index, compile_index); |
| 85 | 86 | } |
| 86 | 87 | } |
| ... | ... | @@ -97,13 +98,12 @@ fn updateGeneratedFile( |
| 97 | 98 | maker: *Maker, |
| 98 | 99 | arena: Allocator, |
| 99 | 100 | conf_comp: *const Configuration.Step.Compile, |
| 100 | out_path: std.Build.Cache.Path, | |
| 101 | o_hex_digest: *const std.Build.Cache.HexDigest, | |
| 101 | 102 | target: *const Configuration.TargetQuery, |
| 102 | 103 | opt_gf: ?Configuration.GeneratedFileIndex, |
| 103 | 104 | ea: std.zig.EmitArtifact, |
| 104 | 105 | ) Allocator.Error!void { |
| 105 | 106 | const gf = opt_gf orelse return; |
| 106 | const graph = maker.graph; | |
| 107 | 107 | const conf = &maker.scanned_config.configuration; |
| 108 | 108 | const name = try ea.cacheName(arena, .{ |
| 109 | 109 | .root_name = conf_comp.root_name.slice(conf), |
| ... | ... | @@ -122,7 +122,7 @@ fn updateGeneratedFile( |
| 122 | 122 | else |
| 123 | 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 | 128 | /// List of importable modules in a compilation's module graph, including |
| ... | ... | @@ -943,7 +943,7 @@ pub fn rebuildInFuzzMode( |
| 943 | 943 | maker: *Maker, |
| 944 | 944 | compile_index: Configuration.Step.Index, |
| 945 | 945 | progress_node: std.Progress.Node, |
| 946 | ) !Path { | |
| 946 | ) !Step.OptCacheDigest { | |
| 947 | 947 | const gpa = maker.gpa; |
| 948 | 948 | const step = maker.stepByIndex(compile_index); |
| 949 | 949 | |
| ... | ... | @@ -963,8 +963,7 @@ pub fn rebuildInFuzzMode( |
| 963 | 963 | defer argv.deinit(gpa); |
| 964 | 964 | |
| 965 | 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); | |
| 967 | return maybe_output_bin_path.?; | |
| 966 | return Step.evalZigProcess(compile_index, maker, argv.items, progress_node, false); | |
| 968 | 967 | } |
| 969 | 968 | |
| 970 | 969 | fn addBool(gpa: Allocator, args: *std.ArrayList([]const u8), arg: []const u8, opt: bool) !void { |
| ... | ... | @@ -1380,7 +1379,7 @@ pub fn appendIncludeDirFlags( |
| 1380 | 1379 | }, |
| 1381 | 1380 | .config_header_step => |ch_index| { |
| 1382 | 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 | 1383 | zig_args.appendAssumeCapacity("-I"); |
| 1385 | 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 | 34 | const conf = &maker.scanned_config.configuration; |
| 35 | 35 | const conf_step = step_index.ptr(conf); |
| 36 | 36 | const conf_ch = conf_step.extended.get(conf.extra).config_header; |
| 37 | const cache_root = graph.local_cache_root; | |
| 38 | 37 | |
| 39 | 38 | const input_size_limit: Io.Limit = if (conf_ch.input_size_limit.value) |x| .limited64(x) else .unlimited; |
| 40 | 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 | 137 | |
| 139 | 138 | if (try step.cacheHit(maker, &man, progress_node)) { |
| 140 | 139 | const digest = man.hitDigestHex(); |
| 141 | maker.generatedPath(conf_ch.generated_dir).* = .{ | |
| 142 | .root_dir = cache_root, | |
| 143 | .sub_path = try Io.Dir.path.join(arena, &.{ "o", &digest }), | |
| 144 | }; | |
| 140 | _ = try maker.setGeneratedPath(conf_ch.generated_dir, .local_cache, &.{ "o", &digest }); | |
| 145 | 141 | return; |
| 146 | 142 | } |
| 147 | 143 | |
| ... | ... | @@ -152,22 +148,16 @@ pub fn make( |
| 152 | 148 | // output_path is libavutil/avconfig.h |
| 153 | 149 | // We want to open directory zig-cache/o/HASH/libavutil/ |
| 154 | 150 | // but keep output_dir as zig-cache/o/HASH for -I include |
| 155 | const out_path: Path = .{ | |
| 156 | .root_dir = cache_root, | |
| 157 | .sub_path = try Io.Dir.path.join(arena, &.{ "o", &digest, conf_ch.include_path.slice(conf) }), | |
| 158 | }; | |
| 151 | ||
| 152 | const artifact_path = try maker.setGeneratedPath(conf_ch.generated_dir, .local_cache, &.{ "o", &digest }); | |
| 153 | const out_path = try artifact_path.join(arena, conf_ch.include_path.slice(conf)); | |
| 159 | 154 | const out_path_dirname = out_path.dirname().?; |
| 160 | 155 | |
| 161 | 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 | 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 }); | |
| 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 | }; | |
| 160 | return step.fail(maker, "failed to write file {qf}: {t}", .{ out_path, err }); | |
| 171 | 161 | |
| 172 | 162 | try step.finalizeManifest(maker, &man); |
| 173 | 163 | } |
lib/compiler/Maker/Step/FindProgram.zig+2-2| ... | ... | @@ -77,7 +77,7 @@ fn checkCandidate( |
| 77 | 77 | const io = graph.io; |
| 78 | 78 | |
| 79 | 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 | 81 | return true; |
| 82 | 82 | } else |err| switch (err) { |
| 83 | 83 | error.Canceled => |e| return e, |
| ... | ... | @@ -96,7 +96,7 @@ fn checkCandidate( |
| 96 | 96 | const extended_path = try std.mem.concat(arena, u8, &.{ full_path, ext }); |
| 97 | 97 | |
| 98 | 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 | 100 | return true; |
| 101 | 101 | } else |err| switch (err) { |
| 102 | 102 | error.Canceled => |e| return e, |
lib/compiler/Maker/Step/InstallArtifact.zig+1-1| ... | ... | @@ -50,7 +50,7 @@ pub fn make( |
| 50 | 50 | }); |
| 51 | 51 | const dest_dir = try maker.resolveInstallDir(arena, bin_dir); |
| 52 | 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 | 54 | const p = try maker.installPath(arena, src_path, dest_path, step_index); |
| 55 | 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 | 22 | const conf = &maker.scanned_config.configuration; |
| 23 | 23 | const conf_step = step_index.ptr(conf); |
| 24 | 24 | const conf_oc = conf_step.extended.get(conf.extra).obj_copy; |
| 25 | const cache_root = graph.local_cache_root; | |
| 26 | 25 | const input_lazy_path = conf_oc.input_file.get(conf); |
| 27 | 26 | const only_section: ?[]const u8 = if (conf_oc.only_section.value) |s| s.slice(conf) else null; |
| 28 | 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 | 48 | if (try step.cacheHit(maker, &man, progress_node)) { |
| 50 | 49 | // Cache hit, skip subprocess execution. |
| 51 | 50 | const digest = man.hitDigestHex(); |
| 52 | maker.generatedPath(conf_oc.output_file).* = .{ | |
| 53 | .root_dir = cache_root, | |
| 54 | .sub_path = try Io.Dir.path.join(arena, &.{ "o", &digest, basename }), | |
| 55 | }; | |
| 51 | _ = try maker.setGeneratedPath(conf_oc.output_file, .local_cache, &.{ "o", &digest, basename }); | |
| 56 | 52 | if (conf_oc.debug_file.value) |debug_file| { |
| 57 | 53 | const debug_basename = opt_debug_basename orelse try arena.print("{s}.debug", .{ |
| 58 | 54 | Io.Dir.path.basename(input_path.sub_path), |
| 59 | 55 | }); |
| 60 | maker.generatedPath(debug_file).* = .{ | |
| 61 | .root_dir = cache_root, | |
| 62 | .sub_path = try Io.Dir.path.join(arena, &.{ "o", &digest, debug_basename }), | |
| 63 | }; | |
| 56 | _ = try maker.setGeneratedPath(debug_file, .local_cache, &.{ "o", &digest, debug_basename }); | |
| 64 | 57 | } |
| 65 | 58 | return; |
| 66 | 59 | } |
| ... | ... | @@ -68,10 +61,8 @@ pub fn make( |
| 68 | 61 | // We don't find out more input files while executing objcopy so we can |
| 69 | 62 | // already obtain the digest and use it directly as the output path. |
| 70 | 63 | const digest = man.missDigestHex(); |
| 71 | const dest_path: Path = .{ | |
| 72 | .root_dir = cache_root, | |
| 73 | .sub_path = try Io.Dir.path.join(arena, &.{ "o", &digest, basename }), | |
| 74 | }; | |
| 64 | const dest_path = try maker.setGeneratedPath(conf_oc.output_file, .local_cache, &.{ "o", &digest, basename }); | |
| 65 | ||
| 75 | 66 | const dest_dirname = dest_path.dirname().?; |
| 76 | 67 | dest_dirname.root_dir.handle.createDirPath(io, dest_dirname.sub_path) catch |err| |
| 77 | 68 | return step.fail(maker, "failed to create path {f}: {t}", .{ dest_dirname, err }); |
| ... | ... | @@ -107,12 +98,10 @@ pub fn make( |
| 107 | 98 | const debug_basename = opt_debug_basename orelse try arena.print("{s}.debug", .{ |
| 108 | 99 | Io.Dir.path.basename(input_path.sub_path), |
| 109 | 100 | }); |
| 110 | const debug_dest_path: Path = .{ | |
| 111 | .root_dir = cache_root, | |
| 112 | .sub_path = try Io.Dir.path.join(arena, &.{ "o", &digest, debug_basename }), | |
| 113 | }; | |
| 101 | const debug_dest_path = try maker.setGeneratedPath(debug_file, .local_cache, &.{ | |
| 102 | "o", &digest, debug_basename, | |
| 103 | }); | |
| 114 | 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 | 107 | try argv.ensureUnusedCapacity(arena, conf_oc.add_section.slice.len * 2); |
| ... | ... | @@ -163,8 +152,6 @@ pub fn make( |
| 163 | 152 | else => |e| return e, |
| 164 | 153 | }; |
| 165 | 154 | |
| 166 | maker.generatedPath(conf_oc.output_file).* = dest_path; | |
| 167 | ||
| 168 | 155 | step.finalizeManifest(maker, &man) catch |err| switch (err) { |
| 169 | 156 | error.Canceled => |e| return e, |
| 170 | 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 | 19 | const graph = maker.graph; |
| 20 | 20 | const step = maker.stepByIndex(step_index); |
| 21 | 21 | const io = graph.io; |
| 22 | const cache_root = graph.local_cache_root; | |
| 23 | 22 | const arena = graph.arena; // TODO don't leak into the process arena |
| 24 | 23 | const conf = &maker.scanned_config.configuration; |
| 25 | 24 | const conf_step = step_index.ptr(conf); |
| ... | ... | @@ -80,19 +79,15 @@ pub fn make( |
| 80 | 79 | |
| 81 | 80 | if (try step.cacheHitWatched(maker, &man, progress_node)) { |
| 82 | 81 | const digest = man.hitDigestHex(); |
| 83 | maker.generatedPath(conf_options.generated_file).* = .{ | |
| 84 | .root_dir = cache_root, | |
| 85 | .sub_path = try Io.Dir.path.join(arena, &.{ "o", &digest, basename }), | |
| 86 | }; | |
| 82 | _ = try maker.setGeneratedPath(conf_options.generated_file, .local_cache, &.{ "o", &digest, basename }); | |
| 87 | 83 | step.result_cached = true; |
| 88 | 84 | return; |
| 89 | 85 | } |
| 90 | 86 | |
| 91 | 87 | const digest = man.missDigestHex(); |
| 92 | const out_path: Cache.Path = .{ | |
| 93 | .root_dir = cache_root, | |
| 94 | .sub_path = try Io.Dir.path.join(arena, &.{ "o", &digest, basename }), | |
| 95 | }; | |
| 88 | const out_path = try maker.setGeneratedPath(conf_options.generated_file, .local_cache, &.{ | |
| 89 | "o", &digest, basename, | |
| 90 | }); | |
| 96 | 91 | |
| 97 | 92 | var file: Io.File = out_path.root_dir.handle.createFile(io, out_path.sub_path, .{}) catch |err| switch (err) { |
| 98 | 93 | error.Canceled => |e| return e, |
| ... | ... | @@ -121,6 +116,4 @@ pub fn make( |
| 121 | 116 | }; |
| 122 | 117 | |
| 123 | 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 | 18 | const Maker = @import("../../Maker.zig"); |
| 19 | 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 | |
| 22 | /// tests that are also fuzz tests. Indexes cannot be used as they may | |
| 23 | /// change between reruns. | |
| 21 | /// If this is a Zig unit test binary, this tracks the names of the unit tests that are also fuzz tests. | |
| 22 | /// Indexes cannot be used as they may change between reruns. Memory owned by `Maker.gpa`. | |
| 24 | 23 | fuzz_tests: std.ArrayList([]const u8) = .empty, |
| 25 | 24 | cached_test_metadata: ?CachedTestMetadata = null, |
| 26 | 25 | |
| 27 | /// Populated during the fuzz phase if this run step corresponds to a unit test | |
| 28 | /// executable that contains fuzz tests. | |
| 26 | /// Populated during the fuzz phase if this run step corresponds to a unit test executable that contains fuzz | |
| 27 | /// tests. `Path.sub_path` owned by `Maker.gpa`. | |
| 29 | 28 | rebuilt_executable: ?Path = null, |
| 30 | 29 | |
| 31 | 30 | pub fn make( |
| ... | ... | @@ -146,7 +145,8 @@ pub fn make( |
| 146 | 145 | const producer_make_comp_step = maker.stepByIndex(producer_index); |
| 147 | 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 | 151 | argv_list.appendAssumeCapacity(try mem.concat(arena, u8, &.{ |
| 152 | 152 | prefix, try convertPathArg(arena, run_index, maker, file_path, arg.flags.make_absolute), suffix, |
| ... | ... | @@ -262,8 +262,8 @@ pub fn make( |
| 262 | 262 | if (!has_side_effects and try step.cacheHitWatched(maker, &man, progress_node)) { |
| 263 | 263 | // Cache hit; skip running command. |
| 264 | 264 | const digest = man.hitDigestHex(); |
| 265 | try populateGeneratedStdIo(maker, &conf_run, cache_root, &digest); | |
| 266 | try populateGeneratedPaths(maker, output_placeholders.items, cache_root, &digest); | |
| 265 | try populateGeneratedStdIo(maker, &conf_run, &digest); | |
| 266 | try populateGeneratedPaths(maker, output_placeholders.items, &digest); | |
| 267 | 267 | step.result_cached = true; |
| 268 | 268 | return; |
| 269 | 269 | } |
| ... | ... | @@ -272,7 +272,7 @@ pub fn make( |
| 272 | 272 | // We already know the final output paths; use them directly. |
| 273 | 273 | const digest = if (has_side_effects) man.hash.final() else man.missDigestHex(); |
| 274 | 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 | 276 | try populateGeneratedPathsCreateDirs(arena, run_index, maker, output_dir_path, output_placeholders.items, argv_list.items); |
| 277 | 277 | try runCommand(arena, run, run_index, maker, progress_node, argv_list.items, has_side_effects, output_dir_path, null); |
| 278 | 278 | if (!has_side_effects) try step.finalizeManifestAndWatch(maker, &man); |
| ... | ... | @@ -291,7 +291,7 @@ pub fn make( |
| 291 | 291 | const arg = placeholder.arg_index.get(conf); |
| 292 | 292 | switch (arg.flags.tag) { |
| 293 | 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 | 295 | if (has_side_effects) { |
| 296 | 296 | var diagnostic: Cache.DepTokenizer.Token = undefined; |
| 297 | 297 | man.addInputDepFile(generated_path, &diagnostic) catch |err| switch (err) { |
| ... | ... | @@ -362,8 +362,8 @@ pub fn make( |
| 362 | 362 | |
| 363 | 363 | if (!has_side_effects) try step.finalizeManifestAndWatch(maker, &man); |
| 364 | 364 | |
| 365 | try populateGeneratedStdIo(maker, &conf_run, cache_root, &digest); | |
| 366 | try populateGeneratedPaths(maker, output_placeholders.items, cache_root, &digest); | |
| 365 | try populateGeneratedStdIo(maker, &conf_run, &digest); | |
| 366 | try populateGeneratedPaths(maker, output_placeholders.items, &digest); | |
| 367 | 367 | |
| 368 | 368 | // The utility functions that spawn the child process must unconditionally allocate |
| 369 | 369 | // the failed command because at that point it is not known whether the step will |
| ... | ... | @@ -375,6 +375,7 @@ pub fn make( |
| 375 | 375 | pub fn deinit(run: *Run, gpa: Allocator, io: Io) void { |
| 376 | 376 | _ = io; |
| 377 | 377 | run.fuzz_tests.deinit(gpa); |
| 378 | if (run.rebuilt_executable) |p| gpa.free(p.sub_path); | |
| 378 | 379 | } |
| 379 | 380 | |
| 380 | 381 | fn thirdPartyToggle( |
| ... | ... | @@ -1575,8 +1576,7 @@ pub fn rerunInFuzzMode( |
| 1575 | 1576 | const file_path: Path = if (producer_index == conf_run.producer.value.?) |
| 1576 | 1577 | run.rebuilt_executable.? |
| 1577 | 1578 | else |
| 1578 | producer_make_comp.installed_path orelse | |
| 1579 | maker.generatedPath(producer.generated_bin.value.?).*; | |
| 1579 | producer_make_comp.installed_path orelse maker.generatedPath(producer.generated_bin.value.?); | |
| 1580 | 1580 | argv_list.appendAssumeCapacity(try mem.concat(arena, u8, &.{ |
| 1581 | 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 | 1615 | fn populateGeneratedPaths( |
| 1616 | 1616 | maker: *Maker, |
| 1617 | 1617 | output_placeholders: []const IndexedOutput, |
| 1618 | cache_root: Cache.Directory, | |
| 1619 | 1618 | digest: *const Cache.HexDigest, |
| 1620 | 1619 | ) !void { |
| 1621 | 1620 | const conf = &maker.scanned_config.configuration; |
| 1622 | const graph = maker.graph; | |
| 1623 | 1621 | |
| 1624 | 1622 | for (output_placeholders) |placeholder| { |
| 1625 | 1623 | const arg = placeholder.arg_index.get(conf); |
| 1626 | maker.generatedPath(arg.generated.value.?).* = .{ | |
| 1627 | .root_dir = cache_root, | |
| 1628 | .sub_path = try Dir.path.join(graph.arena, &.{ | |
| 1629 | "o", digest, arg.basename.value.?.slice(conf), | |
| 1630 | }), | |
| 1631 | }; | |
| 1624 | _ = try maker.setGeneratedPath(arg.generated.value.?, .local_cache, &.{ | |
| 1625 | "o", digest, arg.basename.value.?.slice(conf), | |
| 1626 | }); | |
| 1632 | 1627 | } |
| 1633 | 1628 | } |
| 1634 | 1629 | |
| ... | ... | @@ -1652,10 +1647,9 @@ fn populateGeneratedPathsCreateDirs( |
| 1652 | 1647 | const suffix = if (arg.suffix.value) |p| p.slice(conf) else ""; |
| 1653 | 1648 | const basename = arg.basename.value.?.slice(conf); |
| 1654 | 1649 | |
| 1655 | const generated_path: Path = .{ | |
| 1656 | .root_dir = cache_root, | |
| 1657 | .sub_path = try Dir.path.join(graph.arena, &.{ output_dir_path, basename }), | |
| 1658 | }; | |
| 1650 | const generated_path = try maker.setGeneratedPath(arg.generated.value.?, .local_cache, &.{ | |
| 1651 | output_dir_path, basename, | |
| 1652 | }); | |
| 1659 | 1653 | const create_path: Path = .{ |
| 1660 | 1654 | .root_dir = cache_root, |
| 1661 | 1655 | .sub_path = switch (arg.flags.tag) { |
| ... | ... | @@ -1667,8 +1661,6 @@ fn populateGeneratedPathsCreateDirs( |
| 1667 | 1661 | create_path.root_dir.handle.createDirPath(io, create_path.sub_path) catch |err| |
| 1668 | 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 | 1664 | const arg_output_path = try convertPathArg(arena, run_index, maker, generated_path, arg.flags.make_absolute); |
| 1673 | 1665 | argv[placeholder.index] = try mem.concat(arena, u8, &.{ prefix, arg_output_path, suffix }); |
| 1674 | 1666 | } |
| ... | ... | @@ -1677,28 +1669,20 @@ fn populateGeneratedPathsCreateDirs( |
| 1677 | 1669 | fn populateGeneratedStdIo( |
| 1678 | 1670 | maker: *Maker, |
| 1679 | 1671 | conf_run: *const Configuration.Step.Run, |
| 1680 | cache_root: Cache.Directory, | |
| 1681 | 1672 | digest: *const Cache.HexDigest, |
| 1682 | 1673 | ) !void { |
| 1683 | 1674 | const conf = &maker.scanned_config.configuration; |
| 1684 | const graph = maker.graph; | |
| 1685 | 1675 | |
| 1686 | 1676 | if (conf_run.captured_stdout.value) |captured| { |
| 1687 | maker.generatedPath(captured.generated_file).* = .{ | |
| 1688 | .root_dir = cache_root, | |
| 1689 | .sub_path = try Dir.path.join(graph.arena, &.{ | |
| 1690 | "o", digest, captured.basename.slice(conf), | |
| 1691 | }), | |
| 1692 | }; | |
| 1677 | _ = try maker.setGeneratedPath(captured.generated_file, .local_cache, &.{ | |
| 1678 | "o", digest, captured.basename.slice(conf), | |
| 1679 | }); | |
| 1693 | 1680 | } |
| 1694 | 1681 | |
| 1695 | 1682 | if (conf_run.captured_stderr.value) |captured| { |
| 1696 | maker.generatedPath(captured.generated_file).* = .{ | |
| 1697 | .root_dir = cache_root, | |
| 1698 | .sub_path = try Dir.path.join(graph.arena, &.{ | |
| 1699 | "o", digest, captured.basename.slice(conf), | |
| 1700 | }), | |
| 1701 | }; | |
| 1683 | _ = try maker.setGeneratedPath(captured.generated_file, .local_cache, &.{ | |
| 1684 | "o", digest, captured.basename.slice(conf), | |
| 1685 | }); | |
| 1702 | 1686 | } |
| 1703 | 1687 | } |
| 1704 | 1688 | |
| ... | ... | @@ -1735,7 +1719,6 @@ fn runCommand( |
| 1735 | 1719 | const gpa = maker.gpa; |
| 1736 | 1720 | const step = maker.stepByIndex(run_index); |
| 1737 | 1721 | const io = graph.io; |
| 1738 | const cache_root = graph.local_cache_root; | |
| 1739 | 1722 | const conf = &maker.scanned_config.configuration; |
| 1740 | 1723 | const conf_step = run_index.ptr(conf); |
| 1741 | 1724 | const conf_run = conf_step.extended.get(conf.extra).run; |
| ... | ... | @@ -1989,13 +1972,9 @@ fn runCommand( |
| 1989 | 1972 | }, |
| 1990 | 1973 | }) |*stream| { |
| 1991 | 1974 | if (stream.captured) |captured| { |
| 1992 | const output_path: Path = .{ | |
| 1993 | .root_dir = cache_root, | |
| 1994 | .sub_path = try Dir.path.join(graph.arena, &.{ | |
| 1995 | output_dir_path, captured.basename.slice(conf), | |
| 1996 | }), | |
| 1997 | }; | |
| 1998 | maker.generatedPath(captured.generated_file).* = output_path; | |
| 1975 | const output_path = try maker.setGeneratedPath(captured.generated_file, .local_cache, &.{ | |
| 1976 | output_dir_path, captured.basename.slice(conf), | |
| 1977 | }); | |
| 1999 | 1978 | |
| 2000 | 1979 | const sub_path_parent = output_path.dirname().?; |
| 2001 | 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 | 143 | argv.appendAssumeCapacity(c_source_path); |
| 144 | 144 | |
| 145 | 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 | 147 | error.NeedCompileErrorCheck => unreachable, |
| 148 | 148 | else => |e| return e, |
| 149 | }).?; | |
| 149 | }; | |
| 150 | const o_hex_digest = opt_cache_digest.toHex().?; | |
| 150 | 151 | |
| 151 | 152 | const stem = Io.Dir.path.stem(Io.Dir.path.basename(c_source_path)); |
| 152 | 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 | 24 | const conf = &maker.scanned_config.configuration; |
| 25 | 25 | const conf_step = step_index.ptr(conf); |
| 26 | 26 | const conf_wf = conf_step.extended.get(conf.extra).write_file; |
| 27 | const cache_root = graph.local_cache_root; | |
| 28 | 27 | const directories = conf_wf.directories.slice; |
| 29 | 28 | |
| 30 | 29 | const open_dir_cache = try arena.alloc(Io.Dir, directories.len); |
| ... | ... | @@ -106,25 +105,17 @@ pub fn make( |
| 106 | 105 | |
| 107 | 106 | if (try step.cacheHit(maker, &man, progress_node)) { |
| 108 | 107 | const digest = man.hitDigestHex(); |
| 109 | maker.generatedPath(conf_wf.generated_directory).* = .{ | |
| 110 | .root_dir = cache_root, | |
| 111 | .sub_path = try Io.Dir.path.join(arena, &.{ "o", &digest }), | |
| 112 | }; | |
| 108 | _ = try maker.setGeneratedPath(conf_wf.generated_directory, .local_cache, &.{ "o", &digest }); | |
| 113 | 109 | assert(step.result_cached); |
| 114 | 110 | return; |
| 115 | 111 | } |
| 116 | 112 | |
| 117 | 113 | const digest = man.missDigestHex(); |
| 118 | const out_path: Path = .{ | |
| 119 | .root_dir = cache_root, | |
| 120 | .sub_path = try Io.Dir.path.join(arena, &.{ "o", &digest }), | |
| 121 | }; | |
| 114 | const out_path = try maker.setGeneratedPath(conf_wf.generated_directory, .local_cache, &.{ "o", &digest }); | |
| 122 | 115 | |
| 123 | 116 | progress_node.setEstimatedTotalItems(total_items); |
| 124 | 117 | try operate(maker, step_index, open_dir_cache, out_path, progress_node); |
| 125 | 118 | try step.finalizeManifest(maker, &man); |
| 126 | ||
| 127 | maker.generatedPath(conf_wf.generated_directory).* = out_path; | |
| 128 | 119 | }, |
| 129 | 120 | .tmp => { |
| 130 | 121 | step.result_cached = false; |
| ... | ... | @@ -133,20 +124,17 @@ pub fn make( |
| 133 | 124 | io.random(@ptrCast(&rand_int)); |
| 134 | 125 | const hex_digest = std.fmt.hex(rand_int); |
| 135 | 126 | |
| 136 | const out_path: Path = .{ | |
| 137 | .root_dir = cache_root, | |
| 138 | .sub_path = try Io.Dir.path.join(arena, &.{ "tmp", &hex_digest }), | |
| 139 | }; | |
| 127 | const out_path = try maker.setGeneratedPath(conf_wf.generated_directory, .local_cache, &.{ | |
| 128 | "tmp", &hex_digest, | |
| 129 | }); | |
| 140 | 130 | |
| 141 | 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 | 133 | .mutate => { |
| 146 | 134 | step.result_cached = false; |
| 147 | 135 | const root_path = try maker.resolveLazyPathIndex(arena, conf_wf.mutate_path.value.?, step_index); |
| 148 | 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 | 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 | 218 | fn renderErrorMessage( |
| 201 | 219 | eb: ErrorBundle, |
| 202 | 220 | options: RenderOptions, |
lib/std/zig/Server.zig+13-1| ... | ... | @@ -8,6 +8,7 @@ const OutMessage = std.zig.Server.Message; |
| 8 | 8 | const InMessage = std.zig.Client.Message; |
| 9 | 9 | const Reader = std.Io.Reader; |
| 10 | 10 | const Writer = std.Io.Writer; |
| 11 | const Configuration = std.Build.Configuration; | |
| 11 | 12 | |
| 12 | 13 | in: *Reader, |
| 13 | 14 | out: *Writer, |
| ... | ... | @@ -113,10 +114,15 @@ pub const Message = struct { |
| 113 | 114 | |
| 114 | 115 | /// Trailing: |
| 115 | 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 | 121 | pub const BuildStepCompleted = extern struct { |
| 117 | step_index: std.Build.Configuration.Step.Index, | |
| 122 | step_index: Configuration.Step.Index, | |
| 118 | 123 | status: Status, |
| 119 | 124 | error_bundle: ErrorBundle, |
| 125 | generated_files_len: u32, | |
| 120 | 126 | // TODO result_error_msgs |
| 121 | 127 | // TODO result_stderr |
| 122 | 128 | // TODO result_peak_rss |
| ... | ... | @@ -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 | 145 | pub const PathPrefix = enum(u8) { |
| 134 | 146 | cwd, |
| 135 | 147 | zig_lib, |
tools/bsp.zig+29-1| ... | ... | @@ -184,7 +184,35 @@ pub fn main(init: std.process.Init) !void { |
| 184 | 184 | .bsp_build_started => {}, |
| 185 | 185 | .bsp_build_completed => if (!watch) break, |
| 186 | 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 | 216 | .bsp_configuration => @panic("TODO"), |
| 189 | 217 | else => std.debug.panic("received unexpected message: {f}", .{fmtEnum(header.tag)}), |
| 190 | 218 | } |