aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMotiejus Jakštys <motiejus@uber.com>2023-05-19 10:12:47 +0300
committerAndrew Kelley <andrew@ziglang.org>2024-03-14 09:32:56 -0700
commit400145ee3bb0740cc274a75b7c612d799811b5fe (patch)
tree01a4303a0d32299630f8a876ecc4d8978f59f408 /src
parentbc5b09469509fae80e989adc511e2f31aca05dc0 (diff)
downloadzig-400145ee3bb0740cc274a75b7c612d799811b5fe.tar.gz
zig-400145ee3bb0740cc274a75b7c612d799811b5fe.zip
reduce garbage for repeated `zig cc -` calls
Context: user provides `-` to read from stdin instead of a file. Before: it would create a file in $ZIG_LOCAL_CACHE_DIR/tmp/ for each invocation and leave it there. After: it hashes the file contents and renames the file to the hash. Result: repeated invocations of `zig cc` do not cause so much trash to be created.
Diffstat (limited to 'src')
-rw-r--r--src/main.zig35
1 files changed, 26 insertions, 9 deletions
diff --git a/src/main.zig b/src/main.zig
index b4d493a06f..8c445fdd1e 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -3129,19 +3129,36 @@ fn buildOutputType(
// "-" is stdin. Dump it to a real file.
const sep = fs.path.sep_str;
- const sub_path = try std.fmt.allocPrint(arena, "tmp" ++ sep ++ "{x}-stdin{s}", .{
+ const dump_path = try std.fmt.allocPrint(arena, "tmp" ++ sep ++ "{x}-dump-stdin{s}", .{
std.crypto.random.int(u64), ext.canonicalName(target),
});
try local_cache_directory.handle.makePath("tmp");
- // Note that in one of the happy paths, execve() is used to switch
- // to clang in which case any cleanup logic that exists for this
- // temporary file will not run and this temp file will be leaked.
- // Oh well. It's a minor punishment for using `-x c` which nobody
- // should be doing. Therefore, we make no effort to clean up. Using
- // `-` for stdin as a source file always leaks a temp file.
- var f = try local_cache_directory.handle.createFile(sub_path, .{});
+
+ // Note that in one of the happy paths, execve() is used to switch to
+ // clang in which case any cleanup logic that exists for this temporary
+ // file will not run and this temp file will be leaked. The filename
+ // will be a hash of its contents — so multiple invocations of
+ // `zig cc -` will result in the same temp file name.
+ var f = try local_cache_directory.handle.createFile(dump_path, .{});
defer f.close();
- try f.writeFileAll(io.getStdIn(), .{});
+
+ // Re-using the hasher from Cache, since the functional requirements
+ // for the hashing algorithm here and in the cache are the same.
+ // We are providing our own cache key, because this file has nothing
+ // to do with the cache manifest.
+ var hasher = Cache.Hasher.init("0123456789abcdef");
+ var w = io.multiWriter(.{ f.writer(), hasher.writer() });
+ var fifo = std.fifo.LinearFifo(u8, .{ .Static = 4096 }).init();
+ try fifo.pump(io.getStdIn().reader(), w.writer());
+
+ var bin_digest: Cache.BinDigest = undefined;
+ hasher.final(&bin_digest);
+
+ const sub_path = try std.fmt.allocPrint(arena, "tmp" ++ sep ++ "{s}-stdin{s}", .{
+ std.fmt.fmtSliceHexLower(&bin_digest),
+ ext.canonicalName(target),
+ });
+ try local_cache_directory.handle.rename(dump_path, sub_path);
// Convert `sub_path` to be relative to current working directory.
src.src_path = try local_cache_directory.join(arena, &.{sub_path});