diff options
Diffstat (limited to 'src/main.zig')
| -rw-r--r-- | src/main.zig | 43 |
1 files changed, 42 insertions, 1 deletions
diff --git a/src/main.zig b/src/main.zig index 12e9f88088..05afc2b166 100644 --- a/src/main.zig +++ b/src/main.zig @@ -712,6 +712,14 @@ fn buildOutputType( var link_objects = std.ArrayList(Compilation.LinkObject).init(gpa); defer link_objects.deinit(); + // This map is a flag per link_objects item, used to represent the + // `-l :file.so` syntax from gcc/clang. + // This is only exposed from the `zig cc` interface. It means that the `path` + // field from the corresponding `link_objects` element is a suffix, and is + // to be tried against each library path as a prefix until an existing file is found. + // This map remains empty for the main CLI. + var link_objects_lib_search_paths: std.AutoHashMapUnmanaged(u32, void) = .{}; + var framework_dirs = std.ArrayList([]const u8).init(gpa); defer framework_dirs.deinit(); @@ -1338,7 +1346,16 @@ fn buildOutputType( // -l // We don't know whether this library is part of libc or libc++ until // we resolve the target, so we simply append to the list for now. - if (force_static_libs) { + if (mem.startsWith(u8, it.only_arg, ":")) { + // This "feature" of gcc/clang means to treat this as a positional + // link object, but using the library search directories as a prefix. + try link_objects.append(.{ + .path = it.only_arg[1..], + .must_link = must_link, + }); + const index = @intCast(u32, link_objects.items.len - 1); + try link_objects_lib_search_paths.put(arena, index, {}); + } else if (force_static_libs) { try static_libs.append(it.only_arg); } else { try system_libs.put(it.only_arg, .{ .needed = needed }); @@ -2137,6 +2154,30 @@ fn buildOutputType( } } + // Resolve `-l :file.so` syntax from `zig cc`. We use a separate map for this data + // since this is an uncommon case. + { + var it = link_objects_lib_search_paths.iterator(); + while (it.next()) |item| { + const link_object_i = item.key_ptr.*; + const suffix = link_objects.items[link_object_i].path; + + for (lib_dirs.items) |lib_dir_path| { + const test_path = try fs.path.join(arena, &.{ lib_dir_path, suffix }); + fs.cwd().access(test_path, .{}) catch |err| switch (err) { + error.FileNotFound => continue, + else => |e| fatal("unable to search for library '{s}': {s}", .{ + test_path, @errorName(e), + }), + }; + link_objects.items[link_object_i].path = test_path; + break; + } else { + fatal("library '{s}' not found", .{suffix}); + } + } + } + const object_format: std.Target.ObjectFormat = blk: { const ofmt = target_ofmt orelse break :blk target_info.target.getObjectFormat(); if (mem.eql(u8, ofmt, "elf")) { |
