| ... | @@ -25,6 +25,7 @@ const lldMain = @import("main.zig").lldMain; | ... | @@ -25,6 +25,7 @@ const lldMain = @import("main.zig").lldMain; |
| 25 | const Package = @import("Package.zig"); | 25 | const Package = @import("Package.zig"); |
| 26 | const dev = @import("dev.zig"); | 26 | const dev = @import("dev.zig"); |
| 27 | const ThreadSafeQueue = @import("ThreadSafeQueue.zig").ThreadSafeQueue; | 27 | const ThreadSafeQueue = @import("ThreadSafeQueue.zig").ThreadSafeQueue; |
| | 28 | const target_util = @import("target.zig"); |
| 28 | | 29 | |
| 29 | pub const LdScript = @import("link/LdScript.zig"); | 30 | pub const LdScript = @import("link/LdScript.zig"); |
| 30 | | 31 | |
| ... | @@ -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 already | 1365 | /// 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_diags | 1442 | 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 | } |
| 1875 | | 1919 | |
| 1876 | const AccessLibPathResult = enum { ok, no_match }; | 1920 | const ResolveLibInputResult = enum { ok, no_match }; |
| 1877 | const fatal = std.process.fatal; | 1921 | const fatal = std.process.fatal; |
| 1878 | | 1922 | |
| 1879 | fn resolveLibInput( | 1923 | fn 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); |
| 1897 | | 1941 | |
| 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 | } |
| 1914 | | 1958 | |
| 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 | } |
| 1952 | | 1996 | |
| 1953 | // In the case of MinGW, the main check will be .lib but we also need to | 1997 | // 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 | } |
| 1968 | | 2012 | |
| 1969 | return .no_match; | 2013 | return .no_match; |
| 1970 | } | 2014 | } |
| 1971 | | 2015 | |
| 1972 | fn finishAccessLibPath( | 2016 | fn 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); |
| 2057 | | 2101 | |
| 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 | } |
| 2145 | | 2189 | |
| 2146 | pub fn openObject(path: Path, must_link: bool, hidden: bool) !Input.Object { | 2190 | pub fn openObject(path: Path, must_link: bool, hidden: bool) !Input.Object { |