| ... | ... | @@ -668,6 +668,9 @@ fn buildOutputType( |
| 668 | 668 | var system_libs = std.StringArrayHashMap(Compilation.SystemLib).init(gpa); |
| 669 | 669 | defer system_libs.deinit(); |
| 670 | 670 | |
| 671 | var static_libs = std.ArrayList([]const u8).init(gpa); |
| 672 | defer static_libs.deinit(); |
| 673 | |
| 671 | 674 | var wasi_emulated_libs = std.ArrayList(wasi_libc.CRTFile).init(gpa); |
| 672 | 675 | defer wasi_emulated_libs.deinit(); |
| 673 | 676 | |
| ... | ... | @@ -1253,6 +1256,7 @@ fn buildOutputType( |
| 1253 | 1256 | var it = ClangArgIterator.init(arena, all_args); |
| 1254 | 1257 | var emit_llvm = false; |
| 1255 | 1258 | var needed = false; |
| 1259 | var force_static_libs = false; |
| 1256 | 1260 | while (it.has_next) { |
| 1257 | 1261 | it.next() catch |err| { |
| 1258 | 1262 | fatal("unable to parse command line parameters: {s}", .{@errorName(err)}); |
| ... | ... | @@ -1287,7 +1291,11 @@ fn buildOutputType( |
| 1287 | 1291 | // -l |
| 1288 | 1292 | // We don't know whether this library is part of libc or libc++ until |
| 1289 | 1293 | // we resolve the target, so we simply append to the list for now. |
| 1290 | | try system_libs.put(it.only_arg, .{ .needed = needed }); |
| 1294 | if (force_static_libs) { |
| 1295 | try static_libs.append(it.only_arg); |
| 1296 | } else { |
| 1297 | try system_libs.put(it.only_arg, .{ .needed = needed }); |
| 1298 | } |
| 1291 | 1299 | }, |
| 1292 | 1300 | .ignore => {}, |
| 1293 | 1301 | .driver_punt => { |
| ... | ... | @@ -1333,6 +1341,17 @@ fn buildOutputType( |
| 1333 | 1341 | needed = false; |
| 1334 | 1342 | } else if (mem.eql(u8, linker_arg, "--no-as-needed")) { |
| 1335 | 1343 | needed = true; |
| 1344 | } else if (mem.eql(u8, linker_arg, "-Bdynamic") or |
| 1345 | mem.eql(u8, linker_arg, "-dy") or |
| 1346 | mem.eql(u8, linker_arg, "-call_shared")) |
| 1347 | { |
| 1348 | force_static_libs = false; |
| 1349 | } else if (mem.eql(u8, linker_arg, "-Bstatic") or |
| 1350 | mem.eql(u8, linker_arg, "-dn") or |
| 1351 | mem.eql(u8, linker_arg, "-non_shared") or |
| 1352 | mem.eql(u8, linker_arg, "-static")) |
| 1353 | { |
| 1354 | force_static_libs = true; |
| 1336 | 1355 | } else { |
| 1337 | 1356 | try linker_args.append(linker_arg); |
| 1338 | 1357 | } |
| ... | ... | @@ -1893,6 +1912,48 @@ fn buildOutputType( |
| 1893 | 1912 | } |
| 1894 | 1913 | } |
| 1895 | 1914 | |
| 1915 | { |
| 1916 | // Resolve static libraries into full paths. |
| 1917 | const sep = fs.path.sep_str; |
| 1918 | |
| 1919 | var test_path = std.ArrayList(u8).init(gpa); |
| 1920 | defer test_path.deinit(); |
| 1921 | |
| 1922 | for (static_libs.items) |static_lib| { |
| 1923 | for (lib_dirs.items) |lib_dir_path| { |
| 1924 | test_path.clearRetainingCapacity(); |
| 1925 | try test_path.writer().print("{s}" ++ sep ++ "{s}{s}{s}", .{ |
| 1926 | lib_dir_path, |
| 1927 | target_info.target.libPrefix(), |
| 1928 | static_lib, |
| 1929 | target_info.target.staticLibSuffix(), |
| 1930 | }); |
| 1931 | fs.cwd().access(test_path.items, .{}) catch |err| switch (err) { |
| 1932 | error.FileNotFound => continue, |
| 1933 | else => |e| fatal("unable to search for static library '{s}': {s}", .{ |
| 1934 | test_path.items, @errorName(e), |
| 1935 | }), |
| 1936 | }; |
| 1937 | try link_objects.append(try arena.dupe(u8, test_path.items)); |
| 1938 | break; |
| 1939 | } else { |
| 1940 | var search_paths = std.ArrayList(u8).init(arena); |
| 1941 | for (lib_dirs.items) |lib_dir_path| { |
| 1942 | try search_paths.writer().print("\n {s}" ++ sep ++ "{s}{s}{s}", .{ |
| 1943 | lib_dir_path, |
| 1944 | target_info.target.libPrefix(), |
| 1945 | static_lib, |
| 1946 | target_info.target.staticLibSuffix(), |
| 1947 | }); |
| 1948 | } |
| 1949 | try search_paths.appendSlice("\n suggestion: use full paths to static libraries on the command line rather than using -l and -L arguments"); |
| 1950 | fatal("static library '{s}' not found. search paths: {s}", .{ |
| 1951 | static_lib, search_paths.items, |
| 1952 | }); |
| 1953 | } |
| 1954 | } |
| 1955 | } |
| 1956 | |
| 1896 | 1957 | const object_format: std.Target.ObjectFormat = blk: { |
| 1897 | 1958 | const ofmt = target_ofmt orelse break :blk target_info.target.getObjectFormat(); |
| 1898 | 1959 | if (mem.eql(u8, ofmt, "elf")) { |