diff --git a/src-self-hosted/Compilation.zig b/src-self-hosted/Compilation.zig index 9a46b88619..d8c0bec199 100644 --- a/src-self-hosted/Compilation.zig +++ b/src-self-hosted/Compilation.zig @@ -156,6 +156,15 @@ pub const AllErrors = struct { column: usize, byte_offset: usize, msg: []const u8, + + pub fn renderToStdErr(self: Message) void { + std.debug.print("{}:{}:{}: error: {}\n", .{ + self.src_path, + self.line + 1, + self.column + 1, + self.msg, + }); + } }; pub fn deinit(self: *AllErrors, gpa: *Allocator) void { @@ -693,6 +702,12 @@ pub fn update(self: *Compilation) !void { } } + if (self.totalErrorCount() != 0) { + // Skip flushing. + self.link_error_flags = .{}; + return; + } + // This is needed before reading the error flags. try self.bin_file.flush(self); @@ -957,12 +972,14 @@ fn updateCObject(comp: *Compilation, c_object: *CObject) !void { mem.split(c_source_basename, ".").next().?; const o_basename = try std.fmt.allocPrint(arena, "{}{}", .{ o_basename_noext, comp.getTarget().oFileExt() }); - const full_object_path = if (!(try ch.hit()) or comp.disable_c_depfile) blk: { + const digest = if ((try ch.hit()) and !comp.disable_c_depfile) ch.final() else blk: { var argv = std.ArrayList([]const u8).init(comp.gpa); defer argv.deinit(); // We can't know the digest until we do the C compiler invocation, so we need a temporary filename. const out_obj_path = try comp.tmpFilePath(arena, o_basename); + var zig_cache_tmp_dir = try comp.zig_cache_directory.handle.makeOpenPath("tmp", .{}); + defer zig_cache_tmp_dir.close(); try argv.appendSlice(&[_][]const u8{ self_exe_path, "clang", "-c" }); @@ -1042,25 +1059,23 @@ fn updateCObject(comp: *Compilation, c_object: *CObject) !void { // Rename into place. const digest = ch.final(); - const full_object_path = if (comp.zig_cache_directory.path) |p| - try std.fs.path.join(arena, &[_][]const u8{ p, "o", &digest, o_basename }) - else - try std.fs.path.join(arena, &[_][]const u8{ "o", &digest, o_basename }); - try std.fs.rename(out_obj_path, full_object_path); + const o_sub_path = try std.fs.path.join(arena, &[_][]const u8{ "o", &digest }); + var o_dir = try comp.zig_cache_directory.handle.makeOpenPath(o_sub_path, .{}); + defer o_dir.close(); + // TODO Add renameat capabilities to the std lib in a higher layer than the posix layer. + const tmp_basename = std.fs.path.basename(out_obj_path); + try std.os.renameat(zig_cache_tmp_dir.fd, tmp_basename, o_dir.fd, o_basename); ch.writeManifest() catch |err| { std.log.warn("failed to write cache manifest when compiling '{}': {}", .{ c_object.src_path, @errorName(err) }); }; - break :blk full_object_path; - } else blk: { - const digest = ch.final(); - const full_object_path = if (comp.zig_cache_directory.path) |p| - try std.fs.path.join(arena, &[_][]const u8{ p, "o", &digest, o_basename }) - else - try std.fs.path.join(arena, &[_][]const u8{ "o", &digest, o_basename }); - break :blk full_object_path; + break :blk digest; }; + const full_object_path = if (comp.zig_cache_directory.path) |p| + try std.fs.path.join(comp.gpa, &[_][]const u8{ p, "o", &digest, o_basename }) + else + try std.fs.path.join(comp.gpa, &[_][]const u8{ "o", &digest, o_basename }); c_object.status = .{ .success = .{ .object_path = full_object_path, diff --git a/src-self-hosted/glibc.zig b/src-self-hosted/glibc.zig index 3577442121..23759ea6ad 100644 --- a/src-self-hosted/glibc.zig +++ b/src-self-hosted/glibc.zig @@ -619,11 +619,28 @@ fn build_libc_object(comp: *Compilation, basename: []const u8, c_source_file: Co .c_source_files = &[1]Compilation.CSourceFile{c_source_file}, .debug_cc = comp.debug_cc, .debug_link = comp.bin_file.options.debug_link, + .clang_passthrough_mode = comp.clang_passthrough_mode, }); defer sub_compilation.destroy(); try sub_compilation.update(); + // Look for compilation errors in this sub_compilation + var errors = try sub_compilation.getAllErrorsAlloc(); + defer errors.deinit(sub_compilation.gpa); + + if (errors.list.len != 0) { + for (errors.list) |full_err_msg| { + std.log.err("{}:{}:{}: error: {}\n", .{ + full_err_msg.src_path, + full_err_msg.line + 1, + full_err_msg.column + 1, + full_err_msg.msg, + }); + } + return error.BuildingLibCObjectFailed; + } + try comp.crt_files.ensureCapacity(comp.gpa, comp.crt_files.count() + 1); const artifact_path = if (sub_compilation.bin_file.options.directory.path) |p| try std.fs.path.join(comp.gpa, &[_][]const u8{ p, basename }) diff --git a/src-self-hosted/link/Elf.zig b/src-self-hosted/link/Elf.zig index 2131f44f3d..37ae1b6d69 100644 --- a/src-self-hosted/link/Elf.zig +++ b/src-self-hosted/link/Elf.zig @@ -1265,11 +1265,9 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { try ch.addOptionalFile(self.base.options.linker_script); try ch.addOptionalFile(self.base.options.version_script); try ch.addListOfFiles(self.base.options.objects); - for (comp.c_object_table.items()) |entry| switch (entry.key.status) { - .new => unreachable, - .failure => return error.NotAllCSourceFilesAvailableToLink, - .success => |success| _ = try ch.addFile(success.object_path, null), - }; + for (comp.c_object_table.items()) |entry| { + _ = try ch.addFile(entry.key.status.success.object_path, null); + } try ch.addOptionalFile(module_obj_path); // We can skip hashing libc and libc++ components that we are in charge of building from Zig // installation sources because they are always a product of the compiler version + target information. @@ -1494,11 +1492,9 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { // Positional arguments to the linker such as object files. try argv.appendSlice(self.base.options.objects); - for (comp.c_object_table.items()) |entry| switch (entry.key.status) { - .new => unreachable, - .failure => unreachable, // Checked during cache hashing. - .success => |success| try argv.append(success.object_path), - }; + for (comp.c_object_table.items()) |entry| { + try argv.append(entry.key.status.success.object_path); + } if (module_obj_path) |p| { try argv.append(p); diff --git a/src-self-hosted/main.zig b/src-self-hosted/main.zig index b7ec9ee712..918e92422a 100644 --- a/src-self-hosted/main.zig +++ b/src-self-hosted/main.zig @@ -228,12 +228,8 @@ const usage_build_generic = \\ \\Debug Options (Zig Compiler Development): \\ -ftime-report Print timing diagnostics - \\ --debug-tokenize verbose tokenization - \\ --debug-ast-tree verbose parsing into an AST (tree view) - \\ --debug-ast-fmt verbose parsing into an AST (render source) - \\ --debug-ir verbose Zig IR - \\ --debug-link verbose linking - \\ --debug-codegen verbose machine code generation + \\ --debug-link Verbose linker invocation + \\ --debug-cc Verbose C compiler invocation \\ ; @@ -272,12 +268,7 @@ pub fn buildOutputType( var strip = false; var single_threaded = false; var watch = false; - var debug_tokenize = false; - var debug_ast_tree = false; - var debug_ast_fmt = false; var debug_link = false; - var debug_ir = false; - var debug_codegen = false; var debug_cc = false; var time_report = false; var emit_bin: Emit = .yes_default_path; @@ -531,18 +522,8 @@ pub fn buildOutputType( link_eh_frame_hdr = true; } else if (mem.eql(u8, arg, "-Bsymbolic")) { linker_bind_global_refs_locally = true; - } else if (mem.eql(u8, arg, "--debug-tokenize")) { - debug_tokenize = true; - } else if (mem.eql(u8, arg, "--debug-ast-tree")) { - debug_ast_tree = true; - } else if (mem.eql(u8, arg, "--debug-ast-fmt")) { - debug_ast_fmt = true; } else if (mem.eql(u8, arg, "--debug-link")) { debug_link = true; - } else if (mem.eql(u8, arg, "--debug-ir")) { - debug_ir = true; - } else if (mem.eql(u8, arg, "--debug-codegen")) { - debug_codegen = true; } else if (mem.eql(u8, arg, "--debug-cc")) { debug_cc = true; } else if (mem.startsWith(u8, arg, "-T")) { @@ -1222,12 +1203,7 @@ fn updateModule(gpa: *Allocator, comp: *Compilation, zir_out_path: ?[]const u8) if (errors.list.len != 0) { for (errors.list) |full_err_msg| { - std.debug.print("{}:{}:{}: error: {}\n", .{ - full_err_msg.src_path, - full_err_msg.line + 1, - full_err_msg.column + 1, - full_err_msg.msg, - }); + full_err_msg.renderToStdErr(); } }