authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-12-02 16:37:32-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-12-02 16:37:32-07:00
log41387e1822d5eff75ec88681c14e1f0c7f181af5
tree654e0059a1c083bf22b8eb8316067f58e523564c
parent6d91ebce45cf069376ab2cd2de24ddb838698f09

stage2: linkAsArchive: respect disable_lld_caching

Closes #7274 Closes #6943

1 files changed, 49 insertions(+), 40 deletions(-)

src/link.zig+49-40
...@@ -485,42 +485,49 @@ pub const File = struct {...@@ -485,42 +485,49 @@ pub const File = struct {
485485
486 const id_symlink_basename = "llvm-ar.id";486 const id_symlink_basename = "llvm-ar.id";
487487
488 base.releaseLock();488 var man: Cache.Manifest = undefined;
489 defer if (!base.options.disable_lld_caching) man.deinit();
489490
490 var ch = comp.cache_parent.obtain();491 var digest: [Cache.hex_digest_len]u8 = undefined;
491 defer ch.deinit();
492492
493 try ch.addListOfFiles(base.options.objects);493 if (!base.options.disable_lld_caching) {
494 for (comp.c_object_table.items()) |entry| {494 man = comp.cache_parent.obtain();
495 _ = try ch.addFile(entry.key.status.success.object_path, null);
496 }
497 try ch.addOptionalFile(module_obj_path);
498 try ch.addOptionalFile(compiler_rt_path);
499
500 // We don't actually care whether it's a cache hit or miss; we just need the digest and the lock.
501 _ = try ch.hit();
502 const digest = ch.final();
503
504 var prev_digest_buf: [digest.len]u8 = undefined;
505 const prev_digest: []u8 = Cache.readSmallFile(
506 directory.handle,
507 id_symlink_basename,
508 &prev_digest_buf,
509 ) catch |err| b: {
510 log.debug("archive new_digest={} readFile error: {}", .{ digest, @errorName(err) });
511 break :b prev_digest_buf[0..0];
512 };
513 if (mem.eql(u8, prev_digest, &digest)) {
514 log.debug("archive digest={} match - skipping invocation", .{digest});
515 base.lock = ch.toOwnedLock();
516 return;
517 }
518495
519 // We are about to change the output file to be different, so we invalidate the build hash now.496 // We are about to obtain this lock, so here we give other processes a chance first.
520 directory.handle.deleteFile(id_symlink_basename) catch |err| switch (err) {497 base.releaseLock();
521 error.FileNotFound => {},498
522 else => |e| return e,499 try man.addListOfFiles(base.options.objects);
523 };500 for (comp.c_object_table.items()) |entry| {
501 _ = try man.addFile(entry.key.status.success.object_path, null);
502 }
503 try man.addOptionalFile(module_obj_path);
504 try man.addOptionalFile(compiler_rt_path);
505
506 // We don't actually care whether it's a cache hit or miss; we just need the digest and the lock.
507 _ = try man.hit();
508 digest = man.final();
509
510 var prev_digest_buf: [digest.len]u8 = undefined;
511 const prev_digest: []u8 = Cache.readSmallFile(
512 directory.handle,
513 id_symlink_basename,
514 &prev_digest_buf,
515 ) catch |err| b: {
516 log.debug("archive new_digest={} readFile error: {}", .{ digest, @errorName(err) });
517 break :b prev_digest_buf[0..0];
518 };
519 if (mem.eql(u8, prev_digest, &digest)) {
520 log.debug("archive digest={} match - skipping invocation", .{digest});
521 base.lock = man.toOwnedLock();
522 return;
523 }
524
525 // We are about to change the output file to be different, so we invalidate the build hash now.
526 directory.handle.deleteFile(id_symlink_basename) catch |err| switch (err) {
527 error.FileNotFound => {},
528 else => |e| return e,
529 };
530 }
524531
525 var object_files = std.ArrayList([*:0]const u8).init(base.allocator);532 var object_files = std.ArrayList([*:0]const u8).init(base.allocator);
526 defer object_files.deinit();533 defer object_files.deinit();
...@@ -555,15 +562,17 @@ pub const File = struct {...@@ -555,15 +562,17 @@ pub const File = struct {
555 const bad = llvm.WriteArchive(full_out_path_z, object_files.items.ptr, object_files.items.len, os_type);562 const bad = llvm.WriteArchive(full_out_path_z, object_files.items.ptr, object_files.items.len, os_type);
556 if (bad) return error.UnableToWriteArchive;563 if (bad) return error.UnableToWriteArchive;
557564
558 Cache.writeSmallFile(directory.handle, id_symlink_basename, &digest) catch |err| {565 if (!base.options.disable_lld_caching) {
559 std.log.warn("failed to save archive hash digest file: {}", .{@errorName(err)});566 Cache.writeSmallFile(directory.handle, id_symlink_basename, &digest) catch |err| {
560 };567 std.log.warn("failed to save archive hash digest file: {}", .{@errorName(err)});
568 };
561569
562 ch.writeManifest() catch |err| {570 man.writeManifest() catch |err| {
563 std.log.warn("failed to write cache manifest when archiving: {}", .{@errorName(err)});571 std.log.warn("failed to write cache manifest when archiving: {}", .{@errorName(err)});
564 };572 };
565573
566 base.lock = ch.toOwnedLock();574 base.lock = man.toOwnedLock();
575 }
567 }576 }
568577
569 pub const Tag = enum {578 pub const Tag = enum {