| ... | @@ -485,42 +485,49 @@ pub const File = struct { | ... | @@ -485,42 +485,49 @@ pub const File = struct { |
| 485 | | 485 | |
| 486 | const id_symlink_basename = "llvm-ar.id"; | 486 | const id_symlink_basename = "llvm-ar.id"; |
| 487 | | 487 | |
| 488 | base.releaseLock(); | 488 | var man: Cache.Manifest = undefined; |
| | 489 | defer if (!base.options.disable_lld_caching) man.deinit(); |
| 489 | | 490 | |
| 490 | var ch = comp.cache_parent.obtain(); | 491 | var digest: [Cache.hex_digest_len]u8 = undefined; |
| 491 | defer ch.deinit(); | | |
| 492 | | 492 | |
| 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 | } | | |
| 518 | | 495 | |
| 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 | } |
| 524 | | 531 | |
| 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; |
| 557 | | 564 | |
| 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 | }; |
| 561 | | 569 | |
| 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 | }; |
| 565 | | 573 | |
| 566 | base.lock = ch.toOwnedLock(); | 574 | base.lock = man.toOwnedLock(); |
| | 575 | } |
| 567 | } | 576 | } |
| 568 | | 577 | |
| 569 | pub const Tag = enum { | 578 | pub const Tag = enum { |