Commit 8acbfafefb

Andrew Kelley <andrew@ziglang.org>
2023-03-01 05:14:32
compiler: update function accepts a std.Progress.Node
This makes progress be exposed to the top-level caller of update(). I tossed in a bonus change: when the `zig build` subcommand sees exit code 2, it omits the "following command failed" line, and the build runner uses exit code 2 when there are compile errors. This tidies up the output on build failure by a little bit.
1 parent 85b4b6e
src/Compilation.zig
@@ -1847,8 +1847,15 @@ fn cleanupTmpArtifactDirectory(
     }
 }
 
+pub fn hotCodeSwap(comp: *Compilation, prog_node: *std.Progress.Node, pid: std.os.pid_t) !void {
+    comp.bin_file.child_pid = pid;
+    try comp.makeBinFileWritable();
+    try comp.update(prog_node);
+    try comp.makeBinFileExecutable();
+}
+
 /// Detect changes to source files, perform semantic analysis, and update the output files.
-pub fn update(comp: *Compilation) !void {
+pub fn update(comp: *Compilation, main_progress_node: *std.Progress.Node) !void {
     const tracy_trace = trace(@src());
     defer tracy_trace.end();
 
@@ -1995,21 +2002,6 @@ pub fn update(comp: *Compilation) !void {
         }
     }
 
-    // If the terminal is dumb, we dont want to show the user all the output.
-    var progress: std.Progress = .{ .dont_print_on_dumb = true };
-    const main_progress_node = progress.start("", 0);
-    defer main_progress_node.end();
-    switch (comp.color) {
-        .off => {
-            progress.terminal = null;
-        },
-        .on => {
-            progress.terminal = std.io.getStdErr();
-            progress.supports_ansi_escape_codes = true;
-        },
-        .auto => {},
-    }
-
     try comp.performAllTheWork(main_progress_node);
 
     if (comp.bin_file.options.module) |module| {
@@ -3057,11 +3049,11 @@ pub fn performAllTheWork(
     // backend, preventing anonymous Decls from being prematurely destroyed.
     while (true) {
         if (comp.work_queue.readItem()) |work_item| {
-            try processOneJob(comp, work_item);
+            try processOneJob(comp, work_item, main_progress_node);
             continue;
         }
         if (comp.anon_work_queue.readItem()) |work_item| {
-            try processOneJob(comp, work_item);
+            try processOneJob(comp, work_item, main_progress_node);
             continue;
         }
         break;
@@ -3069,16 +3061,16 @@ pub fn performAllTheWork(
 
     if (comp.job_queued_compiler_rt_lib) {
         comp.job_queued_compiler_rt_lib = false;
-        buildCompilerRtOneShot(comp, .Lib, &comp.compiler_rt_lib);
+        buildCompilerRtOneShot(comp, .Lib, &comp.compiler_rt_lib, main_progress_node);
     }
 
     if (comp.job_queued_compiler_rt_obj) {
         comp.job_queued_compiler_rt_obj = false;
-        buildCompilerRtOneShot(comp, .Obj, &comp.compiler_rt_obj);
+        buildCompilerRtOneShot(comp, .Obj, &comp.compiler_rt_obj, main_progress_node);
     }
 }
 
-fn processOneJob(comp: *Compilation, job: Job) !void {
+fn processOneJob(comp: *Compilation, job: Job, prog_node: *std.Progress.Node) !void {
     switch (job) {
         .codegen_decl => |decl_index| {
             const module = comp.bin_file.options.module.?;
@@ -3230,7 +3222,7 @@ fn processOneJob(comp: *Compilation, job: Job) !void {
             const named_frame = tracy.namedFrame("glibc_crt_file");
             defer named_frame.end();
 
-            glibc.buildCRTFile(comp, crt_file) catch |err| {
+            glibc.buildCRTFile(comp, crt_file, prog_node) catch |err| {
                 // TODO Surface more error details.
                 comp.lockAndSetMiscFailure(.glibc_crt_file, "unable to build glibc CRT file: {s}", .{
                     @errorName(err),
@@ -3241,7 +3233,7 @@ fn processOneJob(comp: *Compilation, job: Job) !void {
             const named_frame = tracy.namedFrame("glibc_shared_objects");
             defer named_frame.end();
 
-            glibc.buildSharedObjects(comp) catch |err| {
+            glibc.buildSharedObjects(comp, prog_node) catch |err| {
                 // TODO Surface more error details.
                 comp.lockAndSetMiscFailure(
                     .glibc_shared_objects,
@@ -3254,7 +3246,7 @@ fn processOneJob(comp: *Compilation, job: Job) !void {
             const named_frame = tracy.namedFrame("musl_crt_file");
             defer named_frame.end();
 
-            musl.buildCRTFile(comp, crt_file) catch |err| {
+            musl.buildCRTFile(comp, crt_file, prog_node) catch |err| {
                 // TODO Surface more error details.
                 comp.lockAndSetMiscFailure(
                     .musl_crt_file,
@@ -3267,7 +3259,7 @@ fn processOneJob(comp: *Compilation, job: Job) !void {
             const named_frame = tracy.namedFrame("mingw_crt_file");
             defer named_frame.end();
 
-            mingw.buildCRTFile(comp, crt_file) catch |err| {
+            mingw.buildCRTFile(comp, crt_file, prog_node) catch |err| {
                 // TODO Surface more error details.
                 comp.lockAndSetMiscFailure(
                     .mingw_crt_file,
@@ -3294,7 +3286,7 @@ fn processOneJob(comp: *Compilation, job: Job) !void {
             const named_frame = tracy.namedFrame("libunwind");
             defer named_frame.end();
 
-            libunwind.buildStaticLib(comp) catch |err| {
+            libunwind.buildStaticLib(comp, prog_node) catch |err| {
                 // TODO Surface more error details.
                 comp.lockAndSetMiscFailure(
                     .libunwind,
@@ -3307,7 +3299,7 @@ fn processOneJob(comp: *Compilation, job: Job) !void {
             const named_frame = tracy.namedFrame("libcxx");
             defer named_frame.end();
 
-            libcxx.buildLibCXX(comp) catch |err| {
+            libcxx.buildLibCXX(comp, prog_node) catch |err| {
                 // TODO Surface more error details.
                 comp.lockAndSetMiscFailure(
                     .libcxx,
@@ -3320,7 +3312,7 @@ fn processOneJob(comp: *Compilation, job: Job) !void {
             const named_frame = tracy.namedFrame("libcxxabi");
             defer named_frame.end();
 
-            libcxx.buildLibCXXABI(comp) catch |err| {
+            libcxx.buildLibCXXABI(comp, prog_node) catch |err| {
                 // TODO Surface more error details.
                 comp.lockAndSetMiscFailure(
                     .libcxxabi,
@@ -3333,7 +3325,7 @@ fn processOneJob(comp: *Compilation, job: Job) !void {
             const named_frame = tracy.namedFrame("libtsan");
             defer named_frame.end();
 
-            libtsan.buildTsan(comp) catch |err| {
+            libtsan.buildTsan(comp, prog_node) catch |err| {
                 // TODO Surface more error details.
                 comp.lockAndSetMiscFailure(
                     .libtsan,
@@ -3346,7 +3338,7 @@ fn processOneJob(comp: *Compilation, job: Job) !void {
             const named_frame = tracy.namedFrame("wasi_libc_crt_file");
             defer named_frame.end();
 
-            wasi_libc.buildCRTFile(comp, crt_file) catch |err| {
+            wasi_libc.buildCRTFile(comp, crt_file, prog_node) catch |err| {
                 // TODO Surface more error details.
                 comp.lockAndSetMiscFailure(
                     .wasi_libc_crt_file,
@@ -3364,6 +3356,7 @@ fn processOneJob(comp: *Compilation, job: Job) !void {
                 .Lib,
                 &comp.libssp_static_lib,
                 .libssp,
+                prog_node,
             ) catch |err| switch (err) {
                 error.OutOfMemory => return error.OutOfMemory,
                 error.SubCompilationFailed => return, // error reported already
@@ -3383,6 +3376,7 @@ fn processOneJob(comp: *Compilation, job: Job) !void {
                 .Lib,
                 &comp.libc_static_lib,
                 .zig_libc,
+                prog_node,
             ) catch |err| switch (err) {
                 error.OutOfMemory => return error.OutOfMemory,
                 error.SubCompilationFailed => return, // error reported already
@@ -3723,8 +3717,15 @@ fn buildCompilerRtOneShot(
     comp: *Compilation,
     output_mode: std.builtin.OutputMode,
     out: *?CRTFile,
+    prog_node: *std.Progress.Node,
 ) void {
-    comp.buildOutputFromZig("compiler_rt.zig", output_mode, out, .compiler_rt) catch |err| switch (err) {
+    comp.buildOutputFromZig(
+        "compiler_rt.zig",
+        output_mode,
+        out,
+        .compiler_rt,
+        prog_node,
+    ) catch |err| switch (err) {
         error.SubCompilationFailed => return, // error reported already
         else => comp.lockAndSetMiscFailure(
             .compiler_rt,
@@ -5248,8 +5249,15 @@ pub fn updateSubCompilation(
     parent_comp: *Compilation,
     sub_comp: *Compilation,
     misc_task: MiscTask,
+    prog_node: *std.Progress.Node,
 ) !void {
-    try sub_comp.update();
+    {
+        var sub_node = prog_node.start(@tagName(misc_task), 0);
+        sub_node.activate();
+        defer sub_node.end();
+
+        try sub_comp.update(prog_node);
+    }
 
     // Look for compilation errors in this sub compilation
     const gpa = parent_comp.gpa;
@@ -5276,6 +5284,7 @@ fn buildOutputFromZig(
     output_mode: std.builtin.OutputMode,
     out: *?CRTFile,
     misc_task_tag: MiscTask,
+    prog_node: *std.Progress.Node,
 ) !void {
     const tracy_trace = trace(@src());
     defer tracy_trace.end();
@@ -5342,7 +5351,7 @@ fn buildOutputFromZig(
     });
     defer sub_compilation.destroy();
 
-    try comp.updateSubCompilation(sub_compilation, misc_task_tag);
+    try comp.updateSubCompilation(sub_compilation, misc_task_tag, prog_node);
 
     assert(out.* == null);
     out.* = Compilation.CRTFile{
@@ -5358,6 +5367,7 @@ pub fn build_crt_file(
     root_name: []const u8,
     output_mode: std.builtin.OutputMode,
     misc_task_tag: MiscTask,
+    prog_node: *std.Progress.Node,
     c_source_files: []const Compilation.CSourceFile,
 ) !void {
     const tracy_trace = trace(@src());
@@ -5418,7 +5428,7 @@ pub fn build_crt_file(
     });
     defer sub_compilation.destroy();
 
-    try comp.updateSubCompilation(sub_compilation, misc_task_tag);
+    try comp.updateSubCompilation(sub_compilation, misc_task_tag, prog_node);
 
     try comp.crt_files.ensureUnusedCapacity(comp.gpa, 1);
 
@@ -5470,10 +5480,3 @@ pub fn compilerRtStrip(comp: Compilation) bool {
         return true;
     }
 }
-
-pub fn hotCodeSwap(comp: *Compilation, pid: std.os.pid_t) !void {
-    comp.bin_file.child_pid = pid;
-    try comp.makeBinFileWritable();
-    try comp.update();
-    try comp.makeBinFileExecutable();
-}
src/glibc.zig
@@ -161,7 +161,7 @@ pub const CRTFile = enum {
     libc_nonshared_a,
 };
 
-pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile) !void {
+pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progress.Node) !void {
     if (!build_options.have_llvm) {
         return error.ZigCompilerNotBuiltWithLLVMExtensions;
     }
@@ -196,7 +196,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile) !void {
                 "-DASSEMBLER",
                 "-Wa,--noexecstack",
             });
-            return comp.build_crt_file("crti", .Obj, .@"glibc crti.o", &[1]Compilation.CSourceFile{
+            return comp.build_crt_file("crti", .Obj, .@"glibc crti.o", prog_node, &.{
                 .{
                     .src_path = try start_asm_path(comp, arena, "crti.S"),
                     .cache_exempt_flags = args.items,
@@ -215,7 +215,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile) !void {
                 "-DASSEMBLER",
                 "-Wa,--noexecstack",
             });
-            return comp.build_crt_file("crtn", .Obj, .@"glibc crtn.o", &[1]Compilation.CSourceFile{
+            return comp.build_crt_file("crtn", .Obj, .@"glibc crtn.o", prog_node, &.{
                 .{
                     .src_path = try start_asm_path(comp, arena, "crtn.S"),
                     .cache_exempt_flags = args.items,
@@ -265,7 +265,9 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile) !void {
                     .cache_exempt_flags = args.items,
                 };
             };
-            return comp.build_crt_file("Scrt1", .Obj, .@"glibc Scrt1.o", &[_]Compilation.CSourceFile{ start_o, abi_note_o });
+            return comp.build_crt_file("Scrt1", .Obj, .@"glibc Scrt1.o", prog_node, &.{
+                start_o, abi_note_o,
+            });
         },
         .libc_nonshared_a => {
             const s = path.sep_str;
@@ -366,7 +368,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile) !void {
                 files_index += 1;
             }
             const files = files_buf[0..files_index];
-            return comp.build_crt_file("c_nonshared", .Lib, .@"glibc libc_nonshared.a", files);
+            return comp.build_crt_file("c_nonshared", .Lib, .@"glibc libc_nonshared.a", prog_node, files);
         },
     }
 }
@@ -639,7 +641,7 @@ pub const BuiltSharedObjects = struct {
 
 const all_map_basename = "all.map";
 
-pub fn buildSharedObjects(comp: *Compilation) !void {
+pub fn buildSharedObjects(comp: *Compilation, prog_node: *std.Progress.Node) !void {
     const tracy = trace(@src());
     defer tracy.end();
 
@@ -1023,7 +1025,7 @@ pub fn buildSharedObjects(comp: *Compilation) !void {
         const asm_file_basename = std.fmt.bufPrint(&lib_name_buf, "{s}.s", .{lib.name}) catch unreachable;
         try o_directory.handle.writeFile(asm_file_basename, stubs_asm.items);
 
-        try buildSharedLib(comp, arena, comp.global_cache_directory, o_directory, asm_file_basename, lib);
+        try buildSharedLib(comp, arena, comp.global_cache_directory, o_directory, asm_file_basename, lib, prog_node);
     }
 
     man.writeManifest() catch |err| {
@@ -1046,6 +1048,7 @@ fn buildSharedLib(
     bin_directory: Compilation.Directory,
     asm_file_basename: []const u8,
     lib: Lib,
+    prog_node: *std.Progress.Node,
 ) !void {
     const tracy = trace(@src());
     defer tracy.end();
@@ -1105,7 +1108,7 @@ fn buildSharedLib(
     });
     defer sub_compilation.destroy();
 
-    try comp.updateSubCompilation(sub_compilation, .@"glibc shared object");
+    try comp.updateSubCompilation(sub_compilation, .@"glibc shared object", prog_node);
 }
 
 // Return true if glibc has crti/crtn sources for that architecture.
src/libcxx.zig
@@ -96,7 +96,7 @@ const libcxx_files = [_][]const u8{
     "src/verbose_abort.cpp",
 };
 
-pub fn buildLibCXX(comp: *Compilation) !void {
+pub fn buildLibCXX(comp: *Compilation, prog_node: *std.Progress.Node) !void {
     if (!build_options.have_llvm) {
         return error.ZigCompilerNotBuiltWithLLVMExtensions;
     }
@@ -258,7 +258,7 @@ pub fn buildLibCXX(comp: *Compilation) !void {
     });
     defer sub_compilation.destroy();
 
-    try comp.updateSubCompilation(sub_compilation, .libcxx);
+    try comp.updateSubCompilation(sub_compilation, .libcxx, prog_node);
 
     assert(comp.libcxx_static_lib == null);
     comp.libcxx_static_lib = Compilation.CRTFile{
@@ -269,7 +269,7 @@ pub fn buildLibCXX(comp: *Compilation) !void {
     };
 }
 
-pub fn buildLibCXXABI(comp: *Compilation) !void {
+pub fn buildLibCXXABI(comp: *Compilation, prog_node: *std.Progress.Node) !void {
     if (!build_options.have_llvm) {
         return error.ZigCompilerNotBuiltWithLLVMExtensions;
     }
@@ -418,7 +418,7 @@ pub fn buildLibCXXABI(comp: *Compilation) !void {
     });
     defer sub_compilation.destroy();
 
-    try comp.updateSubCompilation(sub_compilation, .libcxxabi);
+    try comp.updateSubCompilation(sub_compilation, .libcxxabi, prog_node);
 
     assert(comp.libcxxabi_static_lib == null);
     comp.libcxxabi_static_lib = Compilation.CRTFile{
src/libtsan.zig
@@ -5,7 +5,7 @@ const Compilation = @import("Compilation.zig");
 const build_options = @import("build_options");
 const trace = @import("tracy.zig").trace;
 
-pub fn buildTsan(comp: *Compilation) !void {
+pub fn buildTsan(comp: *Compilation, prog_node: *std.Progress.Node) !void {
     if (!build_options.have_llvm) {
         return error.ZigCompilerNotBuiltWithLLVMExtensions;
     }
@@ -235,7 +235,7 @@ pub fn buildTsan(comp: *Compilation) !void {
     });
     defer sub_compilation.destroy();
 
-    try comp.updateSubCompilation(sub_compilation, .libtsan);
+    try comp.updateSubCompilation(sub_compilation, .libtsan, prog_node);
 
     assert(comp.tsan_static_lib == null);
     comp.tsan_static_lib = Compilation.CRTFile{
src/libunwind.zig
@@ -7,7 +7,7 @@ const Compilation = @import("Compilation.zig");
 const build_options = @import("build_options");
 const trace = @import("tracy.zig").trace;
 
-pub fn buildStaticLib(comp: *Compilation) !void {
+pub fn buildStaticLib(comp: *Compilation, prog_node: *std.Progress.Node) !void {
     if (!build_options.have_llvm) {
         return error.ZigCompilerNotBuiltWithLLVMExtensions;
     }
@@ -130,7 +130,7 @@ pub fn buildStaticLib(comp: *Compilation) !void {
     });
     defer sub_compilation.destroy();
 
-    try comp.updateSubCompilation(sub_compilation, .libunwind);
+    try comp.updateSubCompilation(sub_compilation, .libunwind, prog_node);
 
     assert(comp.libunwind_static_lib == null);
 
src/main.zig
@@ -3543,6 +3543,23 @@ fn serve(
     var receive_fifo = std.fifo.LinearFifo(u8, .Dynamic).init(gpa);
     defer receive_fifo.deinit();
 
+    var progress: std.Progress = .{
+        .terminal = null,
+        .root = .{
+            .context = undefined,
+            .parent = null,
+            .name = "",
+            .unprotected_estimated_total_items = 0,
+            .unprotected_completed_items = 0,
+        },
+        .columns_written = 0,
+        .prev_refresh_timestamp = 0,
+        .timer = null,
+        .done = false,
+    };
+    const main_progress_node = &progress.root;
+    main_progress_node.context = &progress;
+
     while (true) {
         const hdr = try receiveMessage(in, &receive_fifo);
 
@@ -3551,11 +3568,12 @@ fn serve(
                 return cleanExit();
             },
             .update => {
+                assert(main_progress_node.recently_updated_child == null);
                 tracy.frameMark();
                 if (comp.bin_file.options.output_mode == .Exe) {
                     try comp.makeBinFileWritable();
                 }
-                try comp.update();
+                try comp.update(main_progress_node);
                 try comp.makeBinFileExecutable();
                 try serveUpdateResults(out, comp);
             },
@@ -3581,14 +3599,15 @@ fn serve(
             },
             .hot_update => {
                 tracy.frameMark();
+                assert(main_progress_node.recently_updated_child == null);
                 if (child_pid) |pid| {
-                    try comp.hotCodeSwap(pid);
+                    try comp.hotCodeSwap(main_progress_node, pid);
                     try serveUpdateResults(out, comp);
                 } else {
                     if (comp.bin_file.options.output_mode == .Exe) {
                         try comp.makeBinFileWritable();
                     }
-                    try comp.update();
+                    try comp.update(main_progress_node);
                     try comp.makeBinFileExecutable();
                     try serveUpdateResults(out, comp);
 
@@ -3936,7 +3955,24 @@ const AfterUpdateHook = union(enum) {
 };
 
 fn updateModule(gpa: Allocator, comp: *Compilation, hook: AfterUpdateHook) !void {
-    try comp.update();
+    {
+        // If the terminal is dumb, we dont want to show the user all the output.
+        var progress: std.Progress = .{ .dont_print_on_dumb = true };
+        const main_progress_node = progress.start("", 0);
+        defer main_progress_node.end();
+        switch (comp.color) {
+            .off => {
+                progress.terminal = null;
+            },
+            .on => {
+                progress.terminal = std.io.getStdErr();
+                progress.supports_ansi_escape_codes = true;
+            },
+            .auto => {},
+        }
+
+        try comp.update(main_progress_node);
+    }
 
     var errors = try comp.getAllErrorsAlloc();
     defer errors.deinit(comp.gpa);
@@ -4642,6 +4678,10 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi
         switch (term) {
             .Exited => |code| {
                 if (code == 0) return cleanExit();
+                // Indicates that the build runner has reported compile errors
+                // and this parent process does not need to report any further
+                // diagnostics.
+                if (code == 2) process.exit(2);
 
                 const cmd = try std.mem.join(arena, " ", child_argv);
                 fatal("the following build command failed with exit code {d}:\n{s}", .{ code, cmd });
src/mingw.zig
@@ -19,7 +19,7 @@ pub const CRTFile = enum {
     uuid_lib,
 };
 
-pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile) !void {
+pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progress.Node) !void {
     if (!build_options.have_llvm) {
         return error.ZigCompilerNotBuiltWithLLVMExtensions;
     }
@@ -41,7 +41,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile) !void {
                 //"-D_UNICODE",
                 //"-DWPRFLAG=1",
             });
-            return comp.build_crt_file("crt2", .Obj, .@"mingw-w64 crt2.o", &[1]Compilation.CSourceFile{
+            return comp.build_crt_file("crt2", .Obj, .@"mingw-w64 crt2.o", prog_node, &.{
                 .{
                     .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
                         "libc", "mingw", "crt", "crtexe.c",
@@ -60,7 +60,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile) !void {
                 "-U__CRTDLL__",
                 "-D__MSVCRT__",
             });
-            return comp.build_crt_file("dllcrt2", .Obj, .@"mingw-w64 dllcrt2.o", &[1]Compilation.CSourceFile{
+            return comp.build_crt_file("dllcrt2", .Obj, .@"mingw-w64 dllcrt2.o", prog_node, &.{
                 .{
                     .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
                         "libc", "mingw", "crt", "crtdll.c",
@@ -100,7 +100,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile) !void {
                     .extra_flags = args.items,
                 };
             }
-            return comp.build_crt_file("mingw32", .Lib, .@"mingw-w64 mingw32.lib", &c_source_files);
+            return comp.build_crt_file("mingw32", .Lib, .@"mingw-w64 mingw32.lib", prog_node, &c_source_files);
         },
 
         .msvcrt_os_lib => {
@@ -148,7 +148,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile) !void {
                     };
                 }
             }
-            return comp.build_crt_file("msvcrt-os", .Lib, .@"mingw-w64 msvcrt-os.lib", c_source_files.items);
+            return comp.build_crt_file("msvcrt-os", .Lib, .@"mingw-w64 msvcrt-os.lib", prog_node, c_source_files.items);
         },
 
         .mingwex_lib => {
@@ -211,7 +211,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile) !void {
             } else {
                 @panic("unsupported arch");
             }
-            return comp.build_crt_file("mingwex", .Lib, .@"mingw-w64 mingwex.lib", c_source_files.items);
+            return comp.build_crt_file("mingwex", .Lib, .@"mingw-w64 mingwex.lib", prog_node, c_source_files.items);
         },
 
         .uuid_lib => {
@@ -244,7 +244,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile) !void {
                     .extra_flags = extra_flags,
                 };
             }
-            return comp.build_crt_file("uuid", .Lib, .@"mingw-w64 uuid.lib", &c_source_files);
+            return comp.build_crt_file("uuid", .Lib, .@"mingw-w64 uuid.lib", prog_node, &c_source_files);
         },
     }
 }
src/musl.zig
@@ -17,7 +17,7 @@ pub const CRTFile = enum {
     libc_so,
 };
 
-pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile) !void {
+pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progress.Node) !void {
     if (!build_options.have_llvm) {
         return error.ZigCompilerNotBuiltWithLLVMExtensions;
     }
@@ -33,7 +33,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile) !void {
             try args.appendSlice(&[_][]const u8{
                 "-Qunused-arguments",
             });
-            return comp.build_crt_file("crti", .Obj, .@"musl crti.o", &[1]Compilation.CSourceFile{
+            return comp.build_crt_file("crti", .Obj, .@"musl crti.o", prog_node, &.{
                 .{
                     .src_path = try start_asm_path(comp, arena, "crti.s"),
                     .extra_flags = args.items,
@@ -46,7 +46,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile) !void {
             try args.appendSlice(&[_][]const u8{
                 "-Qunused-arguments",
             });
-            return comp.build_crt_file("crtn", .Obj, .@"musl crtn.o", &[1]Compilation.CSourceFile{
+            return comp.build_crt_file("crtn", .Obj, .@"musl crtn.o", prog_node, &.{
                 .{
                     .src_path = try start_asm_path(comp, arena, "crtn.s"),
                     .extra_flags = args.items,
@@ -60,7 +60,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile) !void {
                 "-fno-stack-protector",
                 "-DCRT",
             });
-            return comp.build_crt_file("crt1", .Obj, .@"musl crt1.o", &[1]Compilation.CSourceFile{
+            return comp.build_crt_file("crt1", .Obj, .@"musl crt1.o", prog_node, &.{
                 .{
                     .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
                         "libc", "musl", "crt", "crt1.c",
@@ -77,7 +77,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile) !void {
                 "-fno-stack-protector",
                 "-DCRT",
             });
-            return comp.build_crt_file("rcrt1", .Obj, .@"musl rcrt1.o", &[1]Compilation.CSourceFile{
+            return comp.build_crt_file("rcrt1", .Obj, .@"musl rcrt1.o", prog_node, &.{
                 .{
                     .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
                         "libc", "musl", "crt", "rcrt1.c",
@@ -94,7 +94,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile) !void {
                 "-fno-stack-protector",
                 "-DCRT",
             });
-            return comp.build_crt_file("Scrt1", .Obj, .@"musl Scrt1.o", &[1]Compilation.CSourceFile{
+            return comp.build_crt_file("Scrt1", .Obj, .@"musl Scrt1.o", prog_node, &.{
                 .{
                     .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
                         "libc", "musl", "crt", "Scrt1.c",
@@ -187,7 +187,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile) !void {
                     .extra_flags = args.items,
                 };
             }
-            return comp.build_crt_file("c", .Lib, .@"musl libc.a", c_source_files.items);
+            return comp.build_crt_file("c", .Lib, .@"musl libc.a", prog_node, c_source_files.items);
         },
         .libc_so => {
             const target = comp.getTarget();
@@ -241,7 +241,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile) !void {
             });
             defer sub_compilation.destroy();
 
-            try comp.updateSubCompilation(sub_compilation, .@"musl libc.so");
+            try comp.updateSubCompilation(sub_compilation, .@"musl libc.so", prog_node);
 
             try comp.crt_files.ensureUnusedCapacity(comp.gpa, 1);
 
src/wasi_libc.zig
@@ -59,7 +59,7 @@ pub fn execModelCrtFileFullName(wasi_exec_model: std.builtin.WasiExecModel) []co
     };
 }
 
-pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile) !void {
+pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progress.Node) !void {
     if (!build_options.have_llvm) {
         return error.ZigCompilerNotBuiltWithLLVMExtensions;
     }
@@ -74,7 +74,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile) !void {
             var args = std.ArrayList([]const u8).init(arena);
             try addCCArgs(comp, arena, &args, false);
             try addLibcBottomHalfIncludes(comp, arena, &args);
-            return comp.build_crt_file("crt1-reactor", .Obj, .@"wasi crt1-reactor.o", &[1]Compilation.CSourceFile{
+            return comp.build_crt_file("crt1-reactor", .Obj, .@"wasi crt1-reactor.o", prog_node, &.{
                 .{
                     .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
                         "libc", try sanitize(arena, crt1_reactor_src_file),
@@ -87,7 +87,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile) !void {
             var args = std.ArrayList([]const u8).init(arena);
             try addCCArgs(comp, arena, &args, false);
             try addLibcBottomHalfIncludes(comp, arena, &args);
-            return comp.build_crt_file("crt1-command", .Obj, .@"wasi crt1-command.o", &[1]Compilation.CSourceFile{
+            return comp.build_crt_file("crt1-command", .Obj, .@"wasi crt1-command.o", prog_node, &.{
                 .{
                     .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
                         "libc", try sanitize(arena, crt1_command_src_file),
@@ -145,7 +145,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile) !void {
                 }
             }
 
-            try comp.build_crt_file("c", .Lib, .@"wasi libc.a", libc_sources.items);
+            try comp.build_crt_file("c", .Lib, .@"wasi libc.a", prog_node, libc_sources.items);
         },
         .libwasi_emulated_process_clocks_a => {
             var args = std.ArrayList([]const u8).init(arena);
@@ -161,7 +161,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile) !void {
                     .extra_flags = args.items,
                 });
             }
-            try comp.build_crt_file("wasi-emulated-process-clocks", .Lib, .@"libwasi-emulated-process-clocks.a", emu_clocks_sources.items);
+            try comp.build_crt_file("wasi-emulated-process-clocks", .Lib, .@"libwasi-emulated-process-clocks.a", prog_node, emu_clocks_sources.items);
         },
         .libwasi_emulated_getpid_a => {
             var args = std.ArrayList([]const u8).init(arena);
@@ -177,7 +177,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile) !void {
                     .extra_flags = args.items,
                 });
             }
-            try comp.build_crt_file("wasi-emulated-getpid", .Lib, .@"libwasi-emulated-getpid.a", emu_getpid_sources.items);
+            try comp.build_crt_file("wasi-emulated-getpid", .Lib, .@"libwasi-emulated-getpid.a", prog_node, emu_getpid_sources.items);
         },
         .libwasi_emulated_mman_a => {
             var args = std.ArrayList([]const u8).init(arena);
@@ -193,7 +193,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile) !void {
                     .extra_flags = args.items,
                 });
             }
-            try comp.build_crt_file("wasi-emulated-mman", .Lib, .@"libwasi-emulated-mman.a", emu_mman_sources.items);
+            try comp.build_crt_file("wasi-emulated-mman", .Lib, .@"libwasi-emulated-mman.a", prog_node, emu_mman_sources.items);
         },
         .libwasi_emulated_signal_a => {
             var emu_signal_sources = std.ArrayList(Compilation.CSourceFile).init(arena);
@@ -228,7 +228,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile) !void {
                 }
             }
 
-            try comp.build_crt_file("wasi-emulated-signal", .Lib, .@"libwasi-emulated-signal.a", emu_signal_sources.items);
+            try comp.build_crt_file("wasi-emulated-signal", .Lib, .@"libwasi-emulated-signal.a", prog_node, emu_signal_sources.items);
         },
     }
 }