Skip to content

Commit 644f407

Browse files
committed
link: Simplify library path resolution logic
1 parent e15e70d commit 644f407

File tree

1 file changed

+31
-63
lines changed

1 file changed

+31
-63
lines changed

src/link.zig

Lines changed: 31 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -2136,29 +2136,43 @@ fn resolveLibInput(
21362136

21372137
const lib_name = name_query.name;
21382138

2139-
if (target.os.tag.isDarwin() and link_mode == .dynamic) tbd: {
2140-
// Prefer .tbd over .dylib.
2141-
const test_path: Path = .{
2142-
.root_dir = lib_directory,
2143-
.sub_path = try std.fmt.allocPrint(arena, "lib{s}.tbd", .{lib_name}),
2144-
};
2145-
try checked_paths.writer(gpa).print("\n {}", .{test_path});
2146-
var file = test_path.root_dir.handle.openFile(test_path.sub_path, .{}) catch |err| switch (err) {
2147-
error.FileNotFound => break :tbd,
2148-
else => |e| fatal("unable to search for tbd library '{}': {s}", .{ test_path, @errorName(e) }),
2139+
const LibPathPattern = struct {
2140+
prefix: []const u8,
2141+
suffix: []const u8,
2142+
};
2143+
const default_patterns = &[_]LibPathPattern{.{ .prefix = target.libPrefix(), .suffix = switch (link_mode) {
2144+
.static => target.staticLibSuffix(),
2145+
.dynamic => target.dynamicLibSuffix(),
2146+
} }};
2147+
var candidate_patterns: []const LibPathPattern = default_patterns;
2148+
2149+
if (target.os.tag.isDarwin() and link_mode == .dynamic) {
2150+
candidate_patterns =
2151+
// Prefer .tbd over .dylib.
2152+
[_]LibPathPattern{.{ .prefix = "lib", .suffix = ".tbd" }}
2153+
// In the case of Darwin, the main check will be .dylib
2154+
++ default_patterns
2155+
// Additionally check for .so files.
2156+
++ [_]LibPathPattern{.{ .prefix = "lib", .suffix = ".so" }};
2157+
} else if (target.isMinGW()) {
2158+
// In the case of MinGW, the main check will be `libfoo.dll` and `libfoo.a`, but we also need to
2159+
// look for `libfoo.dll.a`, `foo.dll` and `foo.lib`.
2160+
candidate_patterns = switch (link_mode) {
2161+
.dynamic => default_patterns ++ [_]LibPathPattern{
2162+
.{ .prefix = "lib", .suffix = ".dll.a" },
2163+
.{ .prefix = "", .suffix = ".dll" },
2164+
},
2165+
.static => default_patterns ++ [_]LibPathPattern{
2166+
.{ .prefix = "", .suffix = ".lib" },
2167+
},
21492168
};
2150-
errdefer file.close();
2151-
return finishResolveLibInput(resolved_inputs, test_path, file, link_mode, name_query.query);
21522169
}
21532170

2154-
{
2171+
for (candidate_patterns) |pattern| {
21552172
const test_path: Path = .{
21562173
.root_dir = lib_directory,
21572174
.sub_path = try std.fmt.allocPrint(arena, "{s}{s}{s}", .{
2158-
target.libPrefix(), lib_name, switch (link_mode) {
2159-
.static => target.staticLibSuffix(),
2160-
.dynamic => target.dynamicLibSuffix(),
2161-
},
2175+
pattern.prefix, lib_name, pattern.suffix,
21622176
}),
21632177
};
21642178
try checked_paths.writer(gpa).print("\n {}", .{test_path});
@@ -2171,52 +2185,6 @@ fn resolveLibInput(
21712185
}
21722186
}
21732187

2174-
// In the case of Darwin, the main check will be .dylib, so here we
2175-
// additionally check for .so files.
2176-
if (target.os.tag.isDarwin() and link_mode == .dynamic) so: {
2177-
const test_path: Path = .{
2178-
.root_dir = lib_directory,
2179-
.sub_path = try std.fmt.allocPrint(arena, "lib{s}.so", .{lib_name}),
2180-
};
2181-
try checked_paths.writer(gpa).print("\n {}", .{test_path});
2182-
var file = test_path.root_dir.handle.openFile(test_path.sub_path, .{}) catch |err| switch (err) {
2183-
error.FileNotFound => break :so,
2184-
else => |e| fatal("unable to search for so library '{}': {s}", .{
2185-
test_path, @errorName(e),
2186-
}),
2187-
};
2188-
errdefer file.close();
2189-
return finishResolveLibInput(resolved_inputs, test_path, file, link_mode, name_query.query);
2190-
}
2191-
2192-
// In the case of MinGW, the main check will be `libfoo.dll` and `libfoo.a`, but we also need to
2193-
// look for `foo.dll`, `foo.lib` and `libfoo.dll.a`.
2194-
if (target.isMinGW()) {
2195-
const sub_paths = if (link_mode == .dynamic)
2196-
&[_][]const u8{
2197-
try std.fmt.allocPrint(arena, "lib{s}.dll.a", .{lib_name}),
2198-
try std.fmt.allocPrint(arena, "{s}.dll", .{lib_name}),
2199-
try std.fmt.allocPrint(arena, "{s}.lib", .{lib_name}),
2200-
}
2201-
else
2202-
&[_][]const u8{
2203-
try std.fmt.allocPrint(arena, "{s}.lib", .{lib_name}),
2204-
};
2205-
for (sub_paths) |sub_path| {
2206-
const test_path: Path = .{
2207-
.root_dir = lib_directory,
2208-
.sub_path = sub_path,
2209-
};
2210-
try checked_paths.writer(gpa).print("\n {}", .{test_path});
2211-
var file = test_path.root_dir.handle.openFile(test_path.sub_path, .{}) catch |err| switch (err) {
2212-
error.FileNotFound => continue,
2213-
else => |e| fatal("unable to search for {s} library '{}': {s}", .{ @tagName(link_mode), test_path, @errorName(e) }),
2214-
};
2215-
errdefer file.close();
2216-
return finishResolveLibInput(resolved_inputs, test_path, file, link_mode, name_query.query);
2217-
}
2218-
}
2219-
22202188
return .no_match;
22212189
}
22222190

0 commit comments

Comments
 (0)