From 38e233845ef7fa5c8ccb2cd3ce053d1827f9ee42 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Mon, 7 Jun 2021 18:21:35 -0700 Subject: link: windows: look for more DLL import lib path names When linking with -lfoo syntax, this indicates to Zig that the dependency should either be provided by Zig, or it should be dynamically provided by the system. For windows-gnu targets, the search path was "foo.lib". Now it additionally looks for "libfoo.dll.a". Closes #7799 --- src/link/Coff.zig | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/link/Coff.zig b/src/link/Coff.zig index 983e78e9e9..9ab1c6d78a 100644 --- a/src/link/Coff.zig +++ b/src/link/Coff.zig @@ -1221,13 +1221,26 @@ fn linkWithLLD(self: *Coff, comp: *Compilation) !void { try argv.append(comp.compiler_rt_static_lib.?.full_object_path); } + try argv.ensureUnusedCapacity(self.base.options.system_libs.count()); for (self.base.options.system_libs.keys()) |key| { const lib_basename = try allocPrint(arena, "{s}.lib", .{key}); if (comp.crt_files.get(lib_basename)) |crt_file| { - try argv.append(crt_file.full_object_path); - } else { - try argv.append(lib_basename); + argv.appendAssumeCapacity(crt_file.full_object_path); + continue; + } + if (try self.findLib(arena, lib_basename)) |full_path| { + argv.appendAssumeCapacity(full_path); + continue; + } + if (target.abi.isGnu()) { + const fallback_name = try allocPrint(arena, "lib{s}.dll.a", .{key}); + if (try self.findLib(arena, fallback_name)) |full_path| { + argv.appendAssumeCapacity(full_path); + continue; + } } + log.err("DLL import library for -l{s} not found", .{key}); + return error.DllImportLibraryNotFound; } if (self.base.options.verbose_link) { @@ -1309,6 +1322,18 @@ fn linkWithLLD(self: *Coff, comp: *Compilation) !void { } } +fn findLib(self: *Coff, arena: *Allocator, name: []const u8) !?[]const u8 { + for (self.base.options.lib_dirs) |lib_dir| { + const full_path = try fs.path.join(arena, &.{ lib_dir, name }); + fs.cwd().access(full_path, .{}) catch |err| switch (err) { + error.FileNotFound => continue, + else => |e| return e, + }; + return full_path; + } + return null; +} + pub fn getDeclVAddr(self: *Coff, decl: *const Module.Decl) u64 { assert(self.llvm_object == null); return self.text_section_virtual_address + decl.link.coff.text_offset; -- cgit v1.2.3