Skip to content

Commit 400145e

Browse files
motiejusandrewrk
authored andcommitted
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.
1 parent bc5b094 commit 400145e

File tree

1 file changed

+26
-9
lines changed

1 file changed

+26
-9
lines changed

src/main.zig

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3129,19 +3129,36 @@ fn buildOutputType(
31293129

31303130
// "-" is stdin. Dump it to a real file.
31313131
const sep = fs.path.sep_str;
3132-
const sub_path = try std.fmt.allocPrint(arena, "tmp" ++ sep ++ "{x}-stdin{s}", .{
3132+
const dump_path = try std.fmt.allocPrint(arena, "tmp" ++ sep ++ "{x}-dump-stdin{s}", .{
31333133
std.crypto.random.int(u64), ext.canonicalName(target),
31343134
});
31353135
try local_cache_directory.handle.makePath("tmp");
3136-
// Note that in one of the happy paths, execve() is used to switch
3137-
// to clang in which case any cleanup logic that exists for this
3138-
// temporary file will not run and this temp file will be leaked.
3139-
// Oh well. It's a minor punishment for using `-x c` which nobody
3140-
// should be doing. Therefore, we make no effort to clean up. Using
3141-
// `-` for stdin as a source file always leaks a temp file.
3142-
var f = try local_cache_directory.handle.createFile(sub_path, .{});
3136+
3137+
// Note that in one of the happy paths, execve() is used to switch to
3138+
// clang in which case any cleanup logic that exists for this temporary
3139+
// file will not run and this temp file will be leaked. The filename
3140+
// will be a hash of its contents — so multiple invocations of
3141+
// `zig cc -` will result in the same temp file name.
3142+
var f = try local_cache_directory.handle.createFile(dump_path, .{});
31433143
defer f.close();
3144-
try f.writeFileAll(io.getStdIn(), .{});
3144+
3145+
// Re-using the hasher from Cache, since the functional requirements
3146+
// for the hashing algorithm here and in the cache are the same.
3147+
// We are providing our own cache key, because this file has nothing
3148+
// to do with the cache manifest.
3149+
var hasher = Cache.Hasher.init("0123456789abcdef");
3150+
var w = io.multiWriter(.{ f.writer(), hasher.writer() });
3151+
var fifo = std.fifo.LinearFifo(u8, .{ .Static = 4096 }).init();
3152+
try fifo.pump(io.getStdIn().reader(), w.writer());
3153+
3154+
var bin_digest: Cache.BinDigest = undefined;
3155+
hasher.final(&bin_digest);
3156+
3157+
const sub_path = try std.fmt.allocPrint(arena, "tmp" ++ sep ++ "{s}-stdin{s}", .{
3158+
std.fmt.fmtSliceHexLower(&bin_digest),
3159+
ext.canonicalName(target),
3160+
});
3161+
try local_cache_directory.handle.rename(dump_path, sub_path);
31453162

31463163
// Convert `sub_path` to be relative to current working directory.
31473164
src.src_path = try local_cache_directory.join(arena, &.{sub_path});

0 commit comments

Comments
 (0)