authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-10-21 15:40:41-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-10-23 16:27:39-07:00
log5d75d8f6fc026948aa02309bd820fc15206288e0
treef51698731964244bdf5f88b61104b5eb949b41f1
parent2d8ea78249c85552225db8f50b45e2e71ba85a41

also find static libc files on the host

and don't look for glibc files on windows

3 files changed, 62 insertions(+), 35 deletions(-)

src/Compilation.zig+3-21
...@@ -1780,32 +1780,14 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil...@@ -1780,32 +1780,14 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
1780 const paths = try lci.resolveCrtPaths(arena, basenames, target);1780 const paths = try lci.resolveCrtPaths(arena, basenames, target);
17811781
1782 const fields = @typeInfo(@TypeOf(paths)).@"struct".fields;1782 const fields = @typeInfo(@TypeOf(paths)).@"struct".fields;
1783 try comp.link_task_queue.shared.ensureUnusedCapacity(gpa, fields.len);1783 try comp.link_task_queue.shared.ensureUnusedCapacity(gpa, fields.len + 1);
1784 inline for (fields) |field| {1784 inline for (fields) |field| {
1785 if (@field(paths, field.name)) |path| {1785 if (@field(paths, field.name)) |path| {
1786 comp.link_task_queue.shared.appendAssumeCapacity(.{ .load_object = path });1786 comp.link_task_queue.shared.appendAssumeCapacity(.{ .load_object = path });
1787 }1787 }
1788 }1788 }
17891789 // Loads the libraries provided by `target_util.libcFullLinkFlags(target)`.
1790 const flags = target_util.libcFullLinkFlags(target);1790 comp.link_task_queue.shared.appendAssumeCapacity(.load_host_libc);
1791 try comp.link_task_queue.shared.ensureUnusedCapacity(gpa, flags.len);
1792 for (flags) |flag| {
1793 assert(mem.startsWith(u8, flag, "-l"));
1794 const lib_name = flag["-l".len..];
1795 const suffix = switch (comp.config.link_mode) {
1796 .static => target.staticLibSuffix(),
1797 .dynamic => target.dynamicLibSuffix(),
1798 };
1799 const sep = std.fs.path.sep_str;
1800 const lib_path = try std.fmt.allocPrint(arena, "{s}" ++ sep ++ "lib{s}{s}", .{
1801 lci.crt_dir.?, lib_name, suffix,
1802 });
1803 const resolved_path = Path.initCwd(lib_path);
1804 comp.link_task_queue.shared.appendAssumeCapacity(switch (comp.config.link_mode) {
1805 .static => .{ .load_archive = resolved_path },
1806 .dynamic => .{ .load_dso = resolved_path },
1807 });
1808 }
1809 } else if (target.isMusl() and !target.isWasm()) {1791 } else if (target.isMusl() and !target.isWasm()) {
1810 if (!std.zig.target.canBuildLibC(target)) return error.LibCUnavailable;1792 if (!std.zig.target.canBuildLibC(target)) return error.LibCUnavailable;
18111793
src/link.zig+54-10
...@@ -25,6 +25,7 @@ const lldMain = @import("main.zig").lldMain;...@@ -25,6 +25,7 @@ const lldMain = @import("main.zig").lldMain;
25const Package = @import("Package.zig");25const Package = @import("Package.zig");
26const dev = @import("dev.zig");26const dev = @import("dev.zig");
27const ThreadSafeQueue = @import("ThreadSafeQueue.zig").ThreadSafeQueue;27const ThreadSafeQueue = @import("ThreadSafeQueue.zig").ThreadSafeQueue;
28const target_util = @import("target.zig");
2829
29pub const LdScript = @import("link/LdScript.zig");30pub const LdScript = @import("link/LdScript.zig");
3031
...@@ -1364,6 +1365,10 @@ pub const File = struct {...@@ -1364,6 +1365,10 @@ pub const File = struct {
1364 /// Loads the objects, shared objects, and archives that are already1365 /// Loads the objects, shared objects, and archives that are already
1365 /// known from the command line.1366 /// known from the command line.
1366 load_explicitly_provided,1367 load_explicitly_provided,
1368 /// Loads the shared objects and archives by resolving
1369 /// `target_util.libcFullLinkFlags()` against the host libc
1370 /// installation.
1371 load_host_libc,
1367 /// Tells the linker to load an object file by path.1372 /// Tells the linker to load an object file by path.
1368 load_object: Path,1373 load_object: Path,
1369 /// Tells the linker to load a static library by path.1374 /// Tells the linker to load a static library by path.
...@@ -1393,6 +1398,45 @@ pub const File = struct {...@@ -1393,6 +1398,45 @@ pub const File = struct {
1393 };1398 };
1394 }1399 }
1395 },1400 },
1401 .load_host_libc => {
1402 const target = comp.root_mod.resolved_target.result;
1403 const flags = target_util.libcFullLinkFlags(target);
1404 const crt_dir = comp.libc_installation.?.crt_dir.?;
1405 const sep = std.fs.path.sep_str;
1406 const diags = &comp.link_diags;
1407 for (flags) |flag| {
1408 assert(mem.startsWith(u8, flag, "-l"));
1409 const lib_name = flag["-l".len..];
1410 switch (comp.config.link_mode) {
1411 .dynamic => d: {
1412 const path = Path.initCwd(
1413 std.fmt.allocPrint(comp.arena, "{s}" ++ sep ++ "{s}{s}{s}", .{
1414 crt_dir, target.libPrefix(), lib_name, target.dynamicLibSuffix(),
1415 }) catch return diags.setAllocFailure(),
1416 );
1417 base.openLoadDso(path, .{
1418 .preferred_mode = .dynamic,
1419 .search_strategy = .paths_first,
1420 }) catch |err| switch (err) {
1421 error.FileNotFound => break :d, // also try static
1422 error.LinkFailure => return, // error reported via diags
1423 else => |e| diags.addParseError(path, "failed to parse shared library: {s}", .{@errorName(e)}),
1424 };
1425 continue;
1426 },
1427 .static => {},
1428 }
1429 const path = Path.initCwd(
1430 std.fmt.allocPrint(comp.arena, "{s}" ++ sep ++ "{s}{s}{s}", .{
1431 crt_dir, target.libPrefix(), lib_name, target.staticLibSuffix(),
1432 }) catch return diags.setAllocFailure(),
1433 );
1434 base.openLoadArchive(path) catch |err| switch (err) {
1435 error.LinkFailure => return, // error reported via diags
1436 else => |e| diags.addParseError(path, "failed to parse archive: {s}", .{@errorName(e)}),
1437 };
1438 }
1439 },
1396 .load_object => |path| {1440 .load_object => |path| {
1397 base.openLoadObject(path) catch |err| switch (err) {1441 base.openLoadObject(path) catch |err| switch (err) {
1398 error.LinkFailure => return, // error reported via link_diags1442 error.LinkFailure => return, // error reported via link_diags
...@@ -1873,7 +1917,7 @@ pub fn resolveInputs(...@@ -1873,7 +1917,7 @@ pub fn resolveInputs(
1873 }1917 }
1874}1918}
18751919
1876const AccessLibPathResult = enum { ok, no_match };1920const ResolveLibInputResult = enum { ok, no_match };
1877const fatal = std.process.fatal;1921const fatal = std.process.fatal;
18781922
1879fn resolveLibInput(1923fn resolveLibInput(
...@@ -1892,7 +1936,7 @@ fn resolveLibInput(...@@ -1892,7 +1936,7 @@ fn resolveLibInput(
1892 target: std.Target,1936 target: std.Target,
1893 link_mode: std.builtin.LinkMode,1937 link_mode: std.builtin.LinkMode,
1894 color: std.zig.Color,1938 color: std.zig.Color,
1895) Allocator.Error!AccessLibPathResult {1939) Allocator.Error!ResolveLibInputResult {
1896 try resolved_inputs.ensureUnusedCapacity(gpa, 1);1940 try resolved_inputs.ensureUnusedCapacity(gpa, 1);
18971941
1898 const lib_name = name_query.name;1942 const lib_name = name_query.name;
...@@ -1909,7 +1953,7 @@ fn resolveLibInput(...@@ -1909,7 +1953,7 @@ fn resolveLibInput(
1909 else => |e| fatal("unable to search for tbd library '{}': {s}", .{ test_path, @errorName(e) }),1953 else => |e| fatal("unable to search for tbd library '{}': {s}", .{ test_path, @errorName(e) }),
1910 };1954 };
1911 errdefer file.close();1955 errdefer file.close();
1912 return finishAccessLibPath(resolved_inputs, test_path, file, link_mode, name_query.query);1956 return finishResolveLibInput(resolved_inputs, test_path, file, link_mode, name_query.query);
1913 }1957 }
19141958
1915 {1959 {
...@@ -1947,7 +1991,7 @@ fn resolveLibInput(...@@ -1947,7 +1991,7 @@ fn resolveLibInput(
1947 }),1991 }),
1948 };1992 };
1949 errdefer file.close();1993 errdefer file.close();
1950 return finishAccessLibPath(resolved_inputs, test_path, file, link_mode, name_query.query);1994 return finishResolveLibInput(resolved_inputs, test_path, file, link_mode, name_query.query);
1951 }1995 }
19521996
1953 // In the case of MinGW, the main check will be .lib but we also need to1997 // In the case of MinGW, the main check will be .lib but we also need to
...@@ -1963,19 +2007,19 @@ fn resolveLibInput(...@@ -1963,19 +2007,19 @@ fn resolveLibInput(
1963 else => |e| fatal("unable to search for static library '{}': {s}", .{ test_path, @errorName(e) }),2007 else => |e| fatal("unable to search for static library '{}': {s}", .{ test_path, @errorName(e) }),
1964 };2008 };
1965 errdefer file.close();2009 errdefer file.close();
1966 return finishAccessLibPath(resolved_inputs, test_path, file, link_mode, name_query.query);2010 return finishResolveLibInput(resolved_inputs, test_path, file, link_mode, name_query.query);
1967 }2011 }
19682012
1969 return .no_match;2013 return .no_match;
1970}2014}
19712015
1972fn finishAccessLibPath(2016fn finishResolveLibInput(
1973 resolved_inputs: *std.ArrayListUnmanaged(Input),2017 resolved_inputs: *std.ArrayListUnmanaged(Input),
1974 path: Path,2018 path: Path,
1975 file: std.fs.File,2019 file: std.fs.File,
1976 link_mode: std.builtin.LinkMode,2020 link_mode: std.builtin.LinkMode,
1977 query: UnresolvedInput.Query,2021 query: UnresolvedInput.Query,
1978) AccessLibPathResult {2022) ResolveLibInputResult {
1979 switch (link_mode) {2023 switch (link_mode) {
1980 .static => resolved_inputs.appendAssumeCapacity(.{ .archive = .{2024 .static => resolved_inputs.appendAssumeCapacity(.{ .archive = .{
1981 .path = path,2025 .path = path,
...@@ -2052,7 +2096,7 @@ fn resolvePathInputLib(...@@ -2052,7 +2096,7 @@ fn resolvePathInputLib(
2052 pq: UnresolvedInput.PathQuery,2096 pq: UnresolvedInput.PathQuery,
2053 link_mode: std.builtin.LinkMode,2097 link_mode: std.builtin.LinkMode,
2054 color: std.zig.Color,2098 color: std.zig.Color,
2055) Allocator.Error!AccessLibPathResult {2099) Allocator.Error!ResolveLibInputResult {
2056 try resolved_inputs.ensureUnusedCapacity(gpa, 1);2100 try resolved_inputs.ensureUnusedCapacity(gpa, 1);
20572101
2058 const test_path: Path = pq.path;2102 const test_path: Path = pq.path;
...@@ -2074,7 +2118,7 @@ fn resolvePathInputLib(...@@ -2074,7 +2118,7 @@ fn resolvePathInputLib(
2074 if (n != ld_script_bytes.items.len) break :elf_file;2118 if (n != ld_script_bytes.items.len) break :elf_file;
2075 if (!mem.eql(u8, ld_script_bytes.items[0..4], "\x7fELF")) break :elf_file;2119 if (!mem.eql(u8, ld_script_bytes.items[0..4], "\x7fELF")) break :elf_file;
2076 // Appears to be an ELF file.2120 // Appears to be an ELF file.
2077 return finishAccessLibPath(resolved_inputs, test_path, file, link_mode, pq.query);2121 return finishResolveLibInput(resolved_inputs, test_path, file, link_mode, pq.query);
2078 }2122 }
2079 const stat = file.stat() catch |err|2123 const stat = file.stat() catch |err|
2080 fatal("failed to stat {}: {s}", .{ test_path, @errorName(err) });2124 fatal("failed to stat {}: {s}", .{ test_path, @errorName(err) });
...@@ -2140,7 +2184,7 @@ fn resolvePathInputLib(...@@ -2140,7 +2184,7 @@ fn resolvePathInputLib(
2140 }),2184 }),
2141 };2185 };
2142 errdefer file.close();2186 errdefer file.close();
2143 return finishAccessLibPath(resolved_inputs, test_path, file, link_mode, pq.query);2187 return finishResolveLibInput(resolved_inputs, test_path, file, link_mode, pq.query);
2144}2188}
21452189
2146pub fn openObject(path: Path, must_link: bool, hidden: bool) !Input.Object {2190pub fn openObject(path: Path, must_link: bool, hidden: bool) !Input.Object {
src/target.zig+5-4
...@@ -291,10 +291,11 @@ pub fn libcFullLinkFlags(target: std.Target) []const []const u8 {...@@ -291,10 +291,11 @@ pub fn libcFullLinkFlags(target: std.Target) []const []const u8 {
291 // Solaris releases after 10 merged the threading libraries into libc.291 // Solaris releases after 10 merged the threading libraries into libc.
292 .solaris, .illumos => &.{ "-lm", "-lsocket", "-lnsl", "-lc" },292 .solaris, .illumos => &.{ "-lm", "-lsocket", "-lnsl", "-lc" },
293 .haiku => &.{ "-lm", "-lroot", "-lpthread", "-lc", "-lnetwork" },293 .haiku => &.{ "-lm", "-lroot", "-lpthread", "-lc", "-lnetwork" },
294 else => if (target.isAndroid() or target.abi.isOpenHarmony())294 .linux => switch (target.abi) {
295 &.{ "-lm", "-lc", "-ldl" }295 .android, .androideabi, .ohos, .ohoseabi => &.{ "-lm", "-lc", "-ldl" },
296 else296 else => &.{ "-lm", "-lpthread", "-lc", "-ldl", "-lrt", "-lutil" },
297 &.{ "-lm", "-lpthread", "-lc", "-ldl", "-lrt", "-lutil" },297 },
298 else => &.{},
298 };299 };
299 return result;300 return result;
300}301}