authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-10-09 16:49:05-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-10-09 16:49:05-07:00
logfbc6a00b0a939f8752bbd571284c46ab58a8fcc4
treef1543b917d9407611e014e1a79d26b0eed267621
parent04b0ffdd13e32be0ef5cc84983f8bb830db7520f
parent9f8f4464353460825856b848dfe2480de20d8d55

Merge branch 'mlarouche-Fix_6500'


8 files changed, 90 insertions(+), 29 deletions(-)

lib/std/fs.zig+13
......@@ -1490,6 +1490,19 @@ pub const Dir = struct {
14901490 return os.windows.ReadLink(self.fd, sub_path_w, buffer);
14911491 }
14921492
1493 /// Read all of file contents using a preallocated buffer.
1494 /// The returned slice has the same pointer as `buffer`. If the length matches `buffer.len`
1495 /// the situation is ambiguous. It could either mean that the entire file was read, and
1496 /// it exactly fits the buffer, or it could mean the buffer was not big enough for the
1497 /// entire file.
1498 pub fn readFile(self: Dir, file_path: []const u8, buffer: []u8) ![]u8 {
1499 var file = try self.openFile(file_path, .{});
1500 defer file.close();
1501
1502 const end_index = try file.readAll(buffer);
1503 return buffer[0..end_index];
1504 }
1505
14931506 /// On success, caller owns returned buffer.
14941507 /// If the file is larger than `max_bytes`, returns `error.FileTooBig`.
14951508 pub fn readFileAlloc(self: Dir, allocator: *mem.Allocator, file_path: []const u8, max_bytes: usize) ![]u8 {
src/Cache.zig+24
......@@ -576,6 +576,30 @@ pub const Manifest = struct {
576576 }
577577};
578578
579/// On operating systems that support symlinks, does a readlink. On other operating systems,
580/// uses the file contents. Windows supports symlinks but only with elevated privileges, so
581/// it is treated as not supporting symlinks.
582pub fn readSmallFile(dir: fs.Dir, sub_path: []const u8, buffer: []u8) ![]u8 {
583 if (std.Target.current.os.tag == .windows) {
584 return dir.readFile(sub_path, buffer);
585 } else {
586 return dir.readLink(sub_path, buffer);
587 }
588}
589
590/// On operating systems that support symlinks, does a symlink. On other operating systems,
591/// uses the file contents. Windows supports symlinks but only with elevated privileges, so
592/// it is treated as not supporting symlinks.
593/// `data` must be a valid UTF-8 encoded file path and 255 bytes or fewer.
594pub fn writeSmallFile(dir: fs.Dir, sub_path: []const u8, data: []const u8) !void {
595 assert(data.len <= 255);
596 if (std.Target.current.os.tag == .windows) {
597 return dir.writeFile(sub_path, data);
598 } else {
599 return dir.symLink(data, sub_path, .{});
600 }
601}
602
579603fn hashFile(file: fs.File, bin_digest: []u8) !void {
580604 var buf: [1024]u8 = undefined;
581605
src/Compilation.zig+10-6
......@@ -2605,8 +2605,12 @@ fn updateStage1Module(comp: *Compilation, main_progress_node: *std.Progress.Node
26052605
26062606 // We use an extra hex-encoded byte here to store some flags.
26072607 var prev_digest_buf: [digest.len + 2]u8 = undefined;
2608 const prev_digest: []u8 = directory.handle.readLink(id_symlink_basename, &prev_digest_buf) catch |err| blk: {
2609 log.debug("stage1 {} new_digest={} readlink error: {}", .{ mod.root_pkg.root_src_path, digest, @errorName(err) });
2608 const prev_digest: []u8 = Cache.readSmallFile(
2609 directory.handle,
2610 id_symlink_basename,
2611 &prev_digest_buf,
2612 ) catch |err| blk: {
2613 log.debug("stage1 {} new_digest={} error: {}", .{ mod.root_pkg.root_src_path, digest, @errorName(err) });
26102614 // Handle this as a cache miss.
26112615 break :blk prev_digest_buf[0..0];
26122616 };
......@@ -2777,7 +2781,7 @@ fn updateStage1Module(comp: *Compilation, main_progress_node: *std.Progress.Node
27772781
27782782 const digest = man.final();
27792783
2780 // Update the dangling symlink with the digest. If it fails we can continue; it only
2784 // Update the small file with the digest. If it fails we can continue; it only
27812785 // means that the next invocation will have an unnecessary cache miss.
27822786 const stage1_flags_byte = @bitCast(u8, mod.stage1_flags);
27832787 log.debug("stage1 {} final digest={} flags={x}", .{
......@@ -2792,10 +2796,10 @@ fn updateStage1Module(comp: *Compilation, main_progress_node: *std.Progress.Node
27922796 log.debug("saved digest + flags: '{s}' (byte = {}) have_winmain_crt_startup={}", .{
27932797 digest_plus_flags, stage1_flags_byte, mod.stage1_flags.have_winmain_crt_startup,
27942798 });
2795 directory.handle.symLink(&digest_plus_flags, id_symlink_basename, .{}) catch |err| {
2796 log.warn("failed to save stage1 hash digest symlink: {}", .{@errorName(err)});
2799 Cache.writeSmallFile(directory.handle, id_symlink_basename, &digest_plus_flags) catch |err| {
2800 log.warn("failed to save stage1 hash digest file: {}", .{@errorName(err)});
27972801 };
2798 // Again failure here only means an unnecessary cache miss.
2802 // Failure here only means an unnecessary cache miss.
27992803 man.writeManifest() catch |err| {
28002804 log.warn("failed to write cache manifest when linking: {}", .{@errorName(err)});
28012805 };
src/link.zig+8-4
......@@ -466,8 +466,12 @@ pub const File = struct {
466466 const digest = ch.final();
467467
468468 var prev_digest_buf: [digest.len]u8 = undefined;
469 const prev_digest: []u8 = directory.handle.readLink(id_symlink_basename, &prev_digest_buf) catch |err| b: {
470 log.debug("archive new_digest={} readlink error: {}", .{ digest, @errorName(err) });
469 const prev_digest: []u8 = Cache.readSmallFile(
470 directory.handle,
471 id_symlink_basename,
472 &prev_digest_buf,
473 ) catch |err| b: {
474 log.debug("archive new_digest={} readFile error: {}", .{ digest, @errorName(err) });
471475 break :b prev_digest_buf[0..0];
472476 };
473477 if (mem.eql(u8, prev_digest, &digest)) {
......@@ -512,8 +516,8 @@ pub const File = struct {
512516 const bad = llvm.WriteArchive(full_out_path_z, object_files.items.ptr, object_files.items.len, os_type);
513517 if (bad) return error.UnableToWriteArchive;
514518
515 directory.handle.symLink(&digest, id_symlink_basename, .{}) catch |err| {
516 std.log.warn("failed to save archive hash digest symlink: {}", .{@errorName(err)});
519 Cache.writeSmallFile(directory.handle, id_symlink_basename, &digest) catch |err| {
520 std.log.warn("failed to save archive hash digest file: {}", .{@errorName(err)});
517521 };
518522
519523 ch.writeManifest() catch |err| {
src/link/Coff.zig+9-5
......@@ -854,8 +854,12 @@ fn linkWithLLD(self: *Coff, comp: *Compilation) !void {
854854 _ = try man.hit();
855855 digest = man.final();
856856 var prev_digest_buf: [digest.len]u8 = undefined;
857 const prev_digest: []u8 = directory.handle.readLink(id_symlink_basename, &prev_digest_buf) catch |err| blk: {
858 log.debug("COFF LLD new_digest={} readlink error: {}", .{ digest, @errorName(err) });
857 const prev_digest: []u8 = Cache.readSmallFile(
858 directory.handle,
859 id_symlink_basename,
860 &prev_digest_buf,
861 ) catch |err| blk: {
862 log.debug("COFF LLD new_digest={} error: {}", .{ digest, @errorName(err) });
859863 // Handle this as a cache miss.
860864 break :blk prev_digest_buf[0..0];
861865 };
......@@ -1180,10 +1184,10 @@ fn linkWithLLD(self: *Coff, comp: *Compilation) !void {
11801184 }
11811185
11821186 if (!self.base.options.disable_lld_caching) {
1183 // Update the dangling symlink with the digest. If it fails we can continue; it only
1187 // Update the file with the digest. If it fails we can continue; it only
11841188 // means that the next invocation will have an unnecessary cache miss.
1185 directory.handle.symLink(&digest, id_symlink_basename, .{}) catch |err| {
1186 std.log.warn("failed to save linking hash digest symlink: {}", .{@errorName(err)});
1189 Cache.writeSmallFile(directory.handle, id_symlink_basename, &digest) catch |err| {
1190 std.log.warn("failed to save linking hash digest file: {}", .{@errorName(err)});
11871191 };
11881192 // Again failure here only means an unnecessary cache miss.
11891193 man.writeManifest() catch |err| {
src/link/Elf.zig+9-5
......@@ -1326,8 +1326,12 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
13261326 digest = man.final();
13271327
13281328 var prev_digest_buf: [digest.len]u8 = undefined;
1329 const prev_digest: []u8 = directory.handle.readLink(id_symlink_basename, &prev_digest_buf) catch |err| blk: {
1330 log.debug("ELF LLD new_digest={} readlink error: {}", .{ digest, @errorName(err) });
1329 const prev_digest: []u8 = Cache.readSmallFile(
1330 directory.handle,
1331 id_symlink_basename,
1332 &prev_digest_buf,
1333 ) catch |err| blk: {
1334 log.debug("ELF LLD new_digest={} error: {}", .{ digest, @errorName(err) });
13311335 // Handle this as a cache miss.
13321336 break :blk prev_digest_buf[0..0];
13331337 };
......@@ -1647,10 +1651,10 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
16471651 }
16481652
16491653 if (!self.base.options.disable_lld_caching) {
1650 // Update the dangling symlink with the digest. If it fails we can continue; it only
1654 // Update the file with the digest. If it fails we can continue; it only
16511655 // means that the next invocation will have an unnecessary cache miss.
1652 directory.handle.symLink(&digest, id_symlink_basename, .{}) catch |err| {
1653 std.log.warn("failed to save linking hash digest symlink: {}", .{@errorName(err)});
1656 Cache.writeSmallFile(directory.handle, id_symlink_basename, &digest) catch |err| {
1657 std.log.warn("failed to save linking hash digest file: {}", .{@errorName(err)});
16541658 };
16551659 // Again failure here only means an unnecessary cache miss.
16561660 man.writeManifest() catch |err| {
src/link/MachO.zig+9-5
......@@ -419,8 +419,12 @@ fn linkWithLLD(self: *MachO, comp: *Compilation) !void {
419419 digest = man.final();
420420
421421 var prev_digest_buf: [digest.len]u8 = undefined;
422 const prev_digest: []u8 = directory.handle.readLink(id_symlink_basename, &prev_digest_buf) catch |err| blk: {
423 log.debug("MachO LLD new_digest={} readlink error: {}", .{ digest, @errorName(err) });
422 const prev_digest: []u8 = Cache.readSmallFile(
423 directory.handle,
424 id_symlink_basename,
425 &prev_digest_buf,
426 ) catch |err| blk: {
427 log.debug("MachO LLD new_digest={} error: {}", .{ digest, @errorName(err) });
424428 // Handle this as a cache miss.
425429 break :blk prev_digest_buf[0..0];
426430 };
......@@ -674,10 +678,10 @@ fn linkWithLLD(self: *MachO, comp: *Compilation) !void {
674678 }
675679
676680 if (!self.base.options.disable_lld_caching) {
677 // Update the dangling symlink with the digest. If it fails we can continue; it only
681 // Update the file with the digest. If it fails we can continue; it only
678682 // means that the next invocation will have an unnecessary cache miss.
679 directory.handle.symLink(&digest, id_symlink_basename, .{}) catch |err| {
680 std.log.warn("failed to save linking hash digest symlink: {}", .{@errorName(err)});
683 Cache.writeSmallFile(directory.handle, id_symlink_basename, &digest) catch |err| {
684 std.log.warn("failed to save linking hash digest file: {}", .{@errorName(err)});
681685 };
682686 // Again failure here only means an unnecessary cache miss.
683687 man.writeManifest() catch |err| {
src/link/Wasm.zig+8-4
......@@ -310,8 +310,12 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation) !void {
310310 digest = man.final();
311311
312312 var prev_digest_buf: [digest.len]u8 = undefined;
313 const prev_digest: []u8 = directory.handle.readLink(id_symlink_basename, &prev_digest_buf) catch |err| blk: {
314 log.debug("WASM LLD new_digest={} readlink error: {}", .{ digest, @errorName(err) });
313 const prev_digest: []u8 = Cache.readSmallFile(
314 directory.handle,
315 id_symlink_basename,
316 &prev_digest_buf,
317 ) catch |err| blk: {
318 log.debug("WASM LLD new_digest={} error: {}", .{ digest, @errorName(err) });
315319 // Handle this as a cache miss.
316320 break :blk prev_digest_buf[0..0];
317321 };
......@@ -424,9 +428,9 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation) !void {
424428 }
425429
426430 if (!self.base.options.disable_lld_caching) {
427 // Update the dangling symlink with the digest. If it fails we can continue; it only
431 // Update the file with the digest. If it fails we can continue; it only
428432 // means that the next invocation will have an unnecessary cache miss.
429 directory.handle.symLink(&digest, id_symlink_basename, .{}) catch |err| {
433 Cache.writeSmallFile(directory.handle, id_symlink_basename, &digest) catch |err| {
430434 std.log.warn("failed to save linking hash digest symlink: {}", .{@errorName(err)});
431435 };
432436 // Again failure here only means an unnecessary cache miss.