You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Zig静态库链接Go调用Windows API时出现重复符号错误的求助

Zig静态库链接Go调用Windows API时出现重复符号错误的求助

我最近在尝试把调用Windows API的Zig静态库和Go项目整合,之前简单的Zig库能正常和Go配合,但引入win32相关代码后就碰到了重复符号的编译错误,折腾了好一阵没解决,来求助大家!

我的配置和操作步骤

  1. 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);
}
  1. Go项目的CGO配置
// #cgo LDFLAGS: -L./zig1/zig-out/lib -lmyziglib
import "C"
  1. 编译命令
  • 编译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 .
  1. 遇到的错误
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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.07 07:23:07