aboutsummaryrefslogtreecommitdiff
path: root/lib/std/Build/Cache.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2024-10-23 22:56:04 -0700
committerGitHub <noreply@github.com>2024-10-23 22:56:04 -0700
commitc563ba6b15b65ecdc1cb538c9437e11dfb330453 (patch)
tree99dd968efc3daea52a1d3628b7d8cedba53e84b7 /lib/std/Build/Cache.zig
parent33d07f4b6efe461ee3fbfa32cb18f60aac8c2827 (diff)
parent4bdc2d38717b5655acd862a5762e069419b158c7 (diff)
downloadzig-c563ba6b15b65ecdc1cb538c9437e11dfb330453.tar.gz
zig-c563ba6b15b65ecdc1cb538c9437e11dfb330453.zip
Merge pull request #21700 from ziglang/cli-lib-dirs
move linker input file parsing to the frontend
Diffstat (limited to 'lib/std/Build/Cache.zig')
-rw-r--r--lib/std/Build/Cache.zig57
1 files changed, 41 insertions, 16 deletions
diff --git a/lib/std/Build/Cache.zig b/lib/std/Build/Cache.zig
index bd98634ba8..7f8a6d3159 100644
--- a/lib/std/Build/Cache.zig
+++ b/lib/std/Build/Cache.zig
@@ -142,6 +142,9 @@ pub const hasher_init: Hasher = Hasher.init(&[_]u8{
pub const File = struct {
prefixed_path: PrefixedPath,
max_file_size: ?usize,
+ /// Populated if the user calls `addOpenedFile`.
+ /// The handle is not owned here.
+ handle: ?fs.File,
stat: Stat,
bin_digest: BinDigest,
contents: ?[]const u8,
@@ -173,6 +176,11 @@ pub const File = struct {
const new = new_max_size orelse return;
file.max_file_size = if (file.max_file_size) |old| @max(old, new) else new;
}
+
+ pub fn updateHandle(file: *File, new_handle: ?fs.File) void {
+ const handle = new_handle orelse return;
+ file.handle = handle;
+ }
};
pub const HashHelper = struct {
@@ -363,15 +371,20 @@ pub const Manifest = struct {
/// var file_contents = cache_hash.files.keys()[file_index].contents.?;
/// ```
pub fn addFilePath(m: *Manifest, file_path: Path, max_file_size: ?usize) !usize {
+ return addOpenedFile(m, file_path, null, max_file_size);
+ }
+
+ /// Same as `addFilePath` except the file has already been opened.
+ pub fn addOpenedFile(m: *Manifest, path: Path, handle: ?fs.File, max_file_size: ?usize) !usize {
const gpa = m.cache.gpa;
try m.files.ensureUnusedCapacity(gpa, 1);
const resolved_path = try fs.path.resolve(gpa, &.{
- file_path.root_dir.path orelse ".",
- file_path.subPathOrDot(),
+ path.root_dir.path orelse ".",
+ path.subPathOrDot(),
});
errdefer gpa.free(resolved_path);
const prefixed_path = try m.cache.findPrefixResolved(resolved_path);
- return addFileInner(m, prefixed_path, max_file_size);
+ return addFileInner(m, prefixed_path, handle, max_file_size);
}
/// Deprecated; use `addFilePath`.
@@ -383,13 +396,14 @@ pub const Manifest = struct {
const prefixed_path = try self.cache.findPrefix(file_path);
errdefer gpa.free(prefixed_path.sub_path);
- return addFileInner(self, prefixed_path, max_file_size);
+ return addFileInner(self, prefixed_path, null, max_file_size);
}
- fn addFileInner(self: *Manifest, prefixed_path: PrefixedPath, max_file_size: ?usize) !usize {
+ fn addFileInner(self: *Manifest, prefixed_path: PrefixedPath, handle: ?fs.File, max_file_size: ?usize) usize {
const gop = self.files.getOrPutAssumeCapacityAdapted(prefixed_path, FilesAdapter{});
if (gop.found_existing) {
gop.key_ptr.updateMaxSize(max_file_size);
+ gop.key_ptr.updateHandle(handle);
return gop.index;
}
gop.key_ptr.* = .{
@@ -398,6 +412,7 @@ pub const Manifest = struct {
.max_file_size = max_file_size,
.stat = undefined,
.bin_digest = undefined,
+ .handle = handle,
};
self.hash.add(prefixed_path.prefix);
@@ -565,6 +580,7 @@ pub const Manifest = struct {
},
.contents = null,
.max_file_size = null,
+ .handle = null,
.stat = .{
.size = stat_size,
.inode = stat_inode,
@@ -708,12 +724,19 @@ pub const Manifest = struct {
}
fn populateFileHash(self: *Manifest, ch_file: *File) !void {
- const pp = ch_file.prefixed_path;
- const dir = self.cache.prefixes()[pp.prefix].handle;
- const file = try dir.openFile(pp.sub_path, .{});
- defer file.close();
+ if (ch_file.handle) |handle| {
+ return populateFileHashHandle(self, ch_file, handle);
+ } else {
+ const pp = ch_file.prefixed_path;
+ const dir = self.cache.prefixes()[pp.prefix].handle;
+ const handle = try dir.openFile(pp.sub_path, .{});
+ defer handle.close();
+ return populateFileHashHandle(self, ch_file, handle);
+ }
+ }
- const actual_stat = try file.stat();
+ fn populateFileHashHandle(self: *Manifest, ch_file: *File, handle: fs.File) !void {
+ const actual_stat = try handle.stat();
ch_file.stat = .{
.size = actual_stat.size,
.mtime = actual_stat.mtime,
@@ -739,8 +762,7 @@ pub const Manifest = struct {
var hasher = hasher_init;
var off: usize = 0;
while (true) {
- // give me everything you've got, captain
- const bytes_read = try file.read(contents[off..]);
+ const bytes_read = try handle.pread(contents[off..], off);
if (bytes_read == 0) break;
hasher.update(contents[off..][0..bytes_read]);
off += bytes_read;
@@ -749,7 +771,7 @@ pub const Manifest = struct {
ch_file.contents = contents;
} else {
- try hashFile(file, &ch_file.bin_digest);
+ try hashFile(handle, &ch_file.bin_digest);
}
self.hash.hasher.update(&ch_file.bin_digest);
@@ -813,6 +835,7 @@ pub const Manifest = struct {
gop.key_ptr.* = .{
.prefixed_path = prefixed_path,
.max_file_size = null,
+ .handle = null,
.stat = undefined,
.bin_digest = undefined,
.contents = null,
@@ -851,6 +874,7 @@ pub const Manifest = struct {
new_file.* = .{
.prefixed_path = prefixed_path,
.max_file_size = null,
+ .handle = null,
.stat = stat,
.bin_digest = undefined,
.contents = null,
@@ -1067,6 +1091,7 @@ pub const Manifest = struct {
gop.key_ptr.* = .{
.prefixed_path = prefixed_path,
.max_file_size = file.max_file_size,
+ .handle = file.handle,
.stat = file.stat,
.bin_digest = file.bin_digest,
.contents = null,
@@ -1103,14 +1128,14 @@ pub fn writeSmallFile(dir: fs.Dir, sub_path: []const u8, data: []const u8) !void
fn hashFile(file: fs.File, bin_digest: *[Hasher.mac_length]u8) !void {
var buf: [1024]u8 = undefined;
-
var hasher = hasher_init;
+ var off: u64 = 0;
while (true) {
- const bytes_read = try file.read(&buf);
+ const bytes_read = try file.pread(&buf, off);
if (bytes_read == 0) break;
hasher.update(buf[0..bytes_read]);
+ off += bytes_read;
}
-
hasher.final(bin_digest);
}