| ... | ... | @@ -462,42 +462,49 @@ pub const File = struct { |
| 462 | 462 | |
| 463 | 463 | const id_symlink_basename = "llvm-ar.id"; |
| 464 | 464 | |
| 465 | | base.releaseLock(); |
| 465 | var man: Cache.Manifest = undefined; |
| 466 | defer if (!base.options.disable_lld_caching) man.deinit(); |
| 466 | 467 | |
| 467 | | var ch = comp.cache_parent.obtain(); |
| 468 | | defer ch.deinit(); |
| 468 | var digest: [Cache.hex_digest_len]u8 = undefined; |
| 469 | 469 | |
| 470 | | try ch.addListOfFiles(base.options.objects); |
| 471 | | for (comp.c_object_table.items()) |entry| { |
| 472 | | _ = try ch.addFile(entry.key.status.success.object_path, null); |
| 473 | | } |
| 474 | | try ch.addOptionalFile(module_obj_path); |
| 475 | | try ch.addOptionalFile(compiler_rt_path); |
| 476 | | |
| 477 | | // We don't actually care whether it's a cache hit or miss; we just need the digest and the lock. |
| 478 | | _ = try ch.hit(); |
| 479 | | const digest = ch.final(); |
| 480 | | |
| 481 | | var prev_digest_buf: [digest.len]u8 = undefined; |
| 482 | | const prev_digest: []u8 = Cache.readSmallFile( |
| 483 | | directory.handle, |
| 484 | | id_symlink_basename, |
| 485 | | &prev_digest_buf, |
| 486 | | ) catch |err| b: { |
| 487 | | log.debug("archive new_digest={} readFile error: {}", .{ digest, @errorName(err) }); |
| 488 | | break :b prev_digest_buf[0..0]; |
| 489 | | }; |
| 490 | | if (mem.eql(u8, prev_digest, &digest)) { |
| 491 | | log.debug("archive digest={} match - skipping invocation", .{digest}); |
| 492 | | base.lock = ch.toOwnedLock(); |
| 493 | | return; |
| 494 | | } |
| 470 | if (!base.options.disable_lld_caching) { |
| 471 | man = comp.cache_parent.obtain(); |
| 495 | 472 | |
| 496 | | // We are about to change the output file to be different, so we invalidate the build hash now. |
| 497 | | directory.handle.deleteFile(id_symlink_basename) catch |err| switch (err) { |
| 498 | | error.FileNotFound => {}, |
| 499 | | else => |e| return e, |
| 500 | | }; |
| 473 | // We are about to obtain this lock, so here we give other processes a chance first. |
| 474 | base.releaseLock(); |
| 475 | |
| 476 | try man.addListOfFiles(base.options.objects); |
| 477 | for (comp.c_object_table.items()) |entry| { |
| 478 | _ = try man.addFile(entry.key.status.success.object_path, null); |
| 479 | } |
| 480 | try man.addOptionalFile(module_obj_path); |
| 481 | try man.addOptionalFile(compiler_rt_path); |
| 482 | |
| 483 | // We don't actually care whether it's a cache hit or miss; we just need the digest and the lock. |
| 484 | _ = try man.hit(); |
| 485 | digest = man.final(); |
| 486 | |
| 487 | var prev_digest_buf: [digest.len]u8 = undefined; |
| 488 | const prev_digest: []u8 = Cache.readSmallFile( |
| 489 | directory.handle, |
| 490 | id_symlink_basename, |
| 491 | &prev_digest_buf, |
| 492 | ) catch |err| b: { |
| 493 | log.debug("archive new_digest={} readFile error: {}", .{ digest, @errorName(err) }); |
| 494 | break :b prev_digest_buf[0..0]; |
| 495 | }; |
| 496 | if (mem.eql(u8, prev_digest, &digest)) { |
| 497 | log.debug("archive digest={} match - skipping invocation", .{digest}); |
| 498 | base.lock = man.toOwnedLock(); |
| 499 | return; |
| 500 | } |
| 501 | |
| 502 | // We are about to change the output file to be different, so we invalidate the build hash now. |
| 503 | directory.handle.deleteFile(id_symlink_basename) catch |err| switch (err) { |
| 504 | error.FileNotFound => {}, |
| 505 | else => |e| return e, |
| 506 | }; |
| 507 | } |
| 501 | 508 | |
| 502 | 509 | var object_files = std.ArrayList([*:0]const u8).init(base.allocator); |
| 503 | 510 | defer object_files.deinit(); |
| ... | ... | @@ -532,15 +539,17 @@ pub const File = struct { |
| 532 | 539 | const bad = llvm.WriteArchive(full_out_path_z, object_files.items.ptr, object_files.items.len, os_type); |
| 533 | 540 | if (bad) return error.UnableToWriteArchive; |
| 534 | 541 | |
| 535 | | Cache.writeSmallFile(directory.handle, id_symlink_basename, &digest) catch |err| { |
| 536 | | std.log.warn("failed to save archive hash digest file: {}", .{@errorName(err)}); |
| 537 | | }; |
| 542 | if (!base.options.disable_lld_caching) { |
| 543 | Cache.writeSmallFile(directory.handle, id_symlink_basename, &digest) catch |err| { |
| 544 | std.log.warn("failed to save archive hash digest file: {}", .{@errorName(err)}); |
| 545 | }; |
| 538 | 546 | |
| 539 | | ch.writeManifest() catch |err| { |
| 540 | | std.log.warn("failed to write cache manifest when archiving: {}", .{@errorName(err)}); |
| 541 | | }; |
| 547 | man.writeManifest() catch |err| { |
| 548 | std.log.warn("failed to write cache manifest when archiving: {}", .{@errorName(err)}); |
| 549 | }; |
| 542 | 550 | |
| 543 | | base.lock = ch.toOwnedLock(); |
| 551 | base.lock = man.toOwnedLock(); |
| 552 | } |
| 544 | 553 | } |
| 545 | 554 | |
| 546 | 555 | pub const Tag = enum { |