| ... | @@ -712,6 +712,14 @@ fn buildOutputType( | ... | @@ -712,6 +712,14 @@ fn buildOutputType( |
| 712 | var link_objects = std.ArrayList(Compilation.LinkObject).init(gpa); | 712 | var link_objects = std.ArrayList(Compilation.LinkObject).init(gpa); |
| 713 | defer link_objects.deinit(); | 713 | defer link_objects.deinit(); |
| 714 | | 714 | |
| | 715 | // This map is a flag per link_objects item, used to represent the |
| | 716 | // `-l :file.so` syntax from gcc/clang. |
| | 717 | // This is only exposed from the `zig cc` interface. It means that the `path` |
| | 718 | // field from the corresponding `link_objects` element is a suffix, and is |
| | 719 | // to be tried against each library path as a prefix until an existing file is found. |
| | 720 | // This map remains empty for the main CLI. |
| | 721 | var link_objects_lib_search_paths: std.AutoHashMapUnmanaged(u32, void) = .{}; |
| | 722 | |
| 715 | var framework_dirs = std.ArrayList([]const u8).init(gpa); | 723 | var framework_dirs = std.ArrayList([]const u8).init(gpa); |
| 716 | defer framework_dirs.deinit(); | 724 | defer framework_dirs.deinit(); |
| 717 | | 725 | |
| ... | @@ -1338,7 +1346,16 @@ fn buildOutputType( | ... | @@ -1338,7 +1346,16 @@ fn buildOutputType( |
| 1338 | // -l | 1346 | // -l |
| 1339 | // We don't know whether this library is part of libc or libc++ until | 1347 | // We don't know whether this library is part of libc or libc++ until |
| 1340 | // we resolve the target, so we simply append to the list for now. | 1348 | // we resolve the target, so we simply append to the list for now. |
| 1341 | if (force_static_libs) { | 1349 | if (mem.startsWith(u8, it.only_arg, ":")) { |
| | 1350 | // This "feature" of gcc/clang means to treat this as a positional |
| | 1351 | // link object, but using the library search directories as a prefix. |
| | 1352 | try link_objects.append(.{ |
| | 1353 | .path = it.only_arg[1..], |
| | 1354 | .must_link = must_link, |
| | 1355 | }); |
| | 1356 | const index = @intCast(u32, link_objects.items.len - 1); |
| | 1357 | try link_objects_lib_search_paths.put(arena, index, {}); |
| | 1358 | } else if (force_static_libs) { |
| 1342 | try static_libs.append(it.only_arg); | 1359 | try static_libs.append(it.only_arg); |
| 1343 | } else { | 1360 | } else { |
| 1344 | try system_libs.put(it.only_arg, .{ .needed = needed }); | 1361 | try system_libs.put(it.only_arg, .{ .needed = needed }); |
| ... | @@ -2137,6 +2154,30 @@ fn buildOutputType( | ... | @@ -2137,6 +2154,30 @@ fn buildOutputType( |
| 2137 | } | 2154 | } |
| 2138 | } | 2155 | } |
| 2139 | | 2156 | |
| | 2157 | // Resolve `-l :file.so` syntax from `zig cc`. We use a separate map for this data |
| | 2158 | // since this is an uncommon case. |
| | 2159 | { |
| | 2160 | var it = link_objects_lib_search_paths.iterator(); |
| | 2161 | while (it.next()) |item| { |
| | 2162 | const link_object_i = item.key_ptr.*; |
| | 2163 | const suffix = link_objects.items[link_object_i].path; |
| | 2164 | |
| | 2165 | for (lib_dirs.items) |lib_dir_path| { |
| | 2166 | const test_path = try fs.path.join(arena, &.{ lib_dir_path, suffix }); |
| | 2167 | fs.cwd().access(test_path, .{}) catch |err| switch (err) { |
| | 2168 | error.FileNotFound => continue, |
| | 2169 | else => |e| fatal("unable to search for library '{s}': {s}", .{ |
| | 2170 | test_path, @errorName(e), |
| | 2171 | }), |
| | 2172 | }; |
| | 2173 | link_objects.items[link_object_i].path = test_path; |
| | 2174 | break; |
| | 2175 | } else { |
| | 2176 | fatal("library '{s}' not found", .{suffix}); |
| | 2177 | } |
| | 2178 | } |
| | 2179 | } |
| | 2180 | |
| 2140 | const object_format: std.Target.ObjectFormat = blk: { | 2181 | const object_format: std.Target.ObjectFormat = blk: { |
| 2141 | const ofmt = target_ofmt orelse break :blk target_info.target.getObjectFormat(); | 2182 | const ofmt = target_ofmt orelse break :blk target_info.target.getObjectFormat(); |
| 2142 | if (mem.eql(u8, ofmt, "elf")) { | 2183 | if (mem.eql(u8, ofmt, "elf")) { |