Commit 9b6f39c3a0

Jakub Konka <kubkon@jakubkonka.com>
2023-10-23 18:18:03
elf: when looking for system libs, check .so and .a, and access path
1 parent 4bf27da
Changed files (1)
src
link
src/link/Elf.zig
@@ -1392,11 +1392,33 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
         if (self.base.options.libc_installation) |lc| {
             const flags = target_util.libcFullLinkFlags(target);
             try system_libs.ensureUnusedCapacity(flags.len);
+
+            var test_path = std.ArrayList(u8).init(arena);
+            var checked_paths = std.ArrayList([]const u8).init(arena);
+
             for (flags) |flag| {
-                const lib_path = try std.fmt.allocPrint(arena, "{s}{c}lib{s}.so", .{
-                    lc.crt_dir.?, fs.path.sep, flag["-l".len..],
-                });
-                system_libs.appendAssumeCapacity(.{ .path = lib_path });
+                checked_paths.clearRetainingCapacity();
+                const lib_name = flag["-l".len..];
+
+                success: {
+                    if (!self.isStatic()) {
+                        if (try self.accessLibPath(&test_path, &checked_paths, lc.crt_dir.?, lib_name, .Dynamic))
+                            break :success;
+                    }
+                    if (try self.accessLibPath(&test_path, &checked_paths, lc.crt_dir.?, lib_name, .Static))
+                        break :success;
+
+                    try self.reportMissingLibraryError(
+                        checked_paths.items,
+                        "missing system library: '{s}' was not found",
+                        .{lib_name},
+                    );
+
+                    continue;
+                }
+
+                const resolved_path = try arena.dupe(u8, test_path.items);
+                system_libs.appendAssumeCapacity(.{ .path = resolved_path });
             }
         } else if (target.isGnuLibC()) {
             try system_libs.ensureUnusedCapacity(glibc.libs.len + 1);
@@ -1422,10 +1444,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
 
     for (system_libs.items) |lib| {
         var parse_ctx: ParseErrorCtx = .{ .detected_cpu_arch = undefined };
-        const in_file = std.fs.cwd().openFile(lib.path, .{}) catch |err| {
-            try self.handleAndReportParseError(lib.path, err, &parse_ctx);
-            continue;
-        };
+        const in_file = try std.fs.cwd().openFile(lib.path, .{});
         defer in_file.close();
         self.parseLibrary(in_file, lib, false, &parse_ctx) catch |err|
             try self.handleAndReportParseError(lib.path, err, &parse_ctx);
@@ -1832,15 +1851,6 @@ fn parseLdScript(self: *Elf, in_file: std.fs.File, lib: SystemLib, ctx: *ParseEr
                     if (try self.accessLibPath(&test_path, &checked_paths, lib_dir, lib_name, .Static))
                         break :success;
                 }
-
-                try self.reportMissingLibraryError(
-                    checked_paths.items,
-                    "missing library dependency: GNU ld script '{s}' requires '{s}', but file not found",
-                    .{
-                        lib.path,
-                        scr_obj.path,
-                    },
-                );
             } else {
                 var buffer: [fs.MAX_PATH_BYTES]u8 = undefined;
                 if (fs.realpath(scr_obj.path, &buffer)) |path| {
@@ -1854,16 +1864,17 @@ fn parseLdScript(self: *Elf, in_file: std.fs.File, lib: SystemLib, ctx: *ParseEr
                     if (try self.accessLibPath(&test_path, &checked_paths, lib_dir, scr_obj.path, null))
                         break :success;
                 }
-
-                try self.reportMissingLibraryError(
-                    checked_paths.items,
-                    "missing library dependency: GNU ld script '{s}' requires '{s}', but file not found",
-                    .{
-                        lib.path,
-                        scr_obj.path,
-                    },
-                );
             }
+
+            try self.reportMissingLibraryError(
+                checked_paths.items,
+                "missing library dependency: GNU ld script '{s}' requires '{s}', but file not found",
+                .{
+                    lib.path,
+                    scr_obj.path,
+                },
+            );
+            continue;
         }
 
         const full_path = test_path.items;