From 0334f14a13c0d61c00a767e87499292d13ef2af1 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Mon, 7 Sep 2026 18:18:54 -0700 Subject: [PATCH] compiler: update to new std.Build.Cache API --- lib/compiler/Maker.zig | 2 +- lib/compiler/Maker/Step.zig | 2 +- lib/std/Build/Cache.zig | 129 +++++++++++++++++++++++++--------- lib/std/zig.zig | 2 +- src/Compilation.zig | 100 ++++++++++---------------- src/Zcu.zig | 4 +- src/Zcu/PerThread.zig | 38 +++++----- src/libs/mingw.zig | 12 ++-- src/link.zig | 12 +++- src/link/Elf.zig | 4 +- src/link/Elf/SharedObject.zig | 2 +- src/main.zig | 2 +- 12 files changed, 175 insertions(+), 134 deletions(-) diff --git a/lib/compiler/Maker.zig b/lib/compiler/Maker.zig index 9a3d72714bf56443572ecb4a52679926a4ab5dc6..9e7d1b01e47b034279d83577eeeabb3cf24ebfc7 100644 --- a/lib/compiler/Maker.zig +++ b/lib/compiler/Maker.zig @@ -1500,7 +1500,7 @@ fn configure(graph: *Graph, options: ConfigureOptions) !ScannedConfig { if (config_man) |man| for (configuration.path_deps) |path_dep| { const path = try confPathDepToCachePath(arena, graph, &configuration, path_dep); try man.addDiscoveredPath(.{ - .path = .{ .unresolved = path }, + .discovered_path = .{ .unresolved = path }, .handle = if (path_dep.flags.is_directory) .{ .dir = null } else .{ .file = null }, .metadata_only = path_dep.flags.metadata_only, }); diff --git a/lib/compiler/Maker/Step.zig b/lib/compiler/Maker/Step.zig index b1e89364fb050e5ba397d40f8de6c43966dedb04..25ea943f39d61909415e80741832b547b7f60334 100644 --- a/lib/compiler/Maker/Step.zig +++ b/lib/compiler/Maker/Step.zig @@ -753,7 +753,7 @@ fn failWithCacheError( switch (err) { error.CacheCheckFailed => switch (man.diagnostic) { .none => unreachable, - .manifest_create, .manifest_read, .manifest_lock => |e| { + .manifest_create, .manifest_stat, .manifest_read, .manifest_lock => |e| { return s.fail(maker, "failed checking cache: {t} {t}", .{ man.diagnostic, e }); }, .file_open, .file_stat, .file_read, .file_hash => |op| { diff --git a/lib/std/Build/Cache.zig b/lib/std/Build/Cache.zig index 1081bdbf8ef35c73798b1ca29db22eb90b671396..8481117fcc40788a334fa80bc17d045c6b5d23bd 100644 --- a/lib/std/Build/Cache.zig +++ b/lib/std/Build/Cache.zig @@ -1104,25 +1104,45 @@ pub const Manifest = struct { return timestamp.nanoseconds >= man.recent_problematic_timestamp.nanoseconds; } - pub const AddPathPostOptions = struct { - path: union(enum) { - unresolved: Path, - prefixed: PrefixedPath, - }, + pub const AddDiscoveredPathOptions = struct { + discovered_path: DiscoveredPath, handle: PathHandle = .{ .file = null }, stat: ?Stat = null, /// If it is a directory, there is a special encoding required for contents, which /// is null-separated sorted entries, each one prefixed with `File.Kind`. contents: ?[]const u8 = null, metadata_only: bool = false, + /// Populated if and only if `error.FileSystemFailure` is returned from `addDiscoveredPath`. + diagnostic: ?*AddDiscoveredPathDiagnostic = null, }; + pub const DiscoveredPath = union(enum) { + unresolved: Path, + prefixed: PrefixedPath, + }; + + pub const AddDiscoveredPathDiagnostic = union(enum) { + none, + open_file: Io.File.OpenError, + open_dir: Io.Dir.OpenError, + stat_file: Io.File.StatError, + stat_dir: Io.Dir.StatError, + read_file: Io.File.ReadPositionalError, + read_dir: Io.Dir.Reader.Error, + }; + + pub const AddDiscoveredPathError = error{ + /// If this is returned, diagnostic will be populated. + /// If contents and stat are both provided, this is unreachable. + FileSystemFailure, + } || Allocator.Error || Io.Cancelable; + /// Add a file as a dependency of process being cached, after cache miss /// occurs. /// /// See also: /// * `addInputPath` - pub fn addDiscoveredPath(m: *Manifest, options: AddPathPostOptions) !void { + pub fn addDiscoveredPath(m: *Manifest, options: AddDiscoveredPathOptions) AddDiscoveredPathError!void { assert(m.manifest_file != null); const cache = m.cache; const gpa = cache.gpa; @@ -1135,7 +1155,7 @@ pub const Manifest = struct { try m.contents.appendNTimes(gpa, 0, @offsetOf(File, "path_start")); errdefer m.contents.shrinkRetainingCapacity(@backingInt(new_file_offset)); - const new_prefix = switch (options.path) { + const new_prefix = switch (options.discovered_path) { .unresolved => |unresolved| try cache.resolveAppendPath(&m.contents, unresolved), .prefixed => |prefixed| try cache.appendPrefixedPath(&m.contents, prefixed), }; @@ -1184,26 +1204,38 @@ pub const Manifest = struct { switch (options.handle) { .dir => |opt_handle| if (opt_handle) |handle| { - try populateDirectory(m, header, need_stat, handle, options.contents, metadata_only); + try populateDirectory(m, header, need_stat, handle, options.contents, metadata_only, options.diagnostic); } else { const dir = cache.prefixes()[prefix].handle; const sub_path = filePath(m.contents.items, file_offset); - const handle = try dir.openDir(io, sub_path, .{ + const handle = dir.openDir(io, sub_path, .{ .access_sub_paths = false, .iterate = true, - }); + }) catch |err| switch (err) { + error.Canceled => |e| return e, + else => |e| { + if (options.diagnostic) |d| d.* = .{ .open_dir = e }; + return error.FileSystemFailure; + }, + }; defer handle.close(io); - try populateDirectory(m, header, need_stat, handle, options.contents, metadata_only); + try populateDirectory(m, header, need_stat, handle, options.contents, metadata_only, options.diagnostic); }, .file => |opt_handle| if (opt_handle) |handle| { - try populateFile(m, header, need_stat, handle, options.contents, metadata_only); + try populateFile(m, header, need_stat, handle, options.contents, metadata_only, options.diagnostic); } else { const dir = cache.prefixes()[prefix].handle; const sub_path = filePath(m.contents.items, file_offset); - const handle = try dir.openFile(io, sub_path, .{ .mode = .read_only }); + const handle = dir.openFile(io, sub_path, .{ .mode = .read_only }) catch |err| switch (err) { + error.Canceled => |e| return e, + else => |e| { + if (options.diagnostic) |d| d.* = .{ .open_file = e }; + return error.FileSystemFailure; + }, + }; defer handle.close(io); - try populateFile(m, header, need_stat, handle, options.contents, metadata_only); + try populateFile(m, header, need_stat, handle, options.contents, metadata_only, options.diagnostic); }, } @@ -1217,11 +1249,18 @@ pub const Manifest = struct { handle: Io.File, contents: ?[]const u8, metadata_only: bool, - ) !void { + diagnostic: ?*AddDiscoveredPathDiagnostic, + ) AddDiscoveredPathError!void { const io = m.cache.io; if (need_stat) { - const stat = try handle.stat(io); + const stat = handle.stat(io) catch |err| switch (err) { + error.Canceled => |e| return e, + else => |e| { + if (diagnostic) |d| d.* = .{ .stat_file = e }; + return error.FileSystemFailure; + }, + }; try file.setStat(m, .init(stat)); } if (metadata_only) { @@ -1233,7 +1272,13 @@ pub const Manifest = struct { hasher.update(bytes); hasher.final(&file.digest); } else { - try hashFile(io, handle, &file.digest); + hashFile(io, handle, &file.digest) catch |err| switch (err) { + error.Canceled => |e| return e, + else => |e| { + if (diagnostic) |d| d.* = .{ .read_file = e }; + return error.FileSystemFailure; + }, + }; } } @@ -1244,13 +1289,20 @@ pub const Manifest = struct { handle: Io.Dir, contents: ?[]const u8, metadata_only: bool, - ) !void { + diagnostic: ?*AddDiscoveredPathDiagnostic, + ) AddDiscoveredPathError!void { const cache = m.cache; const io = cache.io; const gpa = cache.gpa; if (need_stat) { - const stat = try handle.stat(io); + const stat = handle.stat(io) catch |err| switch (err) { + error.Canceled => |e| return e, + else => |e| { + if (diagnostic) |d| d.* = .{ .stat_dir = e }; + return error.FileSystemFailure; + }, + }; try file.setStat(m, .init(stat)); } if (metadata_only) { @@ -1264,7 +1316,13 @@ pub const Manifest = struct { } else { const prev_contents_len = m.all_input_content.items.len; defer m.all_input_content.shrinkRetainingCapacity(prev_contents_len); - try hashDir(gpa, io, handle, &file.digest, &m.all_input_content); + hashDir(gpa, io, handle, &file.digest, &m.all_input_content) catch |err| switch (err) { + error.OutOfMemory, error.Canceled => |e| return e, + else => |e| { + if (diagnostic) |d| d.* = .{ .read_dir = e }; + return error.FileSystemFailure; + }, + }; } } @@ -1297,13 +1355,15 @@ pub const Manifest = struct { .target, .target_must_resolve => {}, .prereq => |file_path| if (self.manifest_file == null) { _ = try self.addInputPath(.initCwd(file_path), .{}); - } else try self.addDiscoveredPath(.{ .path = .{ .unresolved = .initCwd(file_path) } }), + } else try self.addDiscoveredPath(.{ .discovered_path = .{ .unresolved = .initCwd(file_path) } }), .prereq_must_resolve => { resolve_buf.clearRetainingCapacity(); try token.resolve(gpa, &resolve_buf); if (self.manifest_file == null) { _ = try self.addInputPath(.initCwd(resolve_buf.items), .{}); - } else try self.addDiscoveredPath(.{ .path = .{ .unresolved = .initCwd(resolve_buf.items) } }); + } else try self.addDiscoveredPath(.{ + .discovered_path = .{ .unresolved = .initCwd(resolve_buf.items) }, + }); }, else => |err| { try err.printError(gpa, &error_buf); @@ -1456,10 +1516,12 @@ pub const Manifest = struct { const gpa = man.cache.gpa; const files = man.files.keys(); if (files.len > 0) { + const contents = man.contents.items; for (files) |file| { - try buf.ensureUnusedCapacity(gpa, file.prefixed_path.sub_path.len + 2); - buf.appendAssumeCapacity(file.prefixed_path.prefix + 1); - buf.appendSliceAssumeCapacity(file.prefixed_path.sub_path); + const file_path = filePath(contents, file); + try buf.ensureUnusedCapacity(gpa, file_path.len + 2); + buf.appendAssumeCapacity(@as(u8, file.get(contents).flags.prefix) + 1); + buf.appendSliceAssumeCapacity(file_path); buf.appendAssumeCapacity(0); } // The null byte is a separator, not a terminator. @@ -1476,12 +1538,12 @@ pub const Manifest = struct { const orig_files_len = other.files.count(); const orig_contents_len = other.contents.items.len; errdefer { - other.files.shrinkRetainingCapacity(orig_files_len); + other.files.shrinkRetainingCapacityContext(orig_files_len, .{ .contents = other.contents.items }); other.contents.shrinkRetainingCapacity(orig_contents_len); } for (man.files.keys(), 0..) |off, file_index| { - try other.files.ensureUnusedCapacity(gpa, 1); + try other.files.ensureUnusedCapacityContext(gpa, 1, .{ .contents = other.contents.items }); const next_off = if (file_index < man.files.count()) @backingInt(man.files.keys()[file_index + 1]) @@ -1489,20 +1551,21 @@ pub const Manifest = struct { man.contents.items.len; const copy_bytes = man.contents.items[@backingInt(off)..next_off]; - const prev_contents_len = other.contents.items.len; + const prev_contents_len: File.Offset = @fromBackingInt(@intCast(other.contents.items.len)); try other.contents.appendSlice(gpa, copy_bytes); - const gop = other.files.getOrPutAssumeCapacityContext(@fromBackingInt(prev_contents_len), .{ - .manifest = other, + const gop = other.files.getOrPutAssumeCapacityContext(prev_contents_len, .{ + .contents = other.contents.items, }); if (gop.found_existing) { - other.contents.shrinkRetainingCapacity(prev_contents_len); + other.contents.shrinkRetainingCapacity(@backingInt(prev_contents_len)); continue; } - const other_file = File.get(@fromBackingInt(prev_contents_len)); - other_file.prefix = prefix_map[other_file.prefix]; + // Flags are already copied but the prefix is supposed to be filtered by `prefix_map`. + const other_file = prev_contents_len.get(other.contents.items); + other_file.flags.prefix = @intCast(prefix_map[other_file.flags.prefix]); } } diff --git a/lib/std/zig.zig b/lib/std/zig.zig index 15218e43c432ad51d2210142b02f2a05cdbc3973..57bda0bbfd85ad057dd45dae7b482f226012b2ae 100644 --- a/lib/std/zig.zig +++ b/lib/std/zig.zig @@ -1840,7 +1840,7 @@ pub fn buildExeSubprocess( const prefix: Server.Message.PathPrefix = @fromBackingInt(@intCast(prefixed_path[0] - 1)); const sub_path = prefixed_path[1..]; man.addDiscoveredPath(.{ - .path = .{ .prefixed = .{ + .discovered_path = .{ .prefixed = .{ .prefix = @intCast(@backingInt(prefix)), .sub_path = sub_path, } }, diff --git a/src/Compilation.zig b/src/Compilation.zig index af532d6c0a253a46650ebd35fb2b939d69d5e107..38229017566600e927fb5dfe2d51f9491bce1d2f 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -701,39 +701,12 @@ pub const Path = struct { }; } - pub fn addToCacheManifestPostHit(p: Path, man: *Cache.Manifest, dirs: *const std.zig.Directories) !void { - comptime assert(0 == @backingInt(std.zig.Server.Message.PathPrefix.cwd)); - comptime assert(1 == @backingInt(std.zig.Server.Message.PathPrefix.zig_lib)); - comptime assert(2 == @backingInt(std.zig.Server.Message.PathPrefix.local_cache)); - comptime assert(3 == @backingInt(std.zig.Server.Message.PathPrefix.global_cache)); - comptime assert(4 == @backingInt(std.zig.Server.Message.PathPrefix.build_root)); - comptime assert(@typeInfo(std.zig.Server.Message.PathPrefix).@"enum".field_names.len == 5); - const gpa = man.cache.gpa; - const prefixed_path: Cache.PrefixedPath = .{ - .prefix = switch (p.root) { - .none => { - const path = try p.toAbsolute(dirs, gpa); - defer gpa.free(path); - return man.addFilePost(path); - }, - .zig_lib => 1, - .local_cache => 2, - .global_cache => 3, - .build_root => 4, - }, - .sub_path = try gpa.dupe(u8, p.sub_path), - }; - var keep = false; - defer if (!keep) gpa.free(prefixed_path.sub_path); - keep = try man.addPrefixedPathPost(prefixed_path); - } - - pub fn addToCacheManifestPostHitContents( + pub fn addToCacheManifestAsDiscovered( p: Path, man: *Cache.Manifest, dirs: *const std.zig.Directories, - bytes: []const u8, - stat: Cache.File.Stat, + contents: ?[]const u8, + stat: ?Cache.Manifest.Stat, ) !void { comptime assert(0 == @backingInt(std.zig.Server.Message.PathPrefix.cwd)); comptime assert(1 == @backingInt(std.zig.Server.Message.PathPrefix.zig_lib)); @@ -741,24 +714,29 @@ pub const Path = struct { comptime assert(3 == @backingInt(std.zig.Server.Message.PathPrefix.global_cache)); comptime assert(4 == @backingInt(std.zig.Server.Message.PathPrefix.build_root)); comptime assert(@typeInfo(std.zig.Server.Message.PathPrefix).@"enum".field_names.len == 5); - const gpa = man.cache.gpa; - const prefixed_path: Cache.PrefixedPath = .{ - .prefix = switch (p.root) { - .none => { - const path = try p.toAbsolute(dirs, gpa); - defer gpa.free(path); - return man.addFilePostContents(path, bytes, stat); + try man.addDiscoveredPath(.{ + .discovered_path = .{ .prefixed = .{ + .prefix = switch (p.root) { + .none => { + const gpa = man.cache.gpa; + const path = try p.toAbsolute(dirs, gpa); + defer gpa.free(path); + return man.addDiscoveredPath(.{ + .discovered_path = .{ .unresolved = .initCwd(path) }, + .contents = contents, + .stat = stat, + }); + }, + .zig_lib => 1, + .local_cache => 2, + .global_cache => 3, + .build_root => 4, }, - .zig_lib => 1, - .local_cache => 2, - .global_cache => 3, - .build_root => 4, - }, - .sub_path = try gpa.dupe(u8, p.sub_path), - }; - var keep = false; - defer if (!keep) gpa.free(prefixed_path.sub_path); - keep = try man.addPrefixedPathPostContents(prefixed_path, bytes, stat); + .sub_path = p.sub_path, + } }, + .contents = contents, + .stat = stat, + }); } }; @@ -2835,20 +2813,18 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) UpdateE man.want_shared_lock = false; } - const is_hit = man.check(main_progress_node) catch |err| switch (err) { + const status = man.check(main_progress_node) catch |err| switch (err) { error.Canceled, error.OutOfMemory => |e| return e, error.CacheCheckFailed => switch (man.diagnostic) { .none => unreachable, - .manifest_create, .manifest_read, .manifest_lock => |e| return comp.setMiscFailure( + .manifest_create, .manifest_stat, .manifest_read, .manifest_lock => |e| return comp.setMiscFailure( .check_whole_cache, "failed to check cache: {t} {t}", .{ man.diagnostic, e }, ), .file_open, .file_stat, .file_read, .file_hash => |op| { - const pp = man.files.keys()[op.file_index].prefixed_path; - const prefix = man.cache.prefixes()[pp.prefix]; - return comp.setMiscFailure(.check_whole_cache, "failed to check cache: {f}{s} {t} {t}", .{ - prefix, pp.sub_path, man.diagnostic, op.err, + return comp.setMiscFailure(.check_whole_cache, "failed to check cache: {f} {t} {t}", .{ + op.path(&man), man.diagnostic, op.err, }); }, }, @@ -2858,7 +2834,7 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) UpdateE .{}, ), }; - if (is_hit and !ignore_hit) { + if (status == .hit and !ignore_hit) { // In this case the cache hit contains the full set of file system inputs. Nice! if (comp.file_system_inputs) |buf| try man.populateFileSystemInputs(buf); if (comp.parent_whole_cache) |pwc| { @@ -3454,8 +3430,8 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes const opts = comp.cache_use.whole.lf_open_opts; - try man.addOptionalFilePath(opts.linker_script); - try man.addOptionalFilePath(opts.version_script); + try man.addInputPathOptional(opts.linker_script, .{}); + try man.addInputPathOptional(opts.version_script, .{}); man.hash.add(opts.allow_undefined_version); man.hash.addOptional(opts.enable_new_dtags); @@ -3514,7 +3490,7 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes // Mach-O specific stuff try link.File.MachO.hashAddFrameworks(man, opts.frameworks); - try man.addOptionalFilePath(opts.entitlements); + try man.addInputPathOptional(opts.entitlements, .{}); man.hash.addOptional(opts.pagezero_size); man.hash.addOptional(opts.headerpad_size); man.hash.add(opts.headerpad_max_install_names); @@ -5905,7 +5881,7 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32 const rc_basename = try std.fmt.allocPrint(arena, "{s}.rc", .{src_basename}); const res_basename = try std.fmt.allocPrint(arena, "{s}.res", .{src_basename}); - const digest = if (try man.check(child_progress_node)) man.final() else blk: { + const digest = if (.hit == try man.check(child_progress_node)) man.final() else blk: { // The digest only depends on the .manifest file, so we can // get the digest now and write the .res directly to the cache const digest = man.final(); @@ -5998,7 +5974,7 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32 const rc_basename_noext = src_basename[0 .. src_basename.len - fs.path.extension(src_basename).len]; - const digest = if (try man.check(child_progress_node)) man.final() else blk: { + const digest = if (.hit == try man.check(child_progress_node)) man.final() else blk: { var zig_cache_tmp_dir = try comp.dirs.local_cache.handle.createDirPathOpen(io, "tmp", .{}); defer zig_cache_tmp_dir.close(io); @@ -6055,12 +6031,14 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32 return comp.failWin32Resource(win32_resource, "depfile from zig rc has unexpected format", .{}); } const dep_file_path = element.string; - try man.addFilePost(dep_file_path); + try man.addDiscoveredPath(.{ .discovered_path = .{ .unresolved = .initCwd(dep_file_path) } }); switch (comp.cache_use) { .whole => |whole| if (whole.cache_manifest) |whole_cache_manifest| { try whole.cache_manifest_mutex.lock(io); defer whole.cache_manifest_mutex.unlock(io); - try whole_cache_manifest.addFilePost(dep_file_path); + try whole_cache_manifest.addDiscoveredPath(.{ + .discovered_path = .{ .unresolved = .initCwd(dep_file_path) }, + }); }, .incremental, .none => {}, } diff --git a/src/Zcu.zig b/src/Zcu.zig index d6f9da974052860224583dd47cd3b6e44c90d056..56118073660df5a55f77517a459fe5f666c1d442 100644 --- a/src/Zcu.zig +++ b/src/Zcu.zig @@ -974,7 +974,7 @@ pub const File = struct { success, }, /// Whether this is populated depends on `status`. - stat: Cache.File.Stat, + stat: Cache.Manifest.Stat, /// Whether this file is the generated file of a "builtin" module. This matters because those /// files are generated and stored in-nemory rather than being read off-disk. The rest of the @@ -1246,7 +1246,7 @@ pub const EmbedFile = struct { val: InternPool.Index, /// If this is `null` and `val` is `.none`, the file has never been loaded. err: ?(Io.File.OpenError || Io.File.StatError || Io.File.Reader.Error || error{UnexpectedEof}), - stat: Cache.File.Stat, + stat: Cache.Manifest.Stat, pub const Index = enum(u32) { _, diff --git a/src/Zcu/PerThread.zig b/src/Zcu/PerThread.zig index 78cf664f71afd94efe6e9044d93d93b1dc1487d8..f0b1764f463dbe9d085e0fca931d20286e99255f 100644 --- a/src/Zcu/PerThread.zig +++ b/src/Zcu/PerThread.zig @@ -224,11 +224,12 @@ pub fn update( const result = res: { try whole.cache_manifest_mutex.lock(io); defer whole.cache_manifest_mutex.unlock(io); - if (file.source) |source| { - break :res file.path.addToCacheManifestPostHitContents(man, &comp.dirs, source, file.stat); - } else { - break :res file.path.addToCacheManifestPostHit(man, &comp.dirs); - } + break :res file.path.addToCacheManifestAsDiscovered( + man, + &comp.dirs, + file.source, + if (file.source != null) file.stat else null, + ); }; result catch |err| switch (err) { error.OutOfMemory => |e| return e, @@ -2835,26 +2836,21 @@ fn updateBuiltinModule(pt: Zcu.PerThread, opts: Builtin) Allocator.Error!struct assert(mem.eql(u8, import_path, "std")); // the single import is of 'std' } - Builtin.updateFileOnDisk(file, comp) catch |err| comp.setMiscFailure( - .write_builtin_zig, - "unable to write '{f}': {s}", - .{ file.path.fmt(comp), @errorName(err) }, - ); + Builtin.updateFileOnDisk(file, comp) catch |err| + comp.setMiscFailure(.write_builtin_zig, "unable to write {qf}: {t}", .{ file.path.fmt(comp), err }); return .{ .file = file_index, .module_root = mod, }; } +pub const EmbedFileError = error{ImportOutsideModulePath} || Allocator.Error || Io.Cancelable; + pub fn embedFile( pt: Zcu.PerThread, cur_file: *Zcu.File, import_string: []const u8, -) error{ - OutOfMemory, - Canceled, - ImportOutsideModulePath, -}!Zcu.EmbedFile.Index { +) EmbedFileError!Zcu.EmbedFile.Index { const zcu = pt.zcu; const gpa = zcu.gpa; @@ -2937,7 +2933,7 @@ fn updateEmbedFileInner( }; defer file.close(io); - const stat: Cache.File.Stat = .fromFs(try file.stat(io)); + const stat: Cache.Manifest.Stat = .init(try file.stat(io)); if (ef.val != .none) { const old_stat = ef.stat; @@ -2994,10 +2990,7 @@ fn updateEmbedFileInner( } /// Assumes that `path` is allocated into `gpa`. Takes ownership of `path` on success. -fn newEmbedFile( - pt: Zcu.PerThread, - path: Compilation.Path, -) !*Zcu.EmbedFile { +fn newEmbedFile(pt: Zcu.PerThread, path: Compilation.Path) EmbedFileError!*Zcu.EmbedFile { const zcu = pt.zcu; const comp = zcu.comp; const io = comp.io; @@ -3034,7 +3027,10 @@ fn newEmbedFile( try whole.cache_manifest_mutex.lock(io); defer whole.cache_manifest_mutex.unlock(io); - try path.addToCacheManifestPostHitContents(man, &comp.dirs, contents, new_file.stat); + path.addToCacheManifestAsDiscovered(man, &comp.dirs, contents, new_file.stat) catch |err| switch (err) { + error.FileSystemFailure => unreachable, // contents and stat are both provided + else => |e| return e, + }; } return new_file; diff --git a/src/libs/mingw.zig b/src/libs/mingw.zig index 63c1e5ad16ccf7a745256242f528203d5a5cbdcf..f0d0ef2990089fd1d6ac7ef5844678d1950f7b3c 100644 --- a/src/libs/mingw.zig +++ b/src/libs/mingw.zig @@ -251,18 +251,16 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8, prog_node: std.P const final_lib_basename = try std.fmt.allocPrint(gpa, "{s}.lib", .{lib_name}); errdefer gpa.free(final_lib_basename); - const is_hit = man.check(prog_node) catch |err| switch (err) { + const status = man.check(prog_node) catch |err| switch (err) { error.CacheCheckFailed => switch (man.diagnostic) { .none => unreachable, - .manifest_create, .manifest_read, .manifest_lock => |e| { + .manifest_create, .manifest_stat, .manifest_read, .manifest_lock => |e| { comp.setMiscFailure(.windows_import_lib, "checking cache failed: {t} {t}", .{ man.diagnostic, e }); return error.AlreadyReported; }, .file_open, .file_stat, .file_read, .file_hash => |op| { - const pp = man.files.keys()[op.file_index].prefixed_path; - const prefix = man.cache.prefixes()[pp.prefix]; - comp.setMiscFailure(.windows_import_lib, "checking cache failed: {f}{s} {t} {t}", .{ - prefix, pp.sub_path, man.diagnostic, op.err, + comp.setMiscFailure(.windows_import_lib, "checking cache failed: {f} {t} {t}", .{ + op.path(&man), man.diagnostic, op.err, }); return error.AlreadyReported; }, @@ -273,7 +271,7 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8, prog_node: std.P return error.AlreadyReported; }, }; - if (is_hit) { + if (status == .hit) { const digest = man.final(); const sub_path = try std.fs.path.join(gpa, &.{ "o", &digest, final_lib_basename }); errdefer gpa.free(sub_path); diff --git a/src/link.zig b/src/link.zig index babee6e563e072fd863c3622be6107fdac6a35fd..df68e0216d3f20ab09837c55f849461c30fbd5a4 100644 --- a/src/link.zig +++ b/src/link.zig @@ -1925,15 +1925,21 @@ pub fn hashInputs(man: *Cache.Manifest, link_inputs: []const Input) !void { man.hash.add(@as(@typeInfo(Input).@"union".tag_type.?, link_input)); switch (link_input) { .object, .archive => |obj| { - _ = try man.addOpenedFile(obj.path, obj.file, null); + _ = try man.addInputPath(obj.path, .{ + .handle = .{ .file = obj.file }, + }); man.hash.add(obj.must_link); man.hash.add(obj.hidden); }, .res => |res| { - _ = try man.addOpenedFile(res.path, res.file, null); + _ = try man.addInputPath(res.path, .{ + .handle = .{ .file = res.file }, + }); }, .dso => |dso| { - _ = try man.addOpenedFile(dso.path, dso.file, null); + _ = try man.addInputPath(dso.path, .{ + .handle = .{ .file = dso.file }, + }); man.hash.add(dso.needed); man.hash.add(dso.weak); man.hash.add(dso.reexport); diff --git a/src/link/Elf.zig b/src/link/Elf.zig index 416eab37e05651c42cfedb4e025bca62b9cac016..f04d7582bd6dac07669861f0d920c86efa6d6d1c 100644 --- a/src/link/Elf.zig +++ b/src/link/Elf.zig @@ -1120,7 +1120,7 @@ fn parseDso( const handle = dso.file; - const stat = Stat.fromFs(try handle.stat(io)); + const stat: Stat = .init(try handle.stat(io)); var header = try SharedObject.parseHeader(gpa, io, diags, dso.path, handle, stat, target); defer header.deinit(gpa); @@ -4407,7 +4407,7 @@ const mem = std.mem; const Allocator = std.mem.Allocator; const Hash = std.hash.Wyhash; const Path = std.Build.Cache.Path; -const Stat = std.Build.Cache.File.Stat; +const Stat = std.Build.Cache.Manifest.Stat; const codegen = @import("../codegen.zig"); const eh_frame = @import("Elf/eh_frame.zig"); diff --git a/src/link/Elf/SharedObject.zig b/src/link/Elf/SharedObject.zig index 052093dce3acdf01c893ec6af73368f55523d234..3030a45bff3806d93b1af418d6eaa49a7a649558 100644 --- a/src/link/Elf/SharedObject.zig +++ b/src/link/Elf/SharedObject.zig @@ -7,7 +7,7 @@ const elf = std.elf; const log = std.log.scoped(.elf); const mem = std.mem; const Path = std.Build.Cache.Path; -const Stat = std.Build.Cache.File.Stat; +const Stat = std.Build.Cache.Manifest.Stat; const Allocator = mem.Allocator; const Elf = @import("../Elf.zig"); diff --git a/src/main.zig b/src/main.zig index 164c2f15ee081a7e0ac22dacad8659d1e9d8f596..bcffbfee9176c9c5fb050927d147a5e39332788b 100644 --- a/src/main.zig +++ b/src/main.zig @@ -4878,7 +4878,7 @@ fn cmdTranslateC( Compilation.cache_helpers.hashCSource(&man, c_source_file) catch |err| fatal("unable to process {q}: {t}", .{ c_source_file.src_path, err }); - const result: Compilation.TranslateCResult = if (try man.check(prog_node)) .{ + const result: Compilation.TranslateCResult = if (.hit == try man.check(prog_node)) .{ .digest = man.finalBin(), .cache_hit = true, .errors = std.zig.ErrorBundle.empty, -- 2.54.0