Merge pull request #8517 from ziglang/zld-archive-fix

zld: fix symbol resolution from interdependent static archives
This commit is contained in:
Jakub Konka 2021-04-13 17:12:26 +02:00 committed by GitHub
commit 36a33c99e3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 55 additions and 20 deletions

View File

@ -1284,17 +1284,14 @@ fn resolveSymbols(self: *Zld) !void {
}
// Second pass, resolve symbols in static libraries.
var next: usize = 0;
var hit: bool = undefined;
while (true) {
var archive = &self.archives.items[next];
hit = false;
for (self.symtab.items()) |entry| {
if (entry.value.tag != .undef) continue;
const sym_name = entry.value.name;
var next_sym: usize = 0;
var nsyms: usize = self.symtab.items().len;
while (next_sym < nsyms) : (next_sym += 1) {
const sym = self.symtab.items()[next_sym];
if (sym.value.tag != .undef) continue;
const sym_name = sym.value.name;
for (self.archives.items) |archive| {
// Check if the entry exists in a static archive.
const offsets = archive.toc.get(sym_name) orelse {
// No hit.
@ -1307,18 +1304,9 @@ fn resolveSymbols(self: *Zld) !void {
try self.objects.append(self.allocator, object);
try self.resolveSymbolsInObject(object_id);
hit = true;
nsyms = self.symtab.items().len;
break;
}
if (!hit) {
// Next archive.
next += 1;
if (next == self.archives.items.len) {
break;
}
archive = &self.archives.items[next];
}
}
// Third pass, resolve symbols in dynamic libraries.

View File

@ -16,6 +16,7 @@ pub fn addCases(cases: *tests.StandaloneContext) void {
cases.addBuildFile("test/standalone/mix_o_files/build.zig");
cases.addBuildFile("test/standalone/global_linkage/build.zig");
cases.addBuildFile("test/standalone/static_c_lib/build.zig");
cases.addBuildFile("test/standalone/link_interdependent_static_c_libs/build.zig");
cases.addBuildFile("test/standalone/issue_339/build.zig");
cases.addBuildFile("test/standalone/issue_794/build.zig");
cases.addBuildFile("test/standalone/issue_5825/build.zig");

View File

@ -0,0 +1,4 @@
#include "a.h"
int32_t add(int32_t a, int32_t b) {
return a + b;
}

View File

@ -0,0 +1,2 @@
#include <stdint.h>
int32_t add(int32_t a, int32_t b);

View File

@ -0,0 +1,6 @@
#include "a.h"
#include "b.h"
int32_t sub(int32_t a, int32_t b) {
return add(a, -1 * b);
}

View File

@ -0,0 +1,2 @@
#include <stdint.h>
int32_t sub(int32_t a, int32_t b);

View File

@ -0,0 +1,24 @@
const Builder = @import("std").build.Builder;
pub fn build(b: *Builder) void {
const mode = b.standardReleaseOptions();
const lib_a = b.addStaticLibrary("a", null);
lib_a.addCSourceFile("a.c", &[_][]const u8{});
lib_a.setBuildMode(mode);
lib_a.addIncludeDir(".");
const lib_b = b.addStaticLibrary("b", null);
lib_b.addCSourceFile("b.c", &[_][]const u8{});
lib_b.setBuildMode(mode);
lib_b.addIncludeDir(".");
const test_exe = b.addTest("main.zig");
test_exe.setBuildMode(mode);
test_exe.linkLibrary(lib_a);
test_exe.linkLibrary(lib_b);
test_exe.addIncludeDir(".");
const test_step = b.step("test", "Test it");
test_step.dependOn(&test_exe.step);
}

View File

@ -0,0 +1,8 @@
const std = @import("std");
const expect = std.testing.expect;
const c = @cImport(@cInclude("b.h"));
test "import C sub" {
const result = c.sub(2, 1);
expect(result == 1);
}