authorgravatar for kcbanner@gmail.comCasey Banner <kcbanner@gmail.com> 2025-10-08 03:49:13-04:00
committergravatar for kcbanner@gmail.comCasey Banner <kcbanner@gmail.com> 2025-10-09 01:06:09-04:00
log8b6cdc3d8224cf1e97a970f78281db2fcd14b7a2
tree2b7c53bbec33d5c1d9edde483a51fc196ed602e6
parent447280d0d98b540aed4df83db7cf95a417d81611

- Rework common translate-c and cImport logic into `Compilation.translateC`

- Add std.zig.Server.allocErrorBundle, replace duplicates

7 files changed, 206 insertions(+), 258 deletions(-)

lib/compiler/std-docs.zig+1-14
......@@ -345,20 +345,7 @@ fn buildWasmBinary(
345345 }
346346 },
347347 .error_bundle => {
348 const EbHdr = std.zig.Server.Message.ErrorBundle;
349 const eb_hdr = @as(*align(1) const EbHdr, @ptrCast(body));
350 const extra_bytes =
351 body[@sizeOf(EbHdr)..][0 .. @sizeOf(u32) * eb_hdr.extra_len];
352 const string_bytes =
353 body[@sizeOf(EbHdr) + extra_bytes.len ..][0..eb_hdr.string_bytes_len];
354 // TODO: use @ptrCast when the compiler supports it
355 const unaligned_extra = std.mem.bytesAsSlice(u32, extra_bytes);
356 const extra_array = try arena.alloc(u32, unaligned_extra.len);
357 @memcpy(extra_array, unaligned_extra);
358 result_error_bundle = .{
359 .string_bytes = try arena.dupe(u8, string_bytes),
360 .extra = extra_array,
361 };
348 result_error_bundle = try std.zig.Server.allocErrorBundle(arena, body);
362349 },
363350 .emit_digest => {
364351 const EmitDigest = std.zig.Server.Message.EmitDigest;
lib/std/Build/Step.zig+1-16
......@@ -524,22 +524,7 @@ fn zigProcessUpdate(s: *Step, zp: *ZigProcess, watch: bool, web_server: ?*Build.
524524 }
525525 },
526526 .error_bundle => {
527 const EbHdr = std.zig.Server.Message.ErrorBundle;
528 const eb_hdr = @as(*align(1) const EbHdr, @ptrCast(body));
529 const extra_bytes =
530 body[@sizeOf(EbHdr)..][0 .. @sizeOf(u32) * eb_hdr.extra_len];
531 const string_bytes =
532 body[@sizeOf(EbHdr) + extra_bytes.len ..][0..eb_hdr.string_bytes_len];
533 // TODO: use @ptrCast when the compiler supports it
534 const unaligned_extra = std.mem.bytesAsSlice(u32, extra_bytes);
535 {
536 s.result_error_bundle = .{ .string_bytes = &.{}, .extra = &.{} };
537 errdefer s.result_error_bundle.deinit(gpa);
538 s.result_error_bundle.string_bytes = try gpa.dupe(u8, string_bytes);
539 const extra = try gpa.alloc(u32, unaligned_extra.len);
540 @memcpy(extra, unaligned_extra);
541 s.result_error_bundle.extra = extra;
542 }
527 s.result_error_bundle = try std.zig.Server.allocErrorBundle(gpa, body);
543528 // This message indicates the end of the update.
544529 if (watch) break :poll;
545530 },
lib/std/Build/WebServer.zig+1-13
......@@ -595,19 +595,7 @@ fn buildClientWasm(ws: *WebServer, arena: Allocator, optimize: std.builtin.Optim
595595 }
596596 },
597597 .error_bundle => {
598 const EbHdr = std.zig.Server.Message.ErrorBundle;
599 const eb_hdr = @as(*align(1) const EbHdr, @ptrCast(body));
600 const extra_bytes =
601 body[@sizeOf(EbHdr)..][0 .. @sizeOf(u32) * eb_hdr.extra_len];
602 const string_bytes =
603 body[@sizeOf(EbHdr) + extra_bytes.len ..][0..eb_hdr.string_bytes_len];
604 const unaligned_extra: []align(1) const u32 = @ptrCast(extra_bytes);
605 const extra_array = try arena.alloc(u32, unaligned_extra.len);
606 @memcpy(extra_array, unaligned_extra);
607 result_error_bundle = .{
608 .string_bytes = try arena.dupe(u8, string_bytes),
609 .extra = extra_array,
610 };
598 result_error_bundle = try std.zig.Server.allocErrorBundle(arena, body);
611599 },
612600 .emit_digest => {
613601 const EmitDigest = std.zig.Server.Message.EmitDigest;
lib/std/zig/Server.zig+22
......@@ -231,6 +231,28 @@ pub fn serveErrorBundle(s: *Server, error_bundle: std.zig.ErrorBundle) !void {
231231 try s.out.flush();
232232}
233233
234pub fn allocErrorBundle(allocator: std.mem.Allocator, body: []const u8) !std.zig.ErrorBundle {
235 const eb_hdr = @as(*align(1) const OutMessage.ErrorBundle, @ptrCast(body));
236 const extra_bytes =
237 body[@sizeOf(OutMessage.ErrorBundle)..][0 .. @sizeOf(u32) * eb_hdr.extra_len];
238 const string_bytes =
239 body[@sizeOf(OutMessage.ErrorBundle) + extra_bytes.len ..][0..eb_hdr.string_bytes_len];
240 const unaligned_extra: []align(1) const u32 = @ptrCast(extra_bytes);
241
242 var error_bundle: std.zig.ErrorBundle = .{
243 .string_bytes = &.{},
244 .extra = &.{},
245 };
246 errdefer error_bundle.deinit(allocator);
247
248 error_bundle.string_bytes = try allocator.dupe(u8, string_bytes);
249 const extra = try allocator.alloc(u32, unaligned_extra.len);
250 @memcpy(extra, unaligned_extra);
251 error_bundle.extra = extra;
252
253 return error_bundle;
254}
255
234256pub const TestMetadata = struct {
235257 names: []const u32,
236258 expected_panic_msgs: []const u32,
src/Compilation.zig+151-103
......@@ -5640,6 +5640,7 @@ pub fn obtainWin32ResourceCacheManifest(comp: *const Compilation) Cache.Manifest
56405640}
56415641
56425642pub const CImportResult = struct {
5643 // Only valid if `errors` is not empty
56435644 digest: [Cache.bin_digest_len]u8,
56445645 cache_hit: bool,
56455646 errors: std.zig.ErrorBundle,
......@@ -5649,76 +5650,182 @@ pub const CImportResult = struct {
56495650 }
56505651};
56515652
5652/// Caller owns returned memory.
5653pub fn cImport(
5653pub fn translateC(
56545654 comp: *Compilation,
5655 c_src: []const u8,
5655 arena: Allocator,
5656 man: *Cache.Manifest,
5657 ext: FileExt,
5658 source: union(enum) {
5659 path: []const u8,
5660 c_src: []const u8,
5661 },
5662 translated_basename: []const u8,
56565663 owner_mod: *Package.Module,
56575664 prog_node: std.Progress.Node,
56585665) !CImportResult {
56595666 dev.check(.translate_c_command);
56605667
5661 const cimport_basename = "cimport.h";
5662 const translated_basename = "cimport.zig";
5668 const tmp_basename = std.fmt.hex(std.crypto.random.int(u64));
5669 const tmp_sub_path = "tmp" ++ fs.path.sep_str ++ tmp_basename;
5670 const cache_dir = comp.dirs.local_cache.handle;
5671 var cache_tmp_dir = try cache_dir.makeOpenPath(tmp_sub_path, .{});
5672 defer cache_tmp_dir.close();
5673
5674 const translated_path = try comp.dirs.local_cache.join(arena, &.{ tmp_sub_path, translated_basename });
5675 const source_path = switch (source) {
5676 .c_src => |c_src| path: {
5677 const cimport_basename = "cimport.h";
5678 const out_h_sub_path = tmp_sub_path ++ fs.path.sep_str ++ cimport_basename;
5679 const out_h_path = try comp.dirs.local_cache.join(arena, &.{out_h_sub_path});
5680 if (comp.verbose_cimport) log.info("writing C import source to {s}", .{out_h_path});
5681 try cache_dir.writeFile(.{ .sub_path = out_h_sub_path, .data = c_src });
5682 break :path out_h_path;
5683 },
5684 .path => |p| p,
5685 };
56635686
5664 var man = comp.obtainCObjectCacheManifest(owner_mod);
5665 defer man.deinit();
5687 const out_dep_path: ?[]const u8 = blk: {
5688 if (comp.disable_c_depfile) break :blk null;
5689 const c_src_basename = fs.path.basename(source_path);
5690 const dep_basename = try std.fmt.allocPrint(arena, "{s}.d", .{c_src_basename});
5691 const out_dep_path = try comp.dirs.local_cache.join(arena, &.{ tmp_sub_path, dep_basename });
5692 break :blk out_dep_path;
5693 };
56665694
5667 man.hash.add(@as(u16, 0x7dd9)); // Random number to distinguish translate-c from compiling C objects
5668 man.hash.addBytes(c_src);
5695 var argv = std.array_list.Managed([]const u8).init(arena);
5696 {
5697 const target = &owner_mod.resolved_target.result;
5698 try argv.appendSlice(&.{ "--zig-integration", "-x", "c" });
56695699
5670 const digest, const is_hit = if (try man.hit()) .{ man.finalBin(), true } else digest: {
5671 var arena_allocator = std.heap.ArenaAllocator.init(comp.gpa);
5672 defer arena_allocator.deinit();
5673 const arena = arena_allocator.allocator();
5700 const resource_path = try comp.dirs.zig_lib.join(arena, &.{ "compiler", "aro", "include" });
5701 try argv.appendSlice(&.{ "-isystem", resource_path });
5702 try comp.addCommonCCArgs(arena, &argv, ext, out_dep_path, owner_mod, .aro);
5703 try argv.appendSlice(&[_][]const u8{ "-target", try target.zigTriple(arena) });
56745704
5675 const tmp_basename = std.fmt.hex(std.crypto.random.int(u64));
5676 const tmp_sub_path = "tmp" ++ fs.path.sep_str ++ tmp_basename;
5677 const cache_dir = comp.dirs.local_cache.handle;
5678 const out_h_sub_path = tmp_sub_path ++ fs.path.sep_str ++ cimport_basename;
5705 const mcpu = mcpu: {
5706 var buf: std.ArrayListUnmanaged(u8) = .empty;
5707 defer buf.deinit(comp.gpa);
5708
5709 try buf.print(comp.gpa, "-mcpu={s}", .{target.cpu.model.name});
5710
5711 // TODO better serialization https://github.com/ziglang/zig/issues/4584
5712 const all_features_list = target.cpu.arch.allFeaturesList();
5713 try argv.ensureUnusedCapacity(all_features_list.len * 4);
5714 for (all_features_list, 0..) |feature, index_usize| {
5715 const index = @as(std.Target.Cpu.Feature.Set.Index, @intCast(index_usize));
5716 const is_enabled = target.cpu.features.isEnabled(index);
56795717
5680 try cache_dir.makePath(tmp_sub_path);
5718 const plus_or_minus = "-+"[@intFromBool(is_enabled)];
5719 try buf.print(comp.gpa, "{c}{s}", .{ plus_or_minus, feature.name });
5720 }
5721 break :mcpu try buf.toOwnedSlice(arena);
5722 };
5723 try argv.append(mcpu);
56815724
5682 const out_h_path = try comp.dirs.local_cache.join(arena, &.{out_h_sub_path});
5683 const translated_path = try comp.dirs.local_cache.join(arena, &.{ tmp_sub_path, translated_basename });
5684 const out_dep_path = try std.fmt.allocPrint(arena, "{s}.d", .{out_h_path});
5725 try argv.appendSlice(comp.global_cc_argv);
5726 try argv.appendSlice(owner_mod.cc_argv);
5727 try argv.appendSlice(&.{ source_path, "-o", translated_path });
5728 if (comp.verbose_cimport) dump_argv(argv.items);
5729 }
56855730
5686 if (comp.verbose_cimport) log.info("writing C import source to {s}", .{out_h_path});
5687 try cache_dir.writeFile(.{ .sub_path = out_h_sub_path, .data = c_src });
5731 var stdout: []u8 = undefined;
5732 try @import("main.zig").translateC(comp.gpa, arena, argv.items, prog_node, &stdout);
56885733
5689 var argv = std.array_list.Managed([]const u8).init(comp.gpa);
5690 defer argv.deinit();
5691 try comp.addTranslateCCArgs(arena, &argv, .c, out_dep_path, owner_mod);
5692 try argv.appendSlice(&.{ out_h_path, "-o", translated_path });
5734 if (out_dep_path) |dep_file_path| add_deps: {
5735 if (comp.verbose_cimport) log.info("processing dep file at {s}", .{dep_file_path});
56935736
5694 if (comp.verbose_cc) dump_argv(argv.items);
5695 var stdout: []u8 = undefined;
5696 try @import("main.zig").translateC(comp.gpa, arena, argv.items, prog_node, &stdout);
5697 if (comp.verbose_cimport and stdout.len != 0) log.info("unexpected stdout: {s}", .{stdout});
5737 const dep_basename = fs.path.basename(dep_file_path);
5738 // Add the files depended on to the cache system, if a dep file was emitted
5739 man.addDepFilePost(cache_tmp_dir, dep_basename) catch |err| switch (err) {
5740 error.FileNotFound => break :add_deps,
5741 else => |e| return e,
5742 };
56985743
5699 const dep_sub_path = out_h_sub_path ++ ".d";
5700 if (comp.verbose_cimport) log.info("processing dep file at {s}", .{dep_sub_path});
5701 try man.addDepFilePost(cache_dir, dep_sub_path);
57025744 switch (comp.cache_use) {
57035745 .whole => |whole| if (whole.cache_manifest) |whole_cache_manifest| {
57045746 whole.cache_manifest_mutex.lock();
57055747 defer whole.cache_manifest_mutex.unlock();
5706 try whole_cache_manifest.addDepFilePost(cache_dir, dep_sub_path);
5748 try whole_cache_manifest.addDepFilePost(cache_tmp_dir, dep_basename);
57075749 },
57085750 .incremental, .none => {},
57095751 }
57105752
5711 const bin_digest = man.finalBin();
5712 const hex_digest = Cache.binToHex(bin_digest);
5713 const o_sub_path = "o" ++ fs.path.sep_str ++ hex_digest;
5753 // Just to save disk space, we delete the file because it is never needed again.
5754 cache_tmp_dir.deleteFile(dep_basename) catch |err| {
5755 log.warn("failed to delete '{s}': {t}", .{ dep_file_path, err });
5756 };
5757 }
5758
5759 if (stdout.len > 0) {
5760 var reader: std.Io.Reader = .fixed(stdout);
5761 const MessageHeader = std.zig.Server.Message.Header;
5762 const header = reader.takeStruct(MessageHeader, .little) catch unreachable;
5763 const body = reader.take(header.bytes_len) catch unreachable;
5764 switch (header.tag) {
5765 .error_bundle => {
5766 const error_bundle = try std.zig.Server.allocErrorBundle(comp.gpa, body);
5767 return .{
5768 .digest = undefined,
5769 .cache_hit = false,
5770 .errors = error_bundle,
5771 };
5772 },
5773 else => unreachable, // No other messagse are sent
5774 }
5775 }
5776
5777 const bin_digest = man.finalBin();
5778 const hex_digest = Cache.binToHex(bin_digest);
5779 const o_sub_path = "o" ++ fs.path.sep_str ++ hex_digest;
57145780
5715 if (comp.verbose_cimport) log.info("renaming {s} to {s}", .{ tmp_sub_path, o_sub_path });
5716 try renameTmpIntoCache(comp.dirs.local_cache, tmp_sub_path, o_sub_path);
5781 if (comp.verbose_cimport) log.info("renaming {s} to {s}", .{ tmp_sub_path, o_sub_path });
5782 try renameTmpIntoCache(comp.dirs.local_cache, tmp_sub_path, o_sub_path);
57175783
5718 break :digest .{ bin_digest, false };
5784 return .{
5785 .digest = bin_digest,
5786 .cache_hit = false,
5787 .errors = ErrorBundle.empty,
57195788 };
5789}
57205790
5721 if (man.have_exclusive_lock) {
5791/// Caller owns returned memory.
5792pub fn cImport(
5793 comp: *Compilation,
5794 c_src: []const u8,
5795 owner_mod: *Package.Module,
5796 prog_node: std.Progress.Node,
5797) !CImportResult {
5798 dev.check(.translate_c_command);
5799
5800 const translated_basename = "cimport.zig";
5801
5802 var man = comp.obtainCObjectCacheManifest(owner_mod);
5803 defer man.deinit();
5804
5805 man.hash.add(@as(u16, 0x7dd9)); // Random number to distinguish c-import from compiling C objects
5806 man.hash.addBytes(c_src);
5807
5808 const result: CImportResult = if (try man.hit()) .{
5809 .digest = man.finalBin(),
5810 .cache_hit = true,
5811 .errors = ErrorBundle.empty,
5812 } else result: {
5813 var arena_allocator = std.heap.ArenaAllocator.init(comp.gpa);
5814 defer arena_allocator.deinit();
5815 const arena = arena_allocator.allocator();
5816
5817 break :result try comp.translateC(
5818 arena,
5819 &man,
5820 .c,
5821 .{ .c_src = c_src },
5822 translated_basename,
5823 owner_mod,
5824 prog_node,
5825 );
5826 };
5827
5828 if (result.errors.errorMessageCount() == 0 and man.have_exclusive_lock) {
57225829 // Write the updated manifest. This is a no-op if the manifest is not dirty. Note that it is
57235830 // possible we had a hit and the manifest is dirty, for example if the file mtime changed but
57245831 // the contents were the same, we hit the cache but the manifest is dirty and we need to update
......@@ -5728,11 +5835,7 @@ pub fn cImport(
57285835 };
57295836 }
57305837
5731 return .{
5732 .digest = digest,
5733 .cache_hit = is_hit,
5734 .errors = std.zig.ErrorBundle.empty,
5735 };
5838 return result;
57365839}
57375840
57385841fn workerUpdateCObject(
......@@ -6622,19 +6725,7 @@ fn spawnZigRc(
66226725 // We expect exactly one ErrorBundle, and if any error_bundle header is
66236726 // sent then it's a fatal error.
66246727 .error_bundle => {
6625 const EbHdr = std.zig.Server.Message.ErrorBundle;
6626 const eb_hdr = @as(*align(1) const EbHdr, @ptrCast(body));
6627 const extra_bytes =
6628 body[@sizeOf(EbHdr)..][0 .. @sizeOf(u32) * eb_hdr.extra_len];
6629 const string_bytes =
6630 body[@sizeOf(EbHdr) + extra_bytes.len ..][0..eb_hdr.string_bytes_len];
6631 const unaligned_extra = std.mem.bytesAsSlice(u32, extra_bytes);
6632 const extra_array = try comp.gpa.alloc(u32, unaligned_extra.len);
6633 @memcpy(extra_array, unaligned_extra);
6634 const error_bundle = std.zig.ErrorBundle{
6635 .string_bytes = try comp.gpa.dupe(u8, string_bytes),
6636 .extra = extra_array,
6637 };
6728 const error_bundle = try std.zig.Server.allocErrorBundle(comp.gpa, body);
66386729 return comp.failWin32ResourceWithOwnedBundle(win32_resource, error_bundle);
66396730 },
66406731 else => {}, // ignore other messages
......@@ -6672,49 +6763,6 @@ pub fn tmpFilePath(comp: Compilation, ally: Allocator, suffix: []const u8) error
66726763 }
66736764}
66746765
6675pub fn addTranslateCCArgs(
6676 comp: *Compilation,
6677 arena: Allocator,
6678 argv: *std.array_list.Managed([]const u8),
6679 ext: FileExt,
6680 out_dep_path: ?[]const u8,
6681 owner_mod: *Package.Module,
6682) !void {
6683 const target = &owner_mod.resolved_target.result;
6684
6685 try argv.appendSlice(&.{ "-x", "c" });
6686
6687 const resource_path = try comp.dirs.zig_lib.join(arena, &.{ "compiler", "aro", "include" });
6688 try argv.appendSlice(&.{ "-isystem", resource_path });
6689
6690 try comp.addCommonCCArgs(arena, argv, ext, out_dep_path, owner_mod, .aro);
6691
6692 try argv.appendSlice(&[_][]const u8{ "-target", try target.zigTriple(arena) });
6693
6694 const mcpu = mcpu: {
6695 var buf: std.ArrayListUnmanaged(u8) = .empty;
6696 defer buf.deinit(comp.gpa);
6697
6698 try buf.print(comp.gpa, "-mcpu={s}", .{target.cpu.model.name});
6699
6700 // TODO better serialization https://github.com/ziglang/zig/issues/4584
6701 const all_features_list = target.cpu.arch.allFeaturesList();
6702 try argv.ensureUnusedCapacity(all_features_list.len * 4);
6703 for (all_features_list, 0..) |feature, index_usize| {
6704 const index = @as(std.Target.Cpu.Feature.Set.Index, @intCast(index_usize));
6705 const is_enabled = target.cpu.features.isEnabled(index);
6706
6707 const plus_or_minus = "-+"[@intFromBool(is_enabled)];
6708 try buf.print(comp.gpa, "{c}{s}", .{ plus_or_minus, feature.name });
6709 }
6710 break :mcpu try buf.toOwnedSlice(arena);
6711 };
6712 try argv.append(mcpu);
6713
6714 try argv.appendSlice(comp.global_cc_argv);
6715 try argv.appendSlice(owner_mod.cc_argv);
6716}
6717
67186766/// Add common C compiler args between translate-c and C object compilation.
67196767fn addCommonCCArgs(
67206768 comp: *const Compilation,
src/main.zig+29-98
......@@ -4520,12 +4520,11 @@ fn cmdTranslateC(
45204520 prog_node: std.Progress.Node,
45214521) !void {
45224522 dev.check(.translate_c_command);
4523 const color: Color = .auto;
45244523
45254524 assert(comp.c_source_files.len == 1);
45264525 const c_source_file = comp.c_source_files[0];
45274526
4528 const translated_zig_basename = try std.fmt.allocPrint(arena, "{s}.zig", .{comp.root_name});
4527 const translated_basename = try std.fmt.allocPrint(arena, "{s}.zig", .{comp.root_name});
45294528
45304529 var man: Cache.Manifest = comp.obtainCObjectCacheManifest(comp.root_mod);
45314530 man.want_shared_lock = false;
......@@ -4537,111 +4536,43 @@ fn cmdTranslateC(
45374536 fatal("unable to process '{s}': {s}", .{ c_source_file.src_path, @errorName(err) });
45384537 };
45394538
4540 if (fancy_output) |p| p.cache_hit = true;
4541 const bin_digest, const hex_digest = if (try man.hit()) digest: {
4542 if (file_system_inputs) |buf| try man.populateFileSystemInputs(buf);
4543 const bin_digest = man.finalBin();
4544 const hex_digest = Cache.binToHex(bin_digest);
4545 break :digest .{ bin_digest, hex_digest };
4546 } else digest: {
4547 if (fancy_output) |p| p.cache_hit = false;
4548
4549 const tmp_basename = std.fmt.hex(std.crypto.random.int(u64));
4550 const tmp_sub_path = "tmp" ++ fs.path.sep_str ++ tmp_basename;
4551 const cache_dir = comp.dirs.local_cache.handle;
4552 var cache_tmp_dir = try cache_dir.makeOpenPath(tmp_sub_path, .{});
4553 defer cache_tmp_dir.close();
4554
4555 const translated_path = try comp.dirs.local_cache.join(arena, &.{ tmp_sub_path, translated_zig_basename });
4556
4557 const ext = Compilation.classifyFileExt(c_source_file.src_path);
4558 const out_dep_path: ?[]const u8 = blk: {
4559 if (comp.disable_c_depfile) break :blk null;
4560 const c_src_basename = fs.path.basename(c_source_file.src_path);
4561 const dep_basename = try std.fmt.allocPrint(arena, "{s}.d", .{c_src_basename});
4562 const out_dep_path = try comp.dirs.local_cache.join(arena, &.{ tmp_sub_path, dep_basename });
4563 break :blk out_dep_path;
4564 };
4565
4566 var argv = std.array_list.Managed([]const u8).init(arena);
4567 try argv.append("--zig-integration");
4568 try comp.addTranslateCCArgs(arena, &argv, ext, out_dep_path, comp.root_mod);
4569 try argv.appendSlice(&.{ c_source_file.src_path, "-o", translated_path });
4570 if (comp.verbose_cc) Compilation.dump_argv(argv.items);
4571
4572 var stdout: []u8 = undefined;
4573 try translateC(comp.gpa, arena, argv.items, prog_node, &stdout);
4574
4575 if (out_dep_path) |dep_file_path| add_deps: {
4576 const dep_basename = fs.path.basename(dep_file_path);
4577 // Add the files depended on to the cache system, if a dep file was emitted
4578 man.addDepFilePost(cache_tmp_dir, dep_basename) catch |err| switch (err) {
4579 error.FileNotFound => break :add_deps,
4580 else => |e| return e,
4581 };
4582 // Just to save disk space, we delete the file because it is never needed again.
4583 cache_tmp_dir.deleteFile(dep_basename) catch |err| {
4584 warn("failed to delete '{s}': {t}", .{ dep_file_path, err });
4585 };
4586 }
4587
4588 if (stdout.len > 0) {
4589 var reader: std.Io.Reader = .fixed(stdout);
4590 const MessageHeader = std.zig.Server.Message.Header;
4591 const header = reader.takeStruct(MessageHeader, .little) catch unreachable;
4592 const body = reader.take(header.bytes_len) catch unreachable;
4593 switch (header.tag) {
4594 .error_bundle => {
4595 // TODO: De-dupe this logic
4596 const EbHdr = std.zig.Server.Message.ErrorBundle;
4597 const eb_hdr = @as(*align(1) const EbHdr, @ptrCast(body));
4598 const extra_bytes =
4599 body[@sizeOf(EbHdr)..][0 .. @sizeOf(u32) * eb_hdr.extra_len];
4600 const string_bytes =
4601 body[@sizeOf(EbHdr) + extra_bytes.len ..][0..eb_hdr.string_bytes_len];
4602 const unaligned_extra = std.mem.bytesAsSlice(u32, extra_bytes);
4603 const extra_array = try comp.gpa.alloc(u32, unaligned_extra.len);
4604 @memcpy(extra_array, unaligned_extra);
4605 const error_bundle: std.zig.ErrorBundle = .{
4606 .string_bytes = try comp.gpa.dupe(u8, string_bytes),
4607 .extra = extra_array,
4608 };
4539 const result: Compilation.CImportResult = if (try man.hit()) .{
4540 .digest = man.finalBin(),
4541 .cache_hit = true,
4542 .errors = std.zig.ErrorBundle.empty,
4543 } else result: {
4544 const result = try comp.translateC(
4545 arena,
4546 &man,
4547 Compilation.classifyFileExt(c_source_file.src_path),
4548 .{ .path = c_source_file.src_path },
4549 translated_basename,
4550 comp.root_mod,
4551 prog_node,
4552 );
46094553
4610 if (fancy_output) |p| {
4611 if (file_system_inputs) |buf| try man.populateFileSystemInputs(buf);
4612 p.errors = error_bundle;
4613 return;
4614 } else {
4615 error_bundle.renderToStdErr(color.renderOptions());
4616 process.exit(1);
4617 }
4618 },
4619 else => unreachable, // No other messagse are sent
4554 if (result.errors.errorMessageCount() != 0) {
4555 if (fancy_output) |p| {
4556 if (file_system_inputs) |buf| try man.populateFileSystemInputs(buf);
4557 p.* = result;
4558 return;
4559 } else {
4560 const color: Color = .auto;
4561 result.errors.renderToStdErr(color.renderOptions());
4562 process.exit(1);
46204563 }
46214564 }
46224565
4623 const bin_digest = man.finalBin();
4624 const hex_digest = Cache.binToHex(bin_digest);
4625
4626 const o_sub_path = "o" ++ fs.path.sep_str ++ hex_digest;
4627 try Compilation.renameTmpIntoCache(
4628 comp.dirs.local_cache,
4629 tmp_sub_path,
4630 o_sub_path,
4631 );
4632
46334566 man.writeManifest() catch |err| warn("failed to write cache manifest: {t}", .{err});
4634
4635 if (file_system_inputs) |buf| try man.populateFileSystemInputs(buf);
4636
4637 break :digest .{ bin_digest, hex_digest };
4567 break :result result;
46384568 };
46394569
4570 if (file_system_inputs) |buf| try man.populateFileSystemInputs(buf);
46404571 if (fancy_output) |p| {
4641 p.digest = bin_digest;
4642 p.errors = std.zig.ErrorBundle.empty;
4572 p.* = result;
46434573 } else {
4644 const out_zig_path = try fs.path.join(arena, &.{ "o", &hex_digest, translated_zig_basename });
4574 const hex_digest = Cache.binToHex(result.digest);
4575 const out_zig_path = try fs.path.join(arena, &.{ "o", &hex_digest, translated_basename });
46454576 const zig_file = comp.dirs.local_cache.handle.openFile(out_zig_path, .{}) catch |err| {
46464577 const path = comp.dirs.local_cache.path orelse ".";
46474578 fatal("unable to open cached translated zig file '{s}{s}{s}': {s}", .{
tools/incr-check.zig+1-14
......@@ -259,20 +259,7 @@ const Eval = struct {
259259
260260 switch (header.tag) {
261261 .error_bundle => {
262 const EbHdr = std.zig.Server.Message.ErrorBundle;
263 const eb_hdr = @as(*align(1) const EbHdr, @ptrCast(body));
264 const extra_bytes =
265 body[@sizeOf(EbHdr)..][0 .. @sizeOf(u32) * eb_hdr.extra_len];
266 const string_bytes =
267 body[@sizeOf(EbHdr) + extra_bytes.len ..][0..eb_hdr.string_bytes_len];
268 // TODO: use @ptrCast when the compiler supports it
269 const unaligned_extra = std.mem.bytesAsSlice(u32, extra_bytes);
270 const extra_array = try arena.alloc(u32, unaligned_extra.len);
271 @memcpy(extra_array, unaligned_extra);
272 const result_error_bundle: std.zig.ErrorBundle = .{
273 .string_bytes = try arena.dupe(u8, string_bytes),
274 .extra = extra_array,
275 };
262 const result_error_bundle = try std.zig.Server.allocErrorBundle(arena, body);
276263 if (stderr.bufferedLen() > 0) {
277264 const stderr_data = try poller.toOwnedSlice(.stderr);
278265 if (eval.allow_stderr) {