| author | |
| committer | |
| log | 36a33c99e3bc0825ada2ce1b374c32b4d6dee6b0 |
| tree | d94b91c8915261eb8bb239a9b7d2b846fc1bcd27 |
| parent | a5bbc66f10339cb2e17ef996ef097b696980595a |
| parent | 461543a5fd27415710f027d034b83ef196bc8a44 |
| signature |
zld: fix symbol resolution from interdependent static archives8 files changed, 56 insertions(+), 21 deletions(-)
src/link/MachO/Zld.zig+9-21| ... | ... | @@ -1284,17 +1284,14 @@ fn resolveSymbols(self: *Zld) !void { |
| 1284 | 1284 | } |
| 1285 | 1285 | |
| 1286 | 1286 | // Second pass, resolve symbols in static libraries. |
| 1287 | var next: usize = 0; | |
| 1288 | var hit: bool = undefined; | |
| 1289 | while (true) { | |
| 1290 | var archive = &self.archives.items[next]; | |
| 1291 | hit = false; | |
| 1292 | ||
| 1293 | for (self.symtab.items()) |entry| { | |
| 1294 | if (entry.value.tag != .undef) continue; | |
| 1295 | ||
| 1296 | const sym_name = entry.value.name; | |
| 1297 | ||
| 1287 | var next_sym: usize = 0; | |
| 1288 | var nsyms: usize = self.symtab.items().len; | |
| 1289 | while (next_sym < nsyms) : (next_sym += 1) { | |
| 1290 | const sym = self.symtab.items()[next_sym]; | |
| 1291 | if (sym.value.tag != .undef) continue; | |
| 1292 | ||
| 1293 | const sym_name = sym.value.name; | |
| 1294 | for (self.archives.items) |archive| { | |
| 1298 | 1295 | // Check if the entry exists in a static archive. |
| 1299 | 1296 | const offsets = archive.toc.get(sym_name) orelse { |
| 1300 | 1297 | // No hit. |
| ... | ... | @@ -1307,18 +1304,9 @@ fn resolveSymbols(self: *Zld) !void { |
| 1307 | 1304 | try self.objects.append(self.allocator, object); |
| 1308 | 1305 | try self.resolveSymbolsInObject(object_id); |
| 1309 | 1306 | |
| 1310 | hit = true; | |
| 1307 | nsyms = self.symtab.items().len; | |
| 1311 | 1308 | break; |
| 1312 | 1309 | } |
| 1313 | ||
| 1314 | if (!hit) { | |
| 1315 | // Next archive. | |
| 1316 | next += 1; | |
| 1317 | if (next == self.archives.items.len) { | |
| 1318 | break; | |
| 1319 | } | |
| 1320 | archive = &self.archives.items[next]; | |
| 1321 | } | |
| 1322 | 1310 | } |
| 1323 | 1311 | |
| 1324 | 1312 | // Third pass, resolve symbols in dynamic libraries. |
test/standalone.zig+1| ... | ... | @@ -16,6 +16,7 @@ pub fn addCases(cases: *tests.StandaloneContext) void { |
| 16 | 16 | cases.addBuildFile("test/standalone/mix_o_files/build.zig"); |
| 17 | 17 | cases.addBuildFile("test/standalone/global_linkage/build.zig"); |
| 18 | 18 | cases.addBuildFile("test/standalone/static_c_lib/build.zig"); |
| 19 | cases.addBuildFile("test/standalone/link_interdependent_static_c_libs/build.zig"); | |
| 19 | 20 | cases.addBuildFile("test/standalone/issue_339/build.zig"); |
| 20 | 21 | cases.addBuildFile("test/standalone/issue_794/build.zig"); |
| 21 | 22 | cases.addBuildFile("test/standalone/issue_5825/build.zig"); |
test/standalone/link_interdependent_static_c_libs/a.c created+4| ... | ... | @@ -0,0 +1,4 @@ |
| 1 | #include "a.h" | |
| 2 | int32_t add(int32_t a, int32_t b) { | |
| 3 | return a + b; | |
| 4 | } |
test/standalone/link_interdependent_static_c_libs/a.h created+2| ... | ... | @@ -0,0 +1,2 @@ |
| 1 | #include <stdint.h> | |
| 2 | int32_t add(int32_t a, int32_t b); |
test/standalone/link_interdependent_static_c_libs/b.c created+6| ... | ... | @@ -0,0 +1,6 @@ |
| 1 | #include "a.h" | |
| 2 | #include "b.h" | |
| 3 | ||
| 4 | int32_t sub(int32_t a, int32_t b) { | |
| 5 | return add(a, -1 * b); | |
| 6 | } |
test/standalone/link_interdependent_static_c_libs/b.h created+2| ... | ... | @@ -0,0 +1,2 @@ |
| 1 | #include <stdint.h> | |
| 2 | int32_t sub(int32_t a, int32_t b); |
test/standalone/link_interdependent_static_c_libs/build.zig created+24| ... | ... | @@ -0,0 +1,24 @@ |
| 1 | const Builder = @import("std").build.Builder; | |
| 2 | ||
| 3 | pub fn build(b: *Builder) void { | |
| 4 | const mode = b.standardReleaseOptions(); | |
| 5 | ||
| 6 | const lib_a = b.addStaticLibrary("a", null); | |
| 7 | lib_a.addCSourceFile("a.c", &[_][]const u8{}); | |
| 8 | lib_a.setBuildMode(mode); | |
| 9 | lib_a.addIncludeDir("."); | |
| 10 | ||
| 11 | const lib_b = b.addStaticLibrary("b", null); | |
| 12 | lib_b.addCSourceFile("b.c", &[_][]const u8{}); | |
| 13 | lib_b.setBuildMode(mode); | |
| 14 | lib_b.addIncludeDir("."); | |
| 15 | ||
| 16 | const test_exe = b.addTest("main.zig"); | |
| 17 | test_exe.setBuildMode(mode); | |
| 18 | test_exe.linkLibrary(lib_a); | |
| 19 | test_exe.linkLibrary(lib_b); | |
| 20 | test_exe.addIncludeDir("."); | |
| 21 | ||
| 22 | const test_step = b.step("test", "Test it"); | |
| 23 | test_step.dependOn(&test_exe.step); | |
| 24 | } |
test/standalone/link_interdependent_static_c_libs/main.zig created+8| ... | ... | @@ -0,0 +1,8 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | const c = @cImport(@cInclude("b.h")); | |
| 4 | ||
| 5 | test "import C sub" { | |
| 6 | const result = c.sub(2, 1); | |
| 7 | expect(result == 1); | |
| 8 | } |