authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-09-13 23:28:28-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-09-13 23:28:28-07:00
log060c91b97f25e22781f4b9e7c90bd0642594b722
treebab6cfff7d7f882915d7f879da276fde1c84f1f8
parent0379d7b4317e7e12d27b66f8a44a443d328ce539

stage2: namespace cache dir with C source path

This is not strictly necessary but it increases the likelihood of cache hits because foo.c and bar.c now will have different cache directories and can be updated independently without clobbering each other's cache data.

2 files changed, 21 insertions(+), 4 deletions(-)

src-self-hosted/Compilation.zig+18-1
...@@ -427,6 +427,13 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {...@@ -427,6 +427,13 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
427 // modified between incremental updates.427 // modified between incremental updates.
428 var hash = cache.hash;428 var hash = cache.hash;
429429
430 // Here we put the root source file path name, but *not* with addFile. We want the
431 // hash to be the same regardless of the contents of the source file, because
432 // incremental compilation will handle it, but we do want to namespace different
433 // source file names because they are likely different compilations and therefore this
434 // would be likely to cause cache hits.
435 hash.addBytes(root_pkg.root_src_path);
436 hash.addOptionalBytes(root_pkg.root_src_directory.path);
430 hash.add(valgrind);437 hash.add(valgrind);
431 hash.add(single_threaded);438 hash.add(single_threaded);
432 switch (options.target.os.getVersionRange()) {439 switch (options.target.os.getVersionRange()) {
...@@ -512,7 +519,17 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {...@@ -512,7 +519,17 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
512 const bin_directory = emit_bin.directory orelse blk: {519 const bin_directory = emit_bin.directory orelse blk: {
513 if (module) |zm| break :blk zm.zig_cache_artifact_directory;520 if (module) |zm| break :blk zm.zig_cache_artifact_directory;
514521
515 const digest = cache.hash.peek();522 // We could use the cache hash as is no problem, however, we increase
523 // the likelihood of cache hits by adding the first C source file
524 // path name (not contents) to the hash. This way if the user is compiling
525 // foo.c and bar.c as separate compilations, they get different cache
526 // directories.
527 var hash = cache.hash;
528 if (options.c_source_files.len >= 1) {
529 hash.addBytes(options.c_source_files[0].src_path);
530 }
531
532 const digest = hash.final();
516 const artifact_sub_dir = try std.fs.path.join(arena, &[_][]const u8{ "o", &digest });533 const artifact_sub_dir = try std.fs.path.join(arena, &[_][]const u8{ "o", &digest });
517 var artifact_dir = try options.zig_cache_directory.handle.makeOpenPath(artifact_sub_dir, .{});534 var artifact_dir = try options.zig_cache_directory.handle.makeOpenPath(artifact_sub_dir, .{});
518 owned_link_dir = artifact_dir;535 owned_link_dir = artifact_dir;
src-self-hosted/link/Elf.zig+3-3
...@@ -1288,15 +1288,15 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {...@@ -1288,15 +1288,15 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
1288 const prev_digest: []u8 = directory.handle.readLink(id_symlink_basename, &prev_digest_buf) catch |err| blk: {1288 const prev_digest: []u8 = directory.handle.readLink(id_symlink_basename, &prev_digest_buf) catch |err| blk: {
1289 log.debug("ELF LLD new_digest={} readlink error: {}", .{digest, @errorName(err)});1289 log.debug("ELF LLD new_digest={} readlink error: {}", .{digest, @errorName(err)});
1290 // Handle this as a cache miss.1290 // Handle this as a cache miss.
1291 mem.set(u8, &prev_digest_buf, 0);1291 break :blk prev_digest_buf[0..0];
1292 break :blk &prev_digest_buf;
1293 };1292 };
1294 log.debug("ELF LLD prev_digest={} new_digest={}", .{prev_digest, digest});
1295 if (mem.eql(u8, prev_digest, &digest)) {1293 if (mem.eql(u8, prev_digest, &digest)) {
1294 log.debug("ELF LLD digest={} match - skipping invocation", .{digest});
1296 // Hot diggity dog! The output binary is already there.1295 // Hot diggity dog! The output binary is already there.
1297 self.base.lock = ch.toOwnedLock();1296 self.base.lock = ch.toOwnedLock();
1298 return;1297 return;
1299 }1298 }
1299 log.debug("ELF LLD prev_digest={} new_digest={}", .{prev_digest, digest});
13001300
1301 // We are about to change the output file to be different, so we invalidate the build hash now.1301 // We are about to change the output file to be different, so we invalidate the build hash now.
1302 directory.handle.deleteFile(id_symlink_basename) catch |err| switch (err) {1302 directory.handle.deleteFile(id_symlink_basename) catch |err| switch (err) {