authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-10-23 22:39:57-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2023-10-23 22:39:57-04:00
log794dc694b140908a9affc5b449cda09bbe971cfe
treeb654e9bfafeb399e8e3355a523b22e7d40f29660
parenta07f288eb1772ac25fd0785b142c6ee7e09b2986
parent2bb713ca1cc66b7c56b2d7a4187095da91be8738
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #17686 from ziglang/elf-non-nixos

elf: fix linking against system libc libs

1 files changed, 46 insertions(+), 48 deletions(-)

src/link/Elf.zig+46-48
...@@ -1318,15 +1318,8 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node...@@ -1318,15 +1318,8 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
1318 defer test_path.deinit();1318 defer test_path.deinit();
1319 for (self.base.options.lib_dirs) |lib_dir_path| {1319 for (self.base.options.lib_dirs) |lib_dir_path| {
1320 for (self.base.options.system_libs.keys()) |link_lib| {1320 for (self.base.options.system_libs.keys()) |link_lib| {
1321 test_path.clearRetainingCapacity();1321 if (!(try self.accessLibPath(&test_path, null, lib_dir_path, link_lib, .Dynamic)))
1322 const sep = fs.path.sep_str;1322 continue;
1323 try test_path.writer().print("{s}" ++ sep ++ "lib{s}.so", .{
1324 lib_dir_path, link_lib,
1325 });
1326 fs.cwd().access(test_path.items, .{}) catch |err| switch (err) {
1327 error.FileNotFound => continue,
1328 else => |e| return e,
1329 };
1330 _ = try rpath_table.put(lib_dir_path, {});1323 _ = try rpath_table.put(lib_dir_path, {});
1331 }1324 }
1332 }1325 }
...@@ -1392,11 +1385,33 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node...@@ -1392,11 +1385,33 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
1392 if (self.base.options.libc_installation) |lc| {1385 if (self.base.options.libc_installation) |lc| {
1393 const flags = target_util.libcFullLinkFlags(target);1386 const flags = target_util.libcFullLinkFlags(target);
1394 try system_libs.ensureUnusedCapacity(flags.len);1387 try system_libs.ensureUnusedCapacity(flags.len);
1388
1389 var test_path = std.ArrayList(u8).init(arena);
1390 var checked_paths = std.ArrayList([]const u8).init(arena);
1391
1395 for (flags) |flag| {1392 for (flags) |flag| {
1396 const lib_path = try std.fmt.allocPrint(arena, "{s}{c}lib{s}.so", .{1393 checked_paths.clearRetainingCapacity();
1397 lc.crt_dir.?, fs.path.sep, flag["-l".len..],1394 const lib_name = flag["-l".len..];
1398 });1395
1399 system_libs.appendAssumeCapacity(.{ .path = lib_path });1396 success: {
1397 if (!self.isStatic()) {
1398 if (try self.accessLibPath(&test_path, &checked_paths, lc.crt_dir.?, lib_name, .Dynamic))
1399 break :success;
1400 }
1401 if (try self.accessLibPath(&test_path, &checked_paths, lc.crt_dir.?, lib_name, .Static))
1402 break :success;
1403
1404 try self.reportMissingLibraryError(
1405 checked_paths.items,
1406 "missing system library: '{s}' was not found",
1407 .{lib_name},
1408 );
1409
1410 continue;
1411 }
1412
1413 const resolved_path = try arena.dupe(u8, test_path.items);
1414 system_libs.appendAssumeCapacity(.{ .path = resolved_path });
1400 }1415 }
1401 } else if (target.isGnuLibC()) {1416 } else if (target.isGnuLibC()) {
1402 try system_libs.ensureUnusedCapacity(glibc.libs.len + 1);1417 try system_libs.ensureUnusedCapacity(glibc.libs.len + 1);
...@@ -1422,10 +1437,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node...@@ -1422,10 +1437,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
14221437
1423 for (system_libs.items) |lib| {1438 for (system_libs.items) |lib| {
1424 var parse_ctx: ParseErrorCtx = .{ .detected_cpu_arch = undefined };1439 var parse_ctx: ParseErrorCtx = .{ .detected_cpu_arch = undefined };
1425 const in_file = std.fs.cwd().openFile(lib.path, .{}) catch |err| {1440 const in_file = try std.fs.cwd().openFile(lib.path, .{});
1426 try self.handleAndReportParseError(lib.path, err, &parse_ctx);
1427 continue;
1428 };
1429 defer in_file.close();1441 defer in_file.close();
1430 self.parseLibrary(in_file, lib, false, &parse_ctx) catch |err|1442 self.parseLibrary(in_file, lib, false, &parse_ctx) catch |err|
1431 try self.handleAndReportParseError(lib.path, err, &parse_ctx);1443 try self.handleAndReportParseError(lib.path, err, &parse_ctx);
...@@ -1832,15 +1844,6 @@ fn parseLdScript(self: *Elf, in_file: std.fs.File, lib: SystemLib, ctx: *ParseEr...@@ -1832,15 +1844,6 @@ fn parseLdScript(self: *Elf, in_file: std.fs.File, lib: SystemLib, ctx: *ParseEr
1832 if (try self.accessLibPath(&test_path, &checked_paths, lib_dir, lib_name, .Static))1844 if (try self.accessLibPath(&test_path, &checked_paths, lib_dir, lib_name, .Static))
1833 break :success;1845 break :success;
1834 }1846 }
1835
1836 try self.reportMissingLibraryError(
1837 checked_paths.items,
1838 "missing library dependency: GNU ld script '{s}' requires '{s}', but file not found",
1839 .{
1840 lib.path,
1841 scr_obj.path,
1842 },
1843 );
1844 } else {1847 } else {
1845 var buffer: [fs.MAX_PATH_BYTES]u8 = undefined;1848 var buffer: [fs.MAX_PATH_BYTES]u8 = undefined;
1846 if (fs.realpath(scr_obj.path, &buffer)) |path| {1849 if (fs.realpath(scr_obj.path, &buffer)) |path| {
...@@ -1854,16 +1857,17 @@ fn parseLdScript(self: *Elf, in_file: std.fs.File, lib: SystemLib, ctx: *ParseEr...@@ -1854,16 +1857,17 @@ fn parseLdScript(self: *Elf, in_file: std.fs.File, lib: SystemLib, ctx: *ParseEr
1854 if (try self.accessLibPath(&test_path, &checked_paths, lib_dir, scr_obj.path, null))1857 if (try self.accessLibPath(&test_path, &checked_paths, lib_dir, scr_obj.path, null))
1855 break :success;1858 break :success;
1856 }1859 }
1857
1858 try self.reportMissingLibraryError(
1859 checked_paths.items,
1860 "missing library dependency: GNU ld script '{s}' requires '{s}', but file not found",
1861 .{
1862 lib.path,
1863 scr_obj.path,
1864 },
1865 );
1866 }1860 }
1861
1862 try self.reportMissingLibraryError(
1863 checked_paths.items,
1864 "missing library dependency: GNU ld script '{s}' requires '{s}', but file not found",
1865 .{
1866 lib.path,
1867 scr_obj.path,
1868 },
1869 );
1870 continue;
1867 }1871 }
18681872
1869 const full_path = test_path.items;1873 const full_path = test_path.items;
...@@ -1881,7 +1885,7 @@ fn parseLdScript(self: *Elf, in_file: std.fs.File, lib: SystemLib, ctx: *ParseEr...@@ -1881,7 +1885,7 @@ fn parseLdScript(self: *Elf, in_file: std.fs.File, lib: SystemLib, ctx: *ParseEr
1881fn accessLibPath(1885fn accessLibPath(
1882 self: *Elf,1886 self: *Elf,
1883 test_path: *std.ArrayList(u8),1887 test_path: *std.ArrayList(u8),
1884 checked_paths: *std.ArrayList([]const u8),1888 checked_paths: ?*std.ArrayList([]const u8),
1885 lib_dir_path: []const u8,1889 lib_dir_path: []const u8,
1886 lib_name: []const u8,1890 lib_name: []const u8,
1887 link_mode: ?std.builtin.LinkMode,1891 link_mode: ?std.builtin.LinkMode,
...@@ -1898,7 +1902,9 @@ fn accessLibPath(...@@ -1898,7 +1902,9 @@ fn accessLibPath(
1898 .Dynamic => target.dynamicLibSuffix(),1902 .Dynamic => target.dynamicLibSuffix(),
1899 } else "",1903 } else "",
1900 });1904 });
1901 try checked_paths.append(try self.base.allocator.dupe(u8, test_path.items));1905 if (checked_paths) |cpaths| {
1906 try cpaths.append(try self.base.allocator.dupe(u8, test_path.items));
1907 }
1902 fs.cwd().access(test_path.items, .{}) catch |err| switch (err) {1908 fs.cwd().access(test_path.items, .{}) catch |err| switch (err) {
1903 error.FileNotFound => return false,1909 error.FileNotFound => return false,
1904 else => |e| return e,1910 else => |e| return e,
...@@ -2532,19 +2538,11 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v...@@ -2532,19 +2538,11 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v
2532 }2538 }
25332539
2534 if (self.base.options.each_lib_rpath) {2540 if (self.base.options.each_lib_rpath) {
2535 var test_path = std.ArrayList(u8).init(self.base.allocator);2541 var test_path = std.ArrayList(u8).init(arena);
2536 defer test_path.deinit();
2537 for (self.base.options.lib_dirs) |lib_dir_path| {2542 for (self.base.options.lib_dirs) |lib_dir_path| {
2538 for (self.base.options.system_libs.keys()) |link_lib| {2543 for (self.base.options.system_libs.keys()) |link_lib| {
2539 test_path.clearRetainingCapacity();2544 if (!(try self.accessLibPath(&test_path, null, lib_dir_path, link_lib, .Dynamic)))
2540 const sep = fs.path.sep_str;2545 continue;
2541 try test_path.writer().print("{s}" ++ sep ++ "lib{s}.so", .{
2542 lib_dir_path, link_lib,
2543 });
2544 fs.cwd().access(test_path.items, .{}) catch |err| switch (err) {
2545 error.FileNotFound => continue,
2546 else => |e| return e,
2547 };
2548 if ((try rpath_table.fetchPut(lib_dir_path, {})) == null) {2546 if ((try rpath_table.fetchPut(lib_dir_path, {})) == null) {
2549 try argv.append("-rpath");2547 try argv.append("-rpath");
2550 try argv.append(lib_dir_path);2548 try argv.append(lib_dir_path);