authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-09-13 22:58:09-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-09-16 13:12:47-07:00
loga014c1a2876acf93a11cf4c1fdd255939ee0c6e0
tree2083018a6fda68add91a5faab9deaf9f1b9ffba0
parent79a7b7c0f033787215471beb9eab99264c1b7003

std.Build.Cache.DepTokenizer: slightly modernize


8 files changed, 380 insertions(+), 344 deletions(-)

lib/compiler/Maker/Step/Run.zig+26-10
......@@ -292,16 +292,32 @@ pub fn make(
292292 switch (arg.flags.tag) {
293293 .output_file => if (arg.flags.dep_file) {
294294 const generated_path = maker.generatedPath(arg.generated.value.?).*;
295 const result = if (has_side_effects)
296 man.addDepFile(generated_path.root_dir.handle, generated_path.sub_path)
297 else
298 man.addDepFilePost(generated_path.root_dir.handle, generated_path.sub_path);
299 result catch |err| switch (err) {
300 error.OutOfMemory, error.Canceled => |e| return e,
301 else => |e| return step.fail(maker, "failed adding to cache the file {f}: {t}", .{
302 generated_path, e,
303 }),
304 };
295 if (has_side_effects) {
296 var diagnostic: Cache.DepTokenizer.Token = undefined;
297 man.addInputDepFile(generated_path, &diagnostic) catch |err| switch (err) {
298 error.OutOfMemory, error.Canceled => |e| return e,
299 error.InvalidDepFile => return step.fail(maker, "failed adding dep file {f} to cache: {f}", .{
300 generated_path, diagnostic,
301 }),
302 else => |e| return step.fail(maker, "failed adding dep file {f} to cache: {t}", .{
303 generated_path, e,
304 }),
305 };
306 } else {
307 var diagnostic: Cache.Manifest.AddDiscoveredDepFileDiagnostic = undefined;
308 man.addDiscoveredDepFile(generated_path, &diagnostic) catch |err| switch (err) {
309 error.OutOfMemory, error.Canceled => |e| return e,
310 error.InvalidDepFile => return step.fail(maker, "failed adding dep file {f} to cache: {f}", .{
311 generated_path, diagnostic.dep_tokenizer,
312 }),
313 error.FileSystemFailure => return step.fail(maker, "failed adding a path from dep file {f} to cache: {f}", .{
314 generated_path, diagnostic.add_discovered_path,
315 }),
316 else => |e| return step.fail(maker, "failed adding dep file {f} to cache: {t}", .{
317 generated_path, e,
318 }),
319 };
320 }
305321 },
306322 .output_directory => continue,
307323 else => unreachable,
lib/std/Build/Cache.zig+112-47
......@@ -759,6 +759,52 @@ pub const Manifest = struct {
759759 _ = try addInputPath(m, opt_path orelse return, options);
760760 }
761761
762 pub const AddInputDepFileError = error{
763 InvalidDepFile,
764 } || Allocator.Error || Io.File.OpenError || Io.File.Reader.Error;
765
766 pub fn addInputDepFile(m: *Manifest, path: Path, diagnostic: ?*DepTokenizer.Token) AddInputDepFileError!void {
767 assert(m.manifest_file == null);
768 assert(m.state == .input);
769
770 const cache = m.cache;
771 const gpa = cache.gpa;
772 const io = cache.io;
773
774 // TODO: change DepTokenizer to be streaming rather than operating on slice of bytes.
775 const prev_len = m.all_input_content.items.len;
776 defer m.all_input_content.items.len = prev_len;
777
778 const file = try path.root_dir.handle.openFile(io, path.sub_path, .{});
779 defer file.close(io);
780
781 var file_reader: Io.File.Reader = .init(file, io, &.{});
782 file_reader.interface.appendRemainingUnlimited(gpa, &m.all_input_content) catch |err| switch (err) {
783 error.OutOfMemory => |e| return e,
784 error.ReadFailed => return file_reader.err.?,
785 };
786
787 var aux: std.ArrayList(u8) = .empty;
788 defer aux.deinit(gpa);
789
790 var it: DepTokenizer = .{ .bytes = m.all_input_content.items[prev_len..] };
791 while (it.next()) |token| switch (token) {
792 .target, .target_must_resolve => {},
793 .prereq => |file_path| {
794 _ = try m.addInputPath(.initCwd(file_path), .{});
795 },
796 .prereq_must_resolve => {
797 aux.clearRetainingCapacity();
798 try token.resolve(gpa, &aux);
799 _ = try m.addInputPath(.initCwd(aux.items), .{});
800 },
801 else => |err| {
802 if (diagnostic) |d| d.* = err;
803 return error.InvalidDepFile;
804 },
805 };
806 }
807
762808 pub const CheckResult = union(enum) {
763809 hit,
764810 incomplete_manifest,
......@@ -1614,6 +1660,13 @@ pub const Manifest = struct {
16141660 stat_dir: Io.Dir.StatError,
16151661 read_file: Io.File.ReadPositionalError,
16161662 read_dir: Io.Dir.Reader.Error,
1663
1664 pub fn format(this: @This(), w: *Io.Writer) Io.Writer.Error!void {
1665 switch (this) {
1666 .none => return w.writeAll("none"),
1667 else => |err, tag| return w.print("{t}: {t}", .{ tag, err }),
1668 }
1669 }
16171670 };
16181671
16191672 pub const AddDiscoveredPathError = error{
......@@ -1726,6 +1779,59 @@ pub const Manifest = struct {
17261779 }
17271780 }
17281781
1782 pub const AddDiscoveredDepFileError = error{
1783 InvalidDepFile,
1784 } || AddDiscoveredPathError || Io.File.OpenError || Io.File.Reader.Error;
1785
1786 pub const AddDiscoveredDepFileDiagnostic = union(enum) {
1787 add_discovered_path: AddDiscoveredPathDiagnostic,
1788 dep_tokenizer: DepTokenizer.Token,
1789 };
1790
1791 pub fn addDiscoveredDepFile(
1792 m: *Manifest,
1793 path: Path,
1794 diagnostic: ?*AddDiscoveredDepFileDiagnostic,
1795 ) AddDiscoveredDepFileError!void {
1796 assert(m.manifest_file != null);
1797 transitionToMissDiscovered(m);
1798
1799 const cache = m.cache;
1800 const gpa = cache.gpa;
1801 const io = cache.io;
1802
1803 // TODO: change DepTokenizer to be streaming rather than operating on slice of bytes.
1804 const prev_len = m.all_input_content.items.len;
1805 defer m.all_input_content.items.len = prev_len;
1806
1807 const file = try path.root_dir.handle.openFile(io, path.sub_path, .{});
1808 defer file.close(io);
1809
1810 var file_reader: Io.File.Reader = .init(file, io, &.{});
1811 file_reader.interface.appendRemainingUnlimited(gpa, &m.all_input_content) catch |err| switch (err) {
1812 error.OutOfMemory => |e| return e,
1813 error.ReadFailed => return file_reader.err.?,
1814 };
1815
1816 var aux: std.ArrayList(u8) = .empty;
1817 defer aux.deinit(gpa);
1818
1819 var it: DepTokenizer = .{ .bytes = m.all_input_content.items[prev_len..] };
1820 while (it.next()) |token| switch (token) {
1821 .target, .target_must_resolve => {},
1822 .prereq => |p| try m.addDiscoveredPath(.{ .discovered_path = .{ .unresolved = .initCwd(p) } }),
1823 .prereq_must_resolve => {
1824 aux.clearRetainingCapacity();
1825 try token.resolve(gpa, &aux);
1826 try m.addDiscoveredPath(.{ .discovered_path = .{ .unresolved = .initCwd(aux.items) } });
1827 },
1828 else => |err| {
1829 if (diagnostic) |d| d.* = .{ .dep_tokenizer = err };
1830 return error.InvalidDepFile;
1831 },
1832 };
1833 }
1834
17291835 fn populateFile(
17301836 m: *Manifest,
17311837 file: *File,
......@@ -1810,53 +1916,6 @@ pub const Manifest = struct {
18101916 }
18111917 }
18121918
1813 pub fn addDepFile(self: *Manifest, dir: Io.Dir, dep_file_sub_path: []const u8) !void {
1814 assert(self.manifest_file == null);
1815 return self.addDepFileMaybePost(dir, dep_file_sub_path);
1816 }
1817
1818 pub fn addDepFilePost(self: *Manifest, dir: Io.Dir, dep_file_sub_path: []const u8) !void {
1819 assert(self.manifest_file != null);
1820 return self.addDepFileMaybePost(dir, dep_file_sub_path);
1821 }
1822
1823 fn addDepFileMaybePost(self: *Manifest, dir: Io.Dir, dep_file_sub_path: []const u8) !void {
1824 const gpa = self.cache.gpa;
1825 const io = self.cache.io;
1826 const dep_file_contents = try dir.readFileAlloc(io, dep_file_sub_path, gpa, .unlimited);
1827 defer gpa.free(dep_file_contents);
1828
1829 var error_buf: std.ArrayList(u8) = .empty;
1830 defer error_buf.deinit(gpa);
1831
1832 var resolve_buf: std.ArrayList(u8) = .empty;
1833 defer resolve_buf.deinit(gpa);
1834
1835 var it: DepTokenizer = .{ .bytes = dep_file_contents };
1836 while (it.next()) |token| switch (token) {
1837 // We don't care about targets, we only want the prereqs
1838 // Clang is invoked in single-source mode but other programs may not
1839 .target, .target_must_resolve => {},
1840 .prereq => |file_path| if (self.manifest_file == null) {
1841 _ = try self.addInputPath(.initCwd(file_path), .{});
1842 } else try self.addDiscoveredPath(.{ .discovered_path = .{ .unresolved = .initCwd(file_path) } }),
1843 .prereq_must_resolve => {
1844 resolve_buf.clearRetainingCapacity();
1845 try token.resolve(gpa, &resolve_buf);
1846 if (self.manifest_file == null) {
1847 _ = try self.addInputPath(.initCwd(resolve_buf.items), .{});
1848 } else try self.addDiscoveredPath(.{
1849 .discovered_path = .{ .unresolved = .initCwd(resolve_buf.items) },
1850 });
1851 },
1852 else => |err| {
1853 try err.printError(gpa, &error_buf);
1854 log.err("failed parsing {s}: {s}", .{ dep_file_sub_path, error_buf.items });
1855 return error.InvalidDepFile;
1856 },
1857 };
1858 }
1859
18601919 /// See also `hitDigestHex`.
18611920 pub fn hitDigest(m: *Manifest) BinDigest {
18621921 assert(m.manifest_file != null);
......@@ -2533,3 +2592,9 @@ test "Manifest with files added after initial hash" {
25332592 try testing.expect(!mem.eql(u8, &digest1, &digest3));
25342593 }
25352594}
2595
2596test {
2597 _ = Path;
2598 _ = Directory;
2599 _ = DepTokenizer;
2600}
lib/std/Build/Cache/DepTokenizer.zig+188-250
......@@ -1,14 +1,15 @@
11const Tokenizer = @This();
22
3index: usize = 0,
4bytes: []const u8,
5state: State = .lhs,
6
73const std = @import("std");
4const Io = std.Io;
85const testing = std.testing;
96const assert = std.debug.assert;
107const Allocator = std.mem.Allocator;
118
9index: usize = 0,
10bytes: []const u8,
11state: State = .lhs,
12
1213pub fn next(self: *Tokenizer) ?Token {
1314 var start = self.index;
1415 var must_resolve = false;
......@@ -16,10 +17,7 @@ pub fn next(self: *Tokenizer) ?Token {
1617 const char = self.bytes[self.index];
1718 switch (self.state) {
1819 .lhs => switch (char) {
19 '\t', '\n', '\r', ' ' => {
20 // silently ignore whitespace
21 self.index += 1;
22 },
20 '\t', '\n', '\r', ' ' => self.index += 1, // Ignore whitespace.
2321 else => {
2422 start = self.index;
2523 self.state = .target;
......@@ -79,7 +77,7 @@ pub fn next(self: *Tokenizer) ?Token {
7977 self.index += 1;
8078 },
8179 else => {
82 return errorIllegalChar(.expected_dollar_sign, self.index, char);
80 return errorIllegalChar(.expected_dollar, self.index, char);
8381 },
8482 },
8583 .target_colon => switch (char) {
......@@ -347,7 +345,7 @@ pub const Token = union(enum) {
347345
348346 invalid_target: IndexAndChar,
349347 bad_target_escape: IndexAndChar,
350 expected_dollar_sign: IndexAndChar,
348 expected_dollar: IndexAndChar,
351349 continuation_eol: IndexAndChar,
352350 incomplete_escape: IndexAndChar,
353351 expected_colon: IndexAndChar,
......@@ -429,48 +427,23 @@ pub const Token = union(enum) {
429427 }
430428 }
431429
432 pub fn printError(self: Token, gpa: Allocator, list: *std.ArrayList(u8)) error{OutOfMemory}!void {
433 switch (self) {
434 .target, .target_must_resolve, .prereq, .prereq_must_resolve => unreachable, // not an error
435 .incomplete_quoted_prerequisite,
436 .incomplete_target,
437 => |index_and_bytes| {
438 try list.print(gpa, "{s} '", .{self.errStr()});
439 if (self == .incomplete_target) {
440 const tmp = Token{ .target_must_resolve = index_and_bytes.bytes };
441 try tmp.resolve(gpa, list);
442 } else {
443 try printCharValues(gpa, list, index_and_bytes.bytes);
444 }
445 try list.print(gpa, "' at position {d}", .{index_and_bytes.index});
446 },
430 pub fn format(token: Token, w: *Io.Writer) Io.Writer.Error!void {
431 switch (token) {
432 .target, .target_must_resolve, .prereq, .prereq_must_resolve => return w.writeAll(@tagName(token)),
433 .incomplete_quoted_prerequisite, .incomplete_target => |info| return w.print("{t} {q} at position {d}", .{
434 token, info.bytes, info.index,
435 }),
447436 .invalid_target,
448437 .bad_target_escape,
449 .expected_dollar_sign,
438 .expected_dollar,
450439 .continuation_eol,
451440 .incomplete_escape,
452441 .expected_colon,
453 => |index_and_char| {
454 try list.appendSlice(gpa, "illegal char ");
455 try printUnderstandableChar(gpa, list, index_and_char.char);
456 try list.print(gpa, " at position {d}: {s}", .{ index_and_char.index, self.errStr() });
457 },
442 => |info| return w.print("illegal char '{f}' at position {d}: {t}", .{
443 std.zig.fmtChar(info.char), info.index, token,
444 }),
458445 }
459446 }
460
461 fn errStr(self: Token) []const u8 {
462 return switch (self) {
463 .target, .target_must_resolve, .prereq, .prereq_must_resolve => unreachable, // not an error
464 .incomplete_quoted_prerequisite => "incomplete quoted prerequisite",
465 .incomplete_target => "incomplete target",
466 .invalid_target => "invalid target",
467 .bad_target_escape => "bad target escape",
468 .expected_dollar_sign => "expecting '$'",
469 .continuation_eol => "continuation expecting end-of-line",
470 .incomplete_escape => "incomplete escape",
471 .expected_colon => "expecting ':'",
472 };
473 }
474447};
475448
476449test "empty file" {
......@@ -493,37 +466,37 @@ test "empty colon" {
493466}
494467
495468test "empty target" {
496 try depTokenizer("foo.o:", "target = {foo.o}");
469 try depTokenizer("foo.o:", "target = {\"foo.o\"}");
497470 try depTokenizer(
498471 \\foo.o:
499472 \\bar.o:
500473 \\abcd.o:
501474 ,
502 \\target = {foo.o}
503 \\target = {bar.o}
504 \\target = {abcd.o}
475 \\target = {"foo.o"}
476 \\target = {"bar.o"}
477 \\target = {"abcd.o"}
505478 );
506479}
507480
508481test "whitespace empty target" {
509 try depTokenizer("\nfoo.o:", "target = {foo.o}");
510 try depTokenizer("\rfoo.o:", "target = {foo.o}");
511 try depTokenizer("\r\nfoo.o:", "target = {foo.o}");
512 try depTokenizer(" foo.o:", "target = {foo.o}");
482 try depTokenizer("\nfoo.o:", "target = {\"foo.o\"}");
483 try depTokenizer("\rfoo.o:", "target = {\"foo.o\"}");
484 try depTokenizer("\r\nfoo.o:", "target = {\"foo.o\"}");
485 try depTokenizer(" foo.o:", "target = {\"foo.o\"}");
513486}
514487
515488test "escape empty target" {
516 try depTokenizer("\\ foo.o:", "target = { foo.o}");
517 try depTokenizer("\\#foo.o:", "target = {#foo.o}");
518 try depTokenizer("\\\\foo.o:", "target = {\\foo.o}");
519 try depTokenizer("$$foo.o:", "target = {$foo.o}");
489 try depTokenizer("\\ foo.o:", "target = {\" foo.o\"}");
490 try depTokenizer("\\#foo.o:", "target = {\"#foo.o\"}");
491 try depTokenizer("\\\\foo.o:", "target = {\"\\\\foo.o\"}");
492 try depTokenizer("$$foo.o:", "target = {\"$foo.o\"}");
520493}
521494
522495test "empty target linefeeds" {
523496 try depTokenizer("\n", "");
524497 try depTokenizer("\r\n", "");
525498
526 const expect = "target = {foo.o}";
499 const expect = "target = {\"foo.o\"}";
527500 try depTokenizer(
528501 \\foo.o:
529502 , expect);
......@@ -541,7 +514,7 @@ test "empty target linefeeds" {
541514}
542515
543516test "empty target linefeeds + continuations" {
544 const expect = "target = {foo.o}";
517 const expect = "target = {\"foo.o\"}";
545518 try depTokenizer(
546519 \\foo.o:\
547520 , expect);
......@@ -559,7 +532,7 @@ test "empty target linefeeds + continuations" {
559532}
560533
561534test "empty target linefeeds + hspace + continuations" {
562 const expect = "target = {foo.o}";
535 const expect = "target = {\"foo.o\"}";
563536 try depTokenizer(
564537 \\foo.o: \
565538 , expect);
......@@ -577,7 +550,7 @@ test "empty target linefeeds + hspace + continuations" {
577550}
578551
579552test "empty target + hspace + colon" {
580 const expect = "target = {foo.o}";
553 const expect = "target = {\"foo.o\"}";
581554
582555 try depTokenizer("foo.o :", expect);
583556 try depTokenizer("foo.o\t\t\t:", expect);
......@@ -588,8 +561,8 @@ test "empty target + hspace + colon" {
588561
589562test "prereq" {
590563 const expect =
591 \\target = {foo.o}
592 \\prereq = {foo.c}
564 \\target = {"foo.o"}
565 \\prereq = {"foo.c"}
593566 ;
594567 try depTokenizer("foo.o: foo.c", expect);
595568 try depTokenizer(
......@@ -608,9 +581,9 @@ test "prereq" {
608581
609582test "prereq continuation" {
610583 const expect =
611 \\target = {foo.o}
612 \\prereq = {foo.h}
613 \\prereq = {bar.h}
584 \\target = {"foo.o"}
585 \\prereq = {"foo.h"}
586 \\prereq = {"bar.h"}
614587 ;
615588 try depTokenizer(
616589 \\foo.o: foo.h\
......@@ -624,19 +597,19 @@ test "prereq continuation" {
624597
625598test "prereq continuation (CRLF)" {
626599 const expect =
627 \\target = {foo.o}
628 \\prereq = {foo.h}
629 \\prereq = {bar.h}
600 \\target = {"foo.o"}
601 \\prereq = {"foo.h"}
602 \\prereq = {"bar.h"}
630603 ;
631604 try depTokenizer("foo.o: foo.h\\\r\nbar.h", expect);
632605}
633606
634607test "multiple prereqs" {
635608 const expect =
636 \\target = {foo.o}
637 \\prereq = {foo.c}
638 \\prereq = {foo.h}
639 \\prereq = {bar.h}
609 \\target = {"foo.o"}
610 \\prereq = {"foo.c"}
611 \\prereq = {"foo.h"}
612 \\prereq = {"bar.h"}
640613 ;
641614 try depTokenizer("foo.o: foo.c foo.h bar.h", expect);
642615 try depTokenizer(
......@@ -680,19 +653,19 @@ test "multiple targets and prereqs" {
680653 \\ one.h two.h \
681654 \\ three.h four.h
682655 ,
683 \\target = {foo.o}
684 \\prereq = {foo.c}
685 \\target = {bar.o}
686 \\prereq = {bar.c}
687 \\prereq = {a.h}
688 \\prereq = {b.h}
689 \\prereq = {c.h}
690 \\target = {abc.o}
691 \\prereq = {abc.c}
692 \\prereq = {one.h}
693 \\prereq = {two.h}
694 \\prereq = {three.h}
695 \\prereq = {four.h}
656 \\target = {"foo.o"}
657 \\prereq = {"foo.c"}
658 \\target = {"bar.o"}
659 \\prereq = {"bar.c"}
660 \\prereq = {"a.h"}
661 \\prereq = {"b.h"}
662 \\prereq = {"c.h"}
663 \\target = {"abc.o"}
664 \\prereq = {"abc.c"}
665 \\prereq = {"one.h"}
666 \\prereq = {"two.h"}
667 \\prereq = {"three.h"}
668 \\prereq = {"four.h"}
696669 );
697670 try depTokenizer(
698671 \\ascii.o: ascii.c
......@@ -702,21 +675,21 @@ test "multiple targets and prereqs" {
702675 \\ macho.c\
703676 \\ a.h b.h c.h
704677 ,
705 \\target = {ascii.o}
706 \\prereq = {ascii.c}
707 \\target = {base64.o}
708 \\prereq = {base64.c}
709 \\prereq = {stdio.h}
710 \\target = {elf.o}
711 \\prereq = {elf.c}
712 \\prereq = {a.h}
713 \\prereq = {b.h}
714 \\prereq = {c.h}
715 \\target = {macho.o}
716 \\prereq = {macho.c}
717 \\prereq = {a.h}
718 \\prereq = {b.h}
719 \\prereq = {c.h}
678 \\target = {"ascii.o"}
679 \\prereq = {"ascii.c"}
680 \\target = {"base64.o"}
681 \\prereq = {"base64.c"}
682 \\prereq = {"stdio.h"}
683 \\target = {"elf.o"}
684 \\prereq = {"elf.c"}
685 \\prereq = {"a.h"}
686 \\prereq = {"b.h"}
687 \\prereq = {"c.h"}
688 \\target = {"macho.o"}
689 \\prereq = {"macho.c"}
690 \\prereq = {"a.h"}
691 \\prereq = {"b.h"}
692 \\prereq = {"c.h"}
720693 );
721694 try depTokenizer(
722695 \\a$$scii.o: ascii.c
......@@ -726,20 +699,20 @@ test "multiple targets and prereqs" {
726699 \\ "macho!.c" \
727700 \\ a.h b.h c.h
728701 ,
729 \\target = {a$scii.o}
730 \\prereq = {ascii.c}
731 \\target = {\base64.o}
732 \\prereq = {\base64.c}
733 \\prereq = {s t#dio.h}
734 \\target = {e\lf.o}
735 \\prereq = {e\lf.c}
736 \\prereq = {a.h$$}
737 \\prereq = {$$b.h c.h$$}
738 \\target = {macho.o}
739 \\prereq = {macho!.c}
740 \\prereq = {a.h}
741 \\prereq = {b.h}
742 \\prereq = {c.h}
702 \\target = {"a$scii.o"}
703 \\prereq = {"ascii.c"}
704 \\target = {"\\base64.o"}
705 \\prereq = {"\\base64.c"}
706 \\prereq = {"s t#dio.h"}
707 \\target = {"e\\lf.o"}
708 \\prereq = {"e\\lf.c"}
709 \\prereq = {"a.h$$"}
710 \\prereq = {"$$b.h c.h$$"}
711 \\target = {"macho.o"}
712 \\prereq = {"macho!.c"}
713 \\prereq = {"a.h"}
714 \\prereq = {"b.h"}
715 \\prereq = {"c.h"}
743716 );
744717}
745718
......@@ -750,12 +723,12 @@ test "windows quoted prereqs" {
750723 \\ "C:\Program Files (x86)\Microsoft Visual Studio\foo1.h" \
751724 \\ "C:\Program Files (x86)\Microsoft Visual Studio\foo2.h"
752725 ,
753 \\target = {c:\foo.o}
754 \\prereq = {C:\Program Files (x86)\Microsoft Visual Studio\foo.c}
755 \\target = {c:\foo2.o}
756 \\prereq = {C:\Program Files (x86)\Microsoft Visual Studio\foo2.c}
757 \\prereq = {C:\Program Files (x86)\Microsoft Visual Studio\foo1.h}
758 \\prereq = {C:\Program Files (x86)\Microsoft Visual Studio\foo2.h}
726 \\target = {"c:\\foo.o"}
727 \\prereq = {"C:\\Program Files (x86)\\Microsoft Visual Studio\\foo.c"}
728 \\target = {"c:\\foo2.o"}
729 \\prereq = {"C:\\Program Files (x86)\\Microsoft Visual Studio\\foo2.c"}
730 \\prereq = {"C:\\Program Files (x86)\\Microsoft Visual Studio\\foo1.h"}
731 \\prereq = {"C:\\Program Files (x86)\\Microsoft Visual Studio\\foo2.h"}
759732 );
760733}
761734
......@@ -779,23 +752,23 @@ test "windows mixed prereqs" {
779752 \\ "C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.21.27702\lib\x64\\..\..\include\vcruntime_string.h" \
780753 \\ "C:\Program Files (x86)\Windows Kits\10\\Include\10.0.17763.0\ucrt\corecrt_wstring.h"
781754 ,
782 \\target = {cimport.o}
783 \\prereq = {C:\msys64\home\anon\project\zig\master\zig-cache\o\qhvhbUo7GU5iKyQ5mpA8TcQpncCYaQu0wwvr3ybiSTj_Dtqi1Nmcb70kfODJ2Qlg\cimport.h}
784 \\prereq = {C:\Program Files (x86)\Windows Kits\10\\Include\10.0.17763.0\ucrt\stdio.h}
785 \\prereq = {C:\Program Files (x86)\Windows Kits\10\\Include\10.0.17763.0\ucrt\corecrt.h}
786 \\prereq = {C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.21.27702\lib\x64\\..\..\include\vcruntime.h}
787 \\prereq = {C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.21.27702\lib\x64\\..\..\include\sal.h}
788 \\prereq = {C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.21.27702\lib\x64\\..\..\include\concurrencysal.h}
789 \\prereq = {C:\msys64\opt\zig\lib\zig\include\vadefs.h}
790 \\prereq = {C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.21.27702\lib\x64\\..\..\include\vadefs.h}
791 \\prereq = {C:\Program Files (x86)\Windows Kits\10\\Include\10.0.17763.0\ucrt\corecrt_wstdio.h}
792 \\prereq = {C:\Program Files (x86)\Windows Kits\10\\Include\10.0.17763.0\ucrt\corecrt_stdio_config.h}
793 \\prereq = {C:\Program Files (x86)\Windows Kits\10\\Include\10.0.17763.0\ucrt\string.h}
794 \\prereq = {C:\Program Files (x86)\Windows Kits\10\\Include\10.0.17763.0\ucrt\corecrt_memory.h}
795 \\prereq = {C:\Program Files (x86)\Windows Kits\10\\Include\10.0.17763.0\ucrt\corecrt_memcpy_s.h}
796 \\prereq = {C:\Program Files (x86)\Windows Kits\10\\Include\10.0.17763.0\ucrt\errno.h}
797 \\prereq = {C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.21.27702\lib\x64\\..\..\include\vcruntime_string.h}
798 \\prereq = {C:\Program Files (x86)\Windows Kits\10\\Include\10.0.17763.0\ucrt\corecrt_wstring.h}
755 \\target = {"cimport.o"}
756 \\prereq = {"C:\\msys64\\home\\anon\\project\\zig\\master\\zig-cache\\o\\qhvhbUo7GU5iKyQ5mpA8TcQpncCYaQu0wwvr3ybiSTj_Dtqi1Nmcb70kfODJ2Qlg\\cimport.h"}
757 \\prereq = {"C:\\Program Files (x86)\\Windows Kits\\10\\\\Include\\10.0.17763.0\\ucrt\\stdio.h"}
758 \\prereq = {"C:\\Program Files (x86)\\Windows Kits\\10\\\\Include\\10.0.17763.0\\ucrt\\corecrt.h"}
759 \\prereq = {"C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\VC\\Tools\\MSVC\\14.21.27702\\lib\\x64\\\\..\\..\\include\\vcruntime.h"}
760 \\prereq = {"C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\VC\\Tools\\MSVC\\14.21.27702\\lib\\x64\\\\..\\..\\include\\sal.h"}
761 \\prereq = {"C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\VC\\Tools\\MSVC\\14.21.27702\\lib\\x64\\\\..\\..\\include\\concurrencysal.h"}
762 \\prereq = {"C:\\msys64\\opt\\zig\\lib\\zig\\include\\vadefs.h"}
763 \\prereq = {"C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\VC\\Tools\\MSVC\\14.21.27702\\lib\\x64\\\\..\\..\\include\\vadefs.h"}
764 \\prereq = {"C:\\Program Files (x86)\\Windows Kits\\10\\\\Include\\10.0.17763.0\\ucrt\\corecrt_wstdio.h"}
765 \\prereq = {"C:\\Program Files (x86)\\Windows Kits\\10\\\\Include\\10.0.17763.0\\ucrt\\corecrt_stdio_config.h"}
766 \\prereq = {"C:\\Program Files (x86)\\Windows Kits\\10\\\\Include\\10.0.17763.0\\ucrt\\string.h"}
767 \\prereq = {"C:\\Program Files (x86)\\Windows Kits\\10\\\\Include\\10.0.17763.0\\ucrt\\corecrt_memory.h"}
768 \\prereq = {"C:\\Program Files (x86)\\Windows Kits\\10\\\\Include\\10.0.17763.0\\ucrt\\corecrt_memcpy_s.h"}
769 \\prereq = {"C:\\Program Files (x86)\\Windows Kits\\10\\\\Include\\10.0.17763.0\\ucrt\\errno.h"}
770 \\prereq = {"C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\VC\\Tools\\MSVC\\14.21.27702\\lib\\x64\\\\..\\..\\include\\vcruntime_string.h"}
771 \\prereq = {"C:\\Program Files (x86)\\Windows Kits\\10\\\\Include\\10.0.17763.0\\ucrt\\corecrt_wstring.h"}
799772 );
800773}
801774
......@@ -810,14 +783,14 @@ test "windows funky targets" {
810783 \\C:\Users\anon\$$foo.o:
811784 \\C:\Users\anon\\\ \ \ \ \ foo.o:
812785 ,
813 \\target = {C:\Users\anon\foo.o}
814 \\target = {C:\Users\anon\foo .o}
815 \\target = {C:\Users\anon\foo#.o}
816 \\target = {C:\Users\anon\foo$.o}
817 \\target = {C:\Users\anon\ foo.o}
818 \\target = {C:\Users\anon\#foo.o}
819 \\target = {C:\Users\anon\$foo.o}
820 \\target = {C:\Users\anon\ foo.o}
786 \\target = {"C:\\Users\\anon\\foo.o"}
787 \\target = {"C:\\Users\\anon\\foo .o"}
788 \\target = {"C:\\Users\\anon\\foo#.o"}
789 \\target = {"C:\\Users\\anon\\foo$.o"}
790 \\target = {"C:\\Users\\anon\\ foo.o"}
791 \\target = {"C:\\Users\\anon\\#foo.o"}
792 \\target = {"C:\\Users\\anon\\$foo.o"}
793 \\target = {"C:\\Users\\anon\\ foo.o"}
821794 );
822795}
823796
......@@ -837,13 +810,13 @@ test "windows funky prereqs" {
837810 \\ somedir\\ \\ \c.c\
838811 \\
839812 ,
840 \\target = {cimport.o}
841 \\prereq = {trailingbackslash\}
842 \\prereq = {C:\Users\John Smith\AppData\Local\zig\p\1220d14057af1a9d6dde4643293527bd5ee5099517d655251a066666a4320737ea7c\cimport.c}
843 \\prereq = {somedir\ a.c}
844 \\prereq = {somedir/ a.c}
845 \\prereq = {somedir\ b.c}
846 \\prereq = {somedir\ \ \c.c}
813 \\target = {"cimport.o"}
814 \\prereq = {"trailingbackslash\\"}
815 \\prereq = {"C:\\Users\\John Smith\\AppData\\Local\\zig\\p\\1220d14057af1a9d6dde4643293527bd5ee5099517d655251a066666a4320737ea7c\\cimport.c"}
816 \\prereq = {"somedir\\ a.c"}
817 \\prereq = {"somedir/ a.c"}
818 \\prereq = {"somedir\\ b.c"}
819 \\prereq = {"somedir\\ \\ \\c.c"}
847820 );
848821}
849822
......@@ -852,171 +825,171 @@ test "windows drive and forward slashes" {
852825 \\C:/msys64/what/zig-cache\tmp\48ac4d78dd531abd-cxa_thread_atexit.obj: \
853826 \\ C:/msys64/opt/zig3/lib/zig/libc/mingw/crt/cxa_thread_atexit.c
854827 ,
855 \\target = {C:/msys64/what/zig-cache\tmp\48ac4d78dd531abd-cxa_thread_atexit.obj}
856 \\prereq = {C:/msys64/opt/zig3/lib/zig/libc/mingw/crt/cxa_thread_atexit.c}
828 \\target = {"C:/msys64/what/zig-cache\\tmp\\48ac4d78dd531abd-cxa_thread_atexit.obj"}
829 \\prereq = {"C:/msys64/opt/zig3/lib/zig/libc/mingw/crt/cxa_thread_atexit.c"}
857830 );
858831}
859832
860833test "error incomplete escape - reverse_solidus" {
861834 try depTokenizer("\\",
862 \\ERROR: illegal char '\' at position 0: incomplete escape
835 \\ERROR: illegal char '\\' at position 0: incomplete_escape
863836 );
864837 try depTokenizer("\t\\",
865 \\ERROR: illegal char '\' at position 1: incomplete escape
838 \\ERROR: illegal char '\\' at position 1: incomplete_escape
866839 );
867840 try depTokenizer("\n\\",
868 \\ERROR: illegal char '\' at position 1: incomplete escape
841 \\ERROR: illegal char '\\' at position 1: incomplete_escape
869842 );
870843 try depTokenizer("\r\\",
871 \\ERROR: illegal char '\' at position 1: incomplete escape
844 \\ERROR: illegal char '\\' at position 1: incomplete_escape
872845 );
873846 try depTokenizer("\r\n\\",
874 \\ERROR: illegal char '\' at position 2: incomplete escape
847 \\ERROR: illegal char '\\' at position 2: incomplete_escape
875848 );
876849 try depTokenizer(" \\",
877 \\ERROR: illegal char '\' at position 1: incomplete escape
850 \\ERROR: illegal char '\\' at position 1: incomplete_escape
878851 );
879852}
880853
881854test "error incomplete escape - dollar_sign" {
882855 try depTokenizer("$",
883 \\ERROR: illegal char '$' at position 0: incomplete escape
856 \\ERROR: illegal char '$' at position 0: incomplete_escape
884857 );
885858 try depTokenizer("\t$",
886 \\ERROR: illegal char '$' at position 1: incomplete escape
859 \\ERROR: illegal char '$' at position 1: incomplete_escape
887860 );
888861 try depTokenizer("\n$",
889 \\ERROR: illegal char '$' at position 1: incomplete escape
862 \\ERROR: illegal char '$' at position 1: incomplete_escape
890863 );
891864 try depTokenizer("\r$",
892 \\ERROR: illegal char '$' at position 1: incomplete escape
865 \\ERROR: illegal char '$' at position 1: incomplete_escape
893866 );
894867 try depTokenizer("\r\n$",
895 \\ERROR: illegal char '$' at position 2: incomplete escape
868 \\ERROR: illegal char '$' at position 2: incomplete_escape
896869 );
897870 try depTokenizer(" $",
898 \\ERROR: illegal char '$' at position 1: incomplete escape
871 \\ERROR: illegal char '$' at position 1: incomplete_escape
899872 );
900873}
901874
902875test "error incomplete target" {
903876 try depTokenizer("foo.o",
904 \\ERROR: incomplete target 'foo.o' at position 0
877 \\ERROR: incomplete_target "foo.o" at position 0
905878 );
906879 try depTokenizer("\tfoo.o",
907 \\ERROR: incomplete target 'foo.o' at position 1
880 \\ERROR: incomplete_target "foo.o" at position 1
908881 );
909882 try depTokenizer("\nfoo.o",
910 \\ERROR: incomplete target 'foo.o' at position 1
883 \\ERROR: incomplete_target "foo.o" at position 1
911884 );
912885 try depTokenizer("\rfoo.o",
913 \\ERROR: incomplete target 'foo.o' at position 1
886 \\ERROR: incomplete_target "foo.o" at position 1
914887 );
915888 try depTokenizer("\r\nfoo.o",
916 \\ERROR: incomplete target 'foo.o' at position 2
889 \\ERROR: incomplete_target "foo.o" at position 2
917890 );
918891 try depTokenizer(" foo.o",
919 \\ERROR: incomplete target 'foo.o' at position 1
892 \\ERROR: incomplete_target "foo.o" at position 1
920893 );
921894
922895 try depTokenizer("\\ foo.o",
923 \\ERROR: incomplete target ' foo.o' at position 0
896 \\ERROR: incomplete_target "\\ foo.o" at position 0
924897 );
925898 try depTokenizer("\\#foo.o",
926 \\ERROR: incomplete target '#foo.o' at position 0
899 \\ERROR: incomplete_target "\\#foo.o" at position 0
927900 );
928901 try depTokenizer("\\\\foo.o",
929 \\ERROR: incomplete target '\foo.o' at position 0
902 \\ERROR: incomplete_target "\\\\foo.o" at position 0
930903 );
931904 try depTokenizer("$$foo.o",
932 \\ERROR: incomplete target '$foo.o' at position 0
905 \\ERROR: incomplete_target "$$foo.o" at position 0
933906 );
934907}
935908
936909test "error illegal char at position - bad target escape" {
937910 try depTokenizer("\\\t",
938 \\ERROR: illegal char \x09 at position 1: bad target escape
911 \\ERROR: illegal char '\t' at position 1: bad_target_escape
939912 );
940913 try depTokenizer("\\\n",
941 \\ERROR: illegal char \x0A at position 1: bad target escape
914 \\ERROR: illegal char '\n' at position 1: bad_target_escape
942915 );
943916 try depTokenizer("\\\r",
944 \\ERROR: illegal char \x0D at position 1: bad target escape
917 \\ERROR: illegal char '\r' at position 1: bad_target_escape
945918 );
946919 try depTokenizer("\\\r\n",
947 \\ERROR: illegal char \x0D at position 1: bad target escape
920 \\ERROR: illegal char '\r' at position 1: bad_target_escape
948921 );
949922}
950923
951924test "error illegal char at position - expecting dollar_sign" {
952925 try depTokenizer("$\t",
953 \\ERROR: illegal char \x09 at position 1: expecting '$'
926 \\ERROR: illegal char '\t' at position 1: expected_dollar
954927 );
955928 try depTokenizer("$\n",
956 \\ERROR: illegal char \x0A at position 1: expecting '$'
929 \\ERROR: illegal char '\n' at position 1: expected_dollar
957930 );
958931 try depTokenizer("$\r",
959 \\ERROR: illegal char \x0D at position 1: expecting '$'
932 \\ERROR: illegal char '\r' at position 1: expected_dollar
960933 );
961934 try depTokenizer("$\r\n",
962 \\ERROR: illegal char \x0D at position 1: expecting '$'
935 \\ERROR: illegal char '\r' at position 1: expected_dollar
963936 );
964937}
965938
966939test "error illegal char at position - invalid target" {
967940 try depTokenizer("foo\n.o",
968 \\ERROR: illegal char \x0A at position 3: invalid target
941 \\ERROR: illegal char '\n' at position 3: invalid_target
969942 );
970943 try depTokenizer("foo\r.o",
971 \\ERROR: illegal char \x0D at position 3: invalid target
944 \\ERROR: illegal char '\r' at position 3: invalid_target
972945 );
973946 try depTokenizer("foo\r\n.o",
974 \\ERROR: illegal char \x0D at position 3: invalid target
947 \\ERROR: illegal char '\r' at position 3: invalid_target
975948 );
976949}
977950
978951test "error target - continuation expecting end-of-line" {
979952 try depTokenizer("foo.o: \\\t",
980 \\target = {foo.o}
981 \\ERROR: illegal char \x09 at position 8: continuation expecting end-of-line
953 \\target = {"foo.o"}
954 \\ERROR: illegal char '\t' at position 8: continuation_eol
982955 );
983956 try depTokenizer("foo.o: \\ ",
984 \\target = {foo.o}
985 \\ERROR: illegal char ' ' at position 8: continuation expecting end-of-line
957 \\target = {"foo.o"}
958 \\ERROR: illegal char ' ' at position 8: continuation_eol
986959 );
987960 try depTokenizer("foo.o: \\x",
988 \\target = {foo.o}
989 \\ERROR: illegal char 'x' at position 8: continuation expecting end-of-line
961 \\target = {"foo.o"}
962 \\ERROR: illegal char 'x' at position 8: continuation_eol
990963 );
991964 try depTokenizer("foo.o: \\\x0dx",
992 \\target = {foo.o}
993 \\ERROR: illegal char 'x' at position 9: continuation expecting end-of-line
965 \\target = {"foo.o"}
966 \\ERROR: illegal char 'x' at position 9: continuation_eol
994967 );
995968}
996969
997970test "error prereq - continuation expecting end-of-line" {
998971 try depTokenizer("foo.o: foo.h\\\x0dx",
999 \\target = {foo.o}
1000 \\ERROR: illegal char 'x' at position 14: continuation expecting end-of-line
972 \\target = {"foo.o"}
973 \\ERROR: illegal char 'x' at position 14: continuation_eol
1001974 );
1002975}
1003976
1004977test "error illegal char at position - expecting colon" {
1005978 try depTokenizer("foo\t.o:",
1006 \\target = {foo}
1007 \\ERROR: illegal char '.' at position 4: expecting ':'
979 \\target = {"foo"}
980 \\ERROR: illegal char '.' at position 4: expected_colon
1008981 );
1009982 try depTokenizer("foo .o:",
1010 \\target = {foo}
1011 \\ERROR: illegal char '.' at position 4: expecting ':'
983 \\target = {"foo"}
984 \\ERROR: illegal char '.' at position 4: expected_colon
1012985 );
1013986 try depTokenizer("foo \n.o:",
1014 \\target = {foo}
1015 \\ERROR: illegal char \x0A at position 4: expecting ':'
987 \\target = {"foo"}
988 \\ERROR: illegal char '\n' at position 4: expected_colon
1016989 );
1017990 try depTokenizer("foo.o\t\n:",
1018 \\target = {foo.o}
1019 \\ERROR: illegal char \x0A at position 6: expecting ':'
991 \\target = {"foo.o"}
992 \\ERROR: illegal char '\n' at position 6: expected_colon
1020993 );
1021994}
1022995
......@@ -1028,70 +1001,35 @@ fn depTokenizer(input: []const u8, expect: []const u8) !void {
10281001
10291002 var it: Tokenizer = .{ .bytes = input };
10301003 var buffer: std.ArrayList(u8) = .empty;
1031 var resolve_buf: std.ArrayList(u8) = .empty;
1004 var aux: std.ArrayList(u8) = .empty;
10321005 var i: usize = 0;
10331006 while (it.next()) |token| {
10341007 if (i != 0) try buffer.appendSlice(arena, "\n");
10351008 switch (token) {
10361009 .target, .prereq => |bytes| {
1037 try buffer.appendSlice(arena, @tagName(token));
1038 try buffer.appendSlice(arena, " = {");
1039 for (bytes) |b| {
1040 try buffer.append(arena, printable_char_tab[b]);
1041 }
1042 try buffer.appendSlice(arena, "}");
1010 try buffer.print(arena, "{t} = {{{q}}}", .{ token, bytes });
10431011 },
10441012 .target_must_resolve => {
10451013 try buffer.appendSlice(arena, "target = {");
1046 try token.resolve(arena, &resolve_buf);
1047 for (resolve_buf.items) |b| {
1048 try buffer.append(arena, printable_char_tab[b]);
1049 }
1050 resolve_buf.items.len = 0;
1014 aux.clearRetainingCapacity();
1015 try token.resolve(arena, &aux);
1016 try buffer.print(arena, "{q}", .{aux.items});
10511017 try buffer.appendSlice(arena, "}");
10521018 },
10531019 .prereq_must_resolve => {
10541020 try buffer.appendSlice(arena, "prereq = {");
1055 try token.resolve(arena, &resolve_buf);
1056 for (resolve_buf.items) |b| {
1057 try buffer.append(arena, printable_char_tab[b]);
1058 }
1059 resolve_buf.items.len = 0;
1021 aux.clearRetainingCapacity();
1022 try token.resolve(arena, &aux);
1023 try buffer.print(arena, "{q}", .{aux.items});
10601024 try buffer.appendSlice(arena, "}");
10611025 },
10621026 else => {
1063 try buffer.appendSlice(arena, "ERROR: ");
1064 try token.printError(arena, &buffer);
1027 try buffer.print(arena, "ERROR: {f}", .{token});
10651028 break;
10661029 },
10671030 }
10681031 i += 1;
10691032 }
10701033
1071 if (std.mem.eql(u8, expect, buffer.items)) {
1072 try testing.expect(true);
1073 return;
1074 }
1075
10761034 try testing.expectEqualStrings(expect, buffer.items);
10771035}
1078
1079fn printCharValues(gpa: Allocator, list: *std.ArrayList(u8), bytes: []const u8) !void {
1080 for (bytes) |b| try list.append(gpa, printable_char_tab[b]);
1081}
1082
1083fn printUnderstandableChar(gpa: Allocator, list: *std.ArrayList(u8), char: u8) !void {
1084 if (std.ascii.isPrint(char)) {
1085 try list.print(gpa, "'{c}'", .{char});
1086 } else {
1087 try list.print(gpa, "\\x{X:0>2}", .{char});
1088 }
1089}
1090
1091// zig fmt: off
1092const printable_char_tab: [256]u8 = (
1093 "................................ !\"#$%&'()*+,-./0123456789:;<=>?" ++
1094 "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~." ++
1095 "................................................................" ++
1096 "................................................................"
1097).*;
src/Compilation.zig+36-15
......@@ -5094,9 +5094,13 @@ pub fn translateC(
50945094 try @import("main.zig").translateC(gpa, arena, io, argv.items, environ_map, prog_node, comp.thread_limit, &stdout);
50955095
50965096 if (out_dep_path) |dep_file_path| add_deps: {
5097 var diagnostic: Cache.Manifest.AddDiscoveredDepFileDiagnostic = undefined;
50975098 const dep_basename = fs.path.basename(dep_file_path);
50985099 // Add the files depended on to the cache system, if a dep file was emitted
5099 man.addDepFilePost(cache_tmp_dir, dep_basename) catch |err| switch (err) {
5100 man.addDiscoveredDepFile(.{
5101 .root_dir = .{ .handle = cache_tmp_dir, .path = tmp_sub_path },
5102 .sub_path = dep_basename,
5103 }, &diagnostic) catch |err| switch (err) {
51005104 error.FileNotFound => break :add_deps,
51015105 else => |e| return e,
51025106 };
......@@ -5105,14 +5109,17 @@ pub fn translateC(
51055109 .whole => |whole| if (whole.cache_manifest) |whole_cache_manifest| {
51065110 try whole.cache_manifest_mutex.lock(io);
51075111 defer whole.cache_manifest_mutex.unlock(io);
5108 try whole_cache_manifest.addDepFilePost(cache_tmp_dir, dep_basename);
5112 try whole_cache_manifest.addDiscoveredDepFile(.{
5113 .root_dir = .{ .handle = cache_tmp_dir, .path = tmp_sub_path },
5114 .sub_path = dep_basename,
5115 }, &diagnostic);
51095116 },
51105117 .incremental, .none => {},
51115118 }
51125119
51135120 // Just to save disk space, we delete the file because it is never needed again.
51145121 cache_tmp_dir.deleteFile(io, dep_basename) catch |err| {
5115 log.warn("failed to delete '{s}': {t}", .{ dep_file_path, err });
5122 log.warn("failed to delete dep file {q}: {t}", .{ dep_file_path, err });
51165123 };
51175124 }
51185125
......@@ -5527,7 +5534,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr
55275534 const target = comp.getTarget();
55285535 assert(target.ofmt != .c);
55295536 const o_ext = target.ofmt.fileExt(target.cpu.arch);
5530 const digest = if (!comp.disable_c_depfile and try man.check(child_progress_node)) man.final() else blk: {
5537 const digest = if (!comp.disable_c_depfile and .hit == try man.check(child_progress_node)) man.hitDigestHex() else miss: {
55315538 var argv: std.array_list.Managed([]const u8) = .init(gpa);
55325539 defer argv.deinit();
55335540
......@@ -5654,11 +5661,11 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr
56545661 // Just to save disk space, we delete the files that are never needed again.
56555662 defer if (out_diag_path) |diag_file_path| zig_cache_tmp_dir.deleteFile(io, fs.path.basename(diag_file_path)) catch |err| switch (err) {
56565663 error.FileNotFound => {}, // the file wasn't created due to an error we reported
5657 else => log.warn("failed to delete '{s}': {s}", .{ diag_file_path, @errorName(err) }),
5664 else => log.warn("failed to delete {q}: {t}", .{ diag_file_path, err }),
56585665 };
56595666 defer if (out_dep_path) |dep_file_path| zig_cache_tmp_dir.deleteFile(io, fs.path.basename(dep_file_path)) catch |err| switch (err) {
56605667 error.FileNotFound => {}, // the file wasn't created due to an error we reported
5661 else => log.warn("failed to delete '{s}': {s}", .{ dep_file_path, @errorName(err) }),
5668 else => log.warn("failed to delete {q}: {t}", .{ dep_file_path, err }),
56625669 };
56635670 if (std.process.can_spawn) {
56645671 if (comp.clang_passthrough_mode) {
......@@ -5747,8 +5754,10 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr
57475754 const dep_basename = fs.path.basename(dep_file_path);
57485755
57495756 if (comp.file_system_inputs != null) {
5757 // TODO instead of this rely on passing the manifest contents directly
5758
57505759 // Use the same file size limit as the cache code does for dependency files.
5751 const dep_file_contents = try zig_cache_tmp_dir.readFileAlloc(io, dep_basename, gpa, .limited(Cache.manifest_file_size_max));
5760 const dep_file_contents = try zig_cache_tmp_dir.readFileAlloc(io, dep_basename, gpa, .unlimited);
57525761 defer gpa.free(dep_file_contents);
57535762
57545763 var str_buf: std.ArrayList(u8) = .empty;
......@@ -5763,9 +5772,8 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr
57635772 try token.resolve(gpa, &str_buf);
57645773 break :p try .fromUnresolved(arena, comp.dirs, &.{str_buf.items});
57655774 },
5766 else => |err| {
5767 try err.printError(gpa, &str_buf);
5768 log.err("failed parsing {s}: {s}", .{ dep_basename, str_buf.items });
5775 else => |err_token| {
5776 log.err("failed parsing {s}: {f}", .{ dep_basename, err_token });
57695777 return error.InvalidDepFile;
57705778 },
57715779 };
......@@ -5774,13 +5782,26 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr
57745782 }
57755783
57765784 // Add the files depended on to the cache system.
5777 try man.addDepFilePost(zig_cache_tmp_dir, dep_basename);
5785 var diagnostic: Cache.Manifest.AddDiscoveredDepFileDiagnostic = undefined;
5786 try man.addDiscoveredDepFile(.{
5787 .root_dir = .{
5788 .handle = zig_cache_tmp_dir,
5789 .path = "tmp",
5790 },
5791 .sub_path = dep_basename,
5792 }, &diagnostic);
57785793 switch (comp.cache_use) {
57795794 .whole => |whole| {
57805795 if (whole.cache_manifest) |whole_cache_manifest| {
57815796 try whole.cache_manifest_mutex.lock(io);
57825797 defer whole.cache_manifest_mutex.unlock(io);
5783 try whole_cache_manifest.addDepFilePost(zig_cache_tmp_dir, dep_basename);
5798 try whole_cache_manifest.addDiscoveredDepFile(.{
5799 .root_dir = .{
5800 .handle = zig_cache_tmp_dir,
5801 .path = "tmp",
5802 },
5803 .sub_path = dep_basename,
5804 }, &diagnostic);
57845805 }
57855806 },
57865807 .incremental, .none => {},
......@@ -5791,13 +5812,13 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr
57915812 if (comp.disable_c_depfile) _ = try man.check(child_progress_node);
57925813
57935814 // Rename into place.
5794 const digest = man.final();
5795 const o_sub_path = try fs.path.join(arena, &[_][]const u8{ "o", &digest });
5815 const digest = man.missDigestHex();
5816 const o_sub_path = try fs.path.join(arena, &.{ "o", &digest });
57965817 var o_dir = try comp.dirs.local_cache.handle.createDirPathOpen(io, o_sub_path, .{});
57975818 defer o_dir.close(io);
57985819 const tmp_basename = fs.path.basename(out_obj_path);
57995820 try Io.Dir.rename(zig_cache_tmp_dir, tmp_basename, o_dir, o_basename, io);
5800 break :blk digest;
5821 break :miss digest;
58015822 };
58025823
58035824 if (man.have_exclusive_lock) {
src/libs/freebsd.zig+4-5
......@@ -465,9 +465,8 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
465465 .request_contents = true,
466466 });
467467
468 if (try man.check(prog_node)) {
469 const digest = man.final();
470
468 if (.hit == try man.check(prog_node)) {
469 const digest = man.hitDigestHex();
471470 return queueSharedObjects(comp, .{
472471 .lock = man.toOwnedLock(),
473472 .dir_path = .{
......@@ -477,7 +476,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
477476 });
478477 }
479478
480 const digest = man.final();
479 const digest = man.missDigestHex();
481480 const o_sub_path = try path.join(arena, &[_][]const u8{ "o", &digest });
482481
483482 var o_directory: Cache.Directory = .{
......@@ -486,7 +485,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
486485 };
487486 defer o_directory.handle.close(io);
488487
489 const abilists_contents = man.files.keys()[abilists_index].contents.?;
488 const abilists_contents = abilists_index.contents(&man);
490489 const metadata = try loadMetaData(gpa, abilists_contents);
491490 defer metadata.destroy(gpa);
492491
src/libs/glibc.zig+5-6
......@@ -705,9 +705,8 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
705705 .request_contents = true,
706706 });
707707
708 if (try man.check(prog_node)) {
709 const digest = man.final();
710
708 if (.hit == try man.check(prog_node)) {
709 const digest = man.hitDigestHex();
711710 return queueSharedObjects(comp, .{
712711 .lock = man.toOwnedLock(),
713712 .dir_path = .{
......@@ -717,8 +716,8 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
717716 });
718717 }
719718
720 const digest = man.final();
721 const o_sub_path = try path.join(arena, &[_][]const u8{ "o", &digest });
719 const digest = man.missDigestHex();
720 const o_sub_path = try path.join(arena, &.{ "o", &digest });
722721
723722 var o_directory: Cache.Directory = .{
724723 .handle = try comp.dirs.global_cache.handle.createDirPathOpen(io, o_sub_path, .{}),
......@@ -726,7 +725,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
726725 };
727726 defer o_directory.handle.close(io);
728727
729 const abilists_contents = man.files.keys()[abilists_index].contents.?;
728 const abilists_contents = abilists_index.contents(&man);
730729 const metadata = try loadMetaData(gpa, abilists_contents);
731730 defer metadata.destroy(gpa);
732731
src/libs/netbsd.zig+5-6
......@@ -413,9 +413,8 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
413413 .request_contents = true,
414414 });
415415
416 if (try man.check(prog_node)) {
417 const digest = man.final();
418
416 if (.hit == try man.check(prog_node)) {
417 const digest = man.hitDigestHex();
419418 return queueSharedObjects(comp, .{
420419 .lock = man.toOwnedLock(),
421420 .dir_path = .{
......@@ -425,8 +424,8 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
425424 });
426425 }
427426
428 const digest = man.final();
429 const o_sub_path = try path.join(arena, &[_][]const u8{ "o", &digest });
427 const digest = man.missDigestHex();
428 const o_sub_path = try path.join(arena, &.{ "o", &digest });
430429
431430 var o_directory: Cache.Directory = .{
432431 .handle = try comp.dirs.global_cache.handle.createDirPathOpen(io, o_sub_path, .{}),
......@@ -434,7 +433,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
434433 };
435434 defer o_directory.handle.close(io);
436435
437 const abilists_contents = man.files.keys()[abilists_index].contents.?;
436 const abilists_contents = abilists_index.contents(&man);
438437 const metadata = try loadMetaData(gpa, abilists_contents);
439438 defer metadata.destroy(gpa);
440439
src/libs/openbsd.zig+4-5
......@@ -334,9 +334,8 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
334334 .request_contents = true,
335335 });
336336
337 if (try man.check(prog_node)) {
338 const digest = man.final();
339
337 if (.hit == try man.check(prog_node)) {
338 const digest = man.hitDigestHex();
340339 return queueSharedObjects(comp, .{
341340 .lock = man.toOwnedLock(),
342341 .dir_path = .{
......@@ -346,7 +345,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
346345 });
347346 }
348347
349 const digest = man.final();
348 const digest = man.missDigestHex();
350349 const o_sub_path = try path.join(arena, &[_][]const u8{ "o", &digest });
351350
352351 var o_directory: Cache.Directory = .{
......@@ -355,7 +354,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
355354 };
356355 defer o_directory.handle.close(io);
357356
358 const abilists_contents = man.files.keys()[abilists_index].contents.?;
357 const abilists_contents = abilists_index.contents(&man);
359358 const metadata = try loadMetaData(gpa, abilists_contents);
360359 defer metadata.destroy(gpa);
361360