authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-02-15 17:32:20-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-02-15 17:36:12-07:00
log22f464a8c3d93e1c38244444ee49efb8648ba09d
tree1b130b50b5537eb016eee8701fe1fe58fba3e6b0
parent092b019a2feb6d7910c77a8dadc76b1ccc8dee53

zig cc: handle `-l :FILE` syntax

This "feature" of gcc/clang means to treat this as a positional link object, but using the library search directories as a prefix. We solve this problem in the CLI layer, using a separate map for the data since it is an uncommon case. Closes #10851

1 files changed, 42 insertions(+), 1 deletions(-)

src/main.zig+42-1
......@@ -712,6 +712,14 @@ fn buildOutputType(
712712 var link_objects = std.ArrayList(Compilation.LinkObject).init(gpa);
713713 defer link_objects.deinit();
714714
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
715723 var framework_dirs = std.ArrayList([]const u8).init(gpa);
716724 defer framework_dirs.deinit();
717725
......@@ -1338,7 +1346,16 @@ fn buildOutputType(
13381346 // -l
13391347 // We don't know whether this library is part of libc or libc++ until
13401348 // 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) {
13421359 try static_libs.append(it.only_arg);
13431360 } else {
13441361 try system_libs.put(it.only_arg, .{ .needed = needed });
......@@ -2137,6 +2154,30 @@ fn buildOutputType(
21372154 }
21382155 }
21392156
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
21402181 const object_format: std.Target.ObjectFormat = blk: {
21412182 const ofmt = target_ofmt orelse break :blk target_info.target.getObjectFormat();
21422183 if (mem.eql(u8, ofmt, "elf")) {