Zig静态库链接Go调用Windows API时出现重复符号错误的求助
Zig静态库链接Go调用Windows API时出现重复符号错误的求助
我最近在尝试把调用Windows API的Zig静态库和Go项目整合,之前简单的Zig库能正常和Go配合,但引入win32相关代码后就碰到了重复符号的编译错误,折腾了好一阵没解决,来求助大家!
我的配置和操作步骤
- Zig的build.zig代码
const std = @import("std"); pub fn build(b: *std.Build) void { const windows = b.option(bool, "windows", "Target Microsoft Windows") orelse false; const arm64 = b.option(bool, "arm64", "Target ARM64 architecture") orelse false; const target = b.resolveTargetQuery(.{ .cpu_arch = if (arm64) .aarch64 else if (windows) .x86_64 else null, .os_tag = if (windows) .windows else null, }); const optimize = b.standardOptimizeOption(.{}); const zigwin32 = b.dependency("zigwin32", .{}); const lib = b.addStaticLibrary(.{ .name = "myziglib", .root_source_file = b.path("src/lib.zig"), .target = target, .optimize = optimize, }); lib.root_module.addImport("zigwin32", zigwin32.module("win32")); b.installArtifact(lib); const exe = b.addExecutable(.{ .name = "myapp", .root_source_file = b.path("src/main.zig"), .target = target, .optimize = optimize, }); exe.root_module.addImport("zigwin32", zigwin32.module("win32")); b.installArtifact(exe); const run_cmd = b.addRunArtifact(exe); run_cmd.step.dependOn(b.getInstallStep()); if (b.args) |args| { run_cmd.addArgs(args); } b.step("run", "Run the app").dependOn(&run_cmd.step); }
- Go项目的CGO配置
// #cgo LDFLAGS: -L./zig1/zig-out/lib -lmyziglib import "C"
- 编译命令
- 编译Zig库:
zig build -Dwindows=true -Darm64=true
- 编译Go项目:
GOOS=windows GOARCH=arm64 CGO_ENABLED=1 \ CC="zig cc -target aarch64-windows-gnu" \ go build -o main.exe .
- 遇到的错误
lld-link: error: duplicate symbol: _tls_end >>> defined at myziglib.lib(myziglib.lib.obj) >>> defined at libmingw32.lib(tlssup.obj) lld-link: error: duplicate symbol: __xl_a >>> defined at myziglib.lib(myziglib.lib.obj) >>> defined at libmingw32.lib(tlssup.obj) lld-link: error: duplicate symbol: __xl_z >>> defined at myziglib.lib(myziglib.lib.obj) >>> defined at libmingw32.lib(tlssup.obj) lld-link: error: duplicate symbol: _tls_used >>> defined at myziglib.lib(myziglib.lib.obj) >>> defined at libmingw32.lib(tlssup.obj)
可能的解决方法
方法1:让Zig静态库不链接libc(最推荐先试)
你碰到的重复符号都是libc的TLS(线程本地存储)相关符号,而zigwin32本身并不依赖libc,所以可以在Zig的build.zig中给静态库添加.link_libc = false,阻止Zig自动链接libc,这样就不会生成这些重复的符号了:
修改build.zig中创建静态库的部分:
const lib = b.addStaticLibrary(.{ .name = "myziglib", .root_source_file = b.path("src/lib.zig"), .target = target, .optimize = optimize, .link_libc = false, // 新增这一行 });
然后重新编译Zig库,再编译Go项目,应该就能解决重复符号的问题了。
方法2:切换到MSVC ABI编译
如果方法1不行,可以试试把编译目标从GNU换成MSVC,这样会使用MSVC的标准库,避免和MinGW的库冲突:
- 修改Zig编译命令:
zig build -Dwindows=true -Darm64=true -target aarch64-windows-msvc
- 修改Go编译命令的CC参数:
GOOS=windows GOARCH=arm64 CGO_ENABLED=1 \ CC="zig cc -target aarch64-windows-msvc" \ go build -o main.exe .
方法3:链接器忽略重复符号(不推荐,仅临时测试)
如果上面的方法都暂时无法生效,可以在Go的CGO LDFLAGS中添加链接器选项强行忽略重复符号,但这可能导致运行时的未知问题,只建议用来验证问题根源:
// #cgo LDFLAGS: -L./zig1/zig-out/lib -lmyziglib -Wl,--allow-multiple-definition import "C"
内容来源于stack exchange
相关产品推荐
相关产品推荐

