diff --git a/src/Compilation.zig b/src/Compilation.zig index e9316d7eb68c2dbf8305ab1691bb811ce8ca8d50..58273389905e37175d60191b613ffebd7dd673a3 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -5351,6 +5351,7 @@ fn buildMingwCrtFile(comp: *Compilation, crt_file: mingw.CrtFile, prog_node: std fn buildMingwImportLib(comp: *Compilation, lib_name: []const u8, is_prelink: bool, prog_node: std.Progress.Node) void { const crt_file_path = mingw.buildImportLib(comp, lib_name, prog_node) catch |err| switch (err) { + error.AlreadyReported => return, // TODO: This isn't actually true for self-hosted // In the non-prelink case we will end up putting foo.lib onto the linker line and letting the linker // use its library paths to look for libraries and report any problems. @@ -5364,7 +5365,7 @@ fn buildMingwImportLib(comp: *Compilation, lib_name: []const u8, is_prelink: boo // TODO Surface more error details. else => |e| return comp.lockAndSetMiscFailure( .windows_import_lib, - "unable to generate mingw DLL import .lib file for {s}: {t}", + "generating mingw DLL import .lib file for {s} failed: {t}", .{ lib_name, e }, ), }; diff --git a/src/libs/mingw.zig b/src/libs/mingw.zig index 73e741c4fa4e97fa2622ed9e13c43d59568bd89c..a91c24291d0a395b189712c4d8f199bf13cd57d0 100644 --- a/src/libs/mingw.zig +++ b/src/libs/mingw.zig @@ -215,12 +215,15 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8, prog_node: std.P defer arena_allocator.deinit(); const arena = arena_allocator.allocator(); - const def_file_path = findDef(arena, io, comp.getTarget(), comp.dirs.zig_lib, lib_name) catch |err| switch (err) { - error.FileNotFound => return error.DefNotFound, - else => |e| return e, + const def_file_path: Cache.Path = .{ + .root_dir = comp.dirs.zig_lib, + .sub_path = findDef(arena, io, comp.getTarget(), comp.dirs.zig_lib, lib_name) catch |err| switch (err) { + error.FileNotFound => return error.DefNotFound, + else => |e| return e, + }, }; // Only .def.in files need preprocessing - const def_needs_preprocessing = mem.endsWith(u8, def_file_path, ".def.in"); + const def_needs_preprocessing = mem.endsWith(u8, def_file_path.sub_path, ".def.in"); const target = comp.getTarget(); @@ -243,15 +246,34 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8, prog_node: std.P var man = cache.obtain(); defer man.deinit(); - _ = try man.addFilePath(.{ - .root_dir = comp.dirs.zig_lib, - .sub_path = def_file_path, - }, null); + _ = try man.addFilePath(def_file_path, null); const final_lib_basename = try std.fmt.allocPrint(gpa, "{s}.lib", .{lib_name}); errdefer gpa.free(final_lib_basename); - if (try man.hit(prog_node)) { + const is_hit = man.hit(prog_node) catch |err| switch (err) { + error.CacheCheckFailed => switch (man.diagnostic) { + .none => unreachable, + .manifest_create, .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, + }); + return error.AlreadyReported; + }, + }, + error.OutOfMemory, error.Canceled => |e| return e, + error.InvalidFormat => { + comp.setMiscFailure(.windows_import_lib, "checking cache failed: invalid manifest file format", .{}); + return error.AlreadyReported; + }, + }; + if (is_hit) { const digest = man.final(); const sub_path = try std.fs.path.join(gpa, &.{ "o", &digest, final_lib_basename }); errdefer gpa.free(sub_path); @@ -276,20 +298,11 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8, prog_node: std.P var o_dir = try comp.dirs.global_cache.handle.createDirPathOpen(io, o_sub_path, .{}); defer o_dir.close(io); - const include_dir = try comp.dirs.zig_lib.join(arena, &.{ "libc", "mingw", "def-include" }); - - if (comp.verbose_cc) { - var buffer: [256]u8 = undefined; - const stderr = try io.lockStderr(&buffer, null); - defer io.unlockStderr(); - const w = &stderr.file_writer.interface; - w.print("def file: {s}\n", .{def_file_path}) catch |err| switch (err) { - error.WriteFailed => return stderr.file_writer.err.?, - }; - w.print("include dir: {s}\n", .{include_dir}) catch |err| switch (err) { - error.WriteFailed => return stderr.file_writer.err.?, - }; - } + const sep = path.sep_str; + const include_dir: Cache.Path = .{ + .root_dir = comp.dirs.zig_lib, + .sub_path = "libc" ++ sep ++ "mingw" ++ sep ++ "def-include", + }; const members = members: { const members_node = sub_node.start("Members", 0); @@ -313,7 +326,7 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8, prog_node: std.P break :pp try aw.toOwnedSliceSentinel(0); }, - false => try Io.Dir.cwd().readFileAllocOptions(io, def_file_path, gpa, .unlimited, .of(u8), 0), + false => try def_file_path.root_dir.handle.readFileAllocOptions(io, def_file_path.sub_path, gpa, .unlimited, .of(u8), 0), }; defer gpa.free(input); diff --git a/src/libs/mingw/Preprocessor.zig b/src/libs/mingw/Preprocessor.zig index f6606eb54cd0f2ea46a85194dd79674115256499..f10cb33d39853efb6455e74937a75a7c34296cca 100644 --- a/src/libs/mingw/Preprocessor.zig +++ b/src/libs/mingw/Preprocessor.zig @@ -4,6 +4,7 @@ const Allocator = std.mem.Allocator; const Token = Tokenizer.Token; const mem = std.mem; const assert = std.debug.assert; +const Path = std.Build.Cache.Path; test { _ = Tokenizer; @@ -25,15 +26,15 @@ pub const Source = struct { pub const generated: Source.Id = std.math.maxInt(usize); pub const Id = usize; id: Id = generated, - path: []const u8, + path: Path, buf: []const u8, }; -sources: std.array_hash_map.String(Source) = .empty, +sources: std.array_hash_map.Custom(Path, Source, Path.TableAdapter, false) = .empty, arena: Allocator, io: std.Io, -include_dir: []const u8, +include_dir: Path, top_expansion_buf: ExpandBuf = .empty, add_expansion_nl: usize = 0, @@ -132,7 +133,7 @@ fn defineBuiltin(pp: *Preprocessor, name: []const u8) !void { }); } -pub fn preprocess(pp: *Preprocessor, file_path: []const u8) !void { +pub fn preprocess(pp: *Preprocessor, file_path: Path) !void { const source = try pp.addSourceFromPath(file_path); try pp.preprocessFile(source); } @@ -789,13 +790,9 @@ fn makeGeneratedToken( return pasted_token; } -fn findInclude( - pp: *Preprocessor, - filename: []const u8, - includer_token: Token, -) !?Source { +fn findInclude(pp: *Preprocessor, filename: []const u8, includer_token: Token) !?Source { const other_file = pp.sources.values()[includer_token.source].path; - const dir = std.fs.path.dirname(other_file) orelse "."; + const dir: Path = other_file.dirname() orelse .cwd(); if (try pp.checkIncludeDir(filename, dir)) |res| return res; return pp.checkIncludeDir(filename, pp.include_dir); @@ -804,31 +801,24 @@ fn findInclude( fn checkIncludeDir( pp: *Preprocessor, include_path: []const u8, - include_dir: []const u8, + include_dir: Path, ) !?Source { - const format = "{s}{c}{s}"; var bfa_buf: [1024]u8 = undefined; var bfa_state: std.heap.BufferFirstAllocator = .init(&bfa_buf, pp.arena); const bfa = bfa_state.allocator(); - const header_path = try std.fmt.allocPrint(bfa, format, .{ - include_dir, - std.fs.path.sep, - include_path, - }); - defer bfa.free(header_path); - + const header_path = try include_dir.join(bfa, include_path); return pp.addSourceFromPath(header_path) catch |err| switch (err) { error.OutOfMemory => |e| return e, else => return null, }; } -pub fn addSourceFromPath(pp: *Preprocessor, path: []const u8) !Source { +pub fn addSourceFromPath(pp: *Preprocessor, path: Path) !Source { if (pp.sources.get(path)) |src| return src; try pp.sources.ensureUnusedCapacity(pp.arena, 1); - const contents = try std.Io.Dir.cwd().readFileAlloc(pp.io, path, pp.arena, .limited(std.math.maxInt(u32))); - const duped_path = try pp.arena.dupe(u8, path); + const contents = try path.root_dir.handle.readFileAlloc(pp.io, path.sub_path, pp.arena, .limited(std.math.maxInt(u32))); + const duped_path = try path.clone(pp.arena); const src: Source = .{ .buf = contents,