| ... | ... | @@ -3434,6 +3434,8 @@ fn serveBuildStepCompleted( |
| 3434 | 3434 | const step = maker.stepByIndex(step_index); |
| 3435 | 3435 | const error_bundle = step.result_error_bundle; |
| 3436 | 3436 | |
| 3437 | const gf_size = countGeneratedFiles(maker.generated_files, step_index, &maker.scanned_config.configuration); |
| 3438 | |
| 3437 | 3439 | const body: Server.Message.BuildStepCompleted = .{ |
| 3438 | 3440 | .step_index = step_index, |
| 3439 | 3441 | .status = status, |
| ... | ... | @@ -3441,19 +3443,172 @@ fn serveBuildStepCompleted( |
| 3441 | 3443 | .extra_len = @intCast(error_bundle.extra.len), |
| 3442 | 3444 | .string_bytes_len = @intCast(error_bundle.string_bytes.len), |
| 3443 | 3445 | }, |
| 3446 | .generated_files_len = gf_size.count, |
| 3444 | 3447 | }; |
| 3445 | 3448 | const eb_bytes_len = @sizeOf(u32) * error_bundle.extra.len + error_bundle.string_bytes.len; |
| 3446 | | 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; |
| 3447 | 3451 | try s.serveMessageHeader(.{ |
| 3448 | 3452 | .tag = .bsp_step_completed, |
| 3449 | 3453 | .bytes_len = @intCast(bytes_len), |
| 3450 | 3454 | }); |
| 3451 | 3455 | try s.out.writeStruct(body, .little); |
| 3456 | |
| 3452 | 3457 | try s.out.writeSliceEndian(u32, error_bundle.extra, .little); |
| 3453 | 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 | |
| 3454 | 3463 | try s.out.flush(); |
| 3455 | 3464 | } |
| 3456 | 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 | |
| 3457 | 3612 | fn initStdoutWriter(io: Io) *Writer { |
| 3458 | 3613 | stdout_writer_allocation = Io.File.stdout().writerStreaming(io, &stdio_buffer_allocation); |
| 3459 | 3614 | return &stdout_writer_allocation.interface; |