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

如何让Zig链接共享(动态)系统库而非静态库?

问题

我希望Zig能够链接共享(动态)系统库(如pthread),但无论尝试何种操作,Zig始终链接静态库。虽然我通常偏好静态链接,但本次场景需要动态链接。

当前构建结果:

$ ldd ./zig-out/bin/zig-perftest
linux-vdso.so.1 (0x00007ffd97d3d000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fdf16a74000)
/lib64/ld-linux-x86-64.so.2 (0x00007f73a65b2000)

期望的动态链接结果(由clang构建的C程序输出):

$ ldd ./raw_ethernet_bw
linux-vdso.so.1 (0x00007ffd139e0000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f73a646f000)
libmlx5.so.1 => /lib/x86_64-linux-gnu/libmlx5.so.1 (0x00007f73a63f1000)
libefa.so.1 => /lib/x86_64-linux-gnu/libefa.so.1 (0x00007f73a63e4000)
librdmacm.so.1 => /lib/x86_64-linux-gnu/librdmacm.so.1 (0x00007f73a63c5000)
libibverbs.so.1 => /lib/x86_64-linux-gnu/libibverbs.so.1 (0x00007f73a63a2000)
libpci.so.3 => /lib/x86_64-linux-gnu/libpci.so.3 (0x00007f73a6390000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f73a6168000)
/lib64/ld-linux-x86-64.so.2 (0x00007f73a65b2000)
libnl-3.so.200 => /lib/x86_64-linux-gnu/libnl-3.so.200 (0x00007f73a6145000)
libnl-route-3.so.200 => /lib/x86_64-linux-gnu/libnl-route-3.so.200
libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f73a60a6000)
libudev.so.1 => /lib/x86_64-linux-gnu/libudev.so.1 (0x00007f73a607c000)

我的build.zig配置如下:

exe.setTarget(target);
exe.setBuildMode(mode);

// C compliation options
const cflags = [_][]const u8{
  "-D_GNU_SOURCE",
  "-g",
  "-O2",
  "-Wall",
  "-march=native",
  "-std=c11",
};

// C source code
const sourceCodeFiles = [_][]const u8{
  "./src/ib/ib_common.c",
  "./src/ib/ib_device.c",
};

// C include paths
exe.addIncludePath("./src/ib");
exe.addIncludePath("/usr/include");
exe.addIncludePath("/usr/include/infiniband");
exe.addIncludePath("/usr/include/x86_64-linux-gnu");

// C linker paths
exe.addLibraryPath("/usr/lib/x86_64-linux-gnu");

// C source code
exe.addCSourceFiles(&sourceCodeFiles, &cflags);

// Link in glibc
exe.linkLibC();

// And link in dependent IB libraries
exe.linkSystemLibrary("mlx5");
exe.linkSystemLibrary("efa");
exe.linkSystemLibrary("rdmacm");
exe.linkSystemLibrary("ibverbs");
exe.linkSystemLibrary("pci");
exe.linkSystemLibrary("pthread");
exe.linkSystemLibrary("nl-route-3");
exe.linkSystemLibrary("nl-3");

// None of these flags help
exe.pie = true;
exe.force_pic = true;
exe.verbose_link = true;
exe.linkage = std.build.LibExeObjStep.Linkage.dynamic;

已尝试设置pie、force_pic、verbose_link及dynamic linkage等选项,但均无效,请问该如何配置才能让Zig实现动态链接?

解决方法
  • 指定系统原生目标
    默认Zig会使用自带的静态libc,构建时需明确指定当前系统的原生目标,比如x86_64-linux-gnu:

    zig build -Dtarget=x86_64-linux-gnu
    

    也可以直接在build.zig中硬编码目标:

    const target = std.zig.CrossTarget{ .os_tag = .linux, .cpu_arch = .x86_64, .abi = .gnu };
    
  • 强制使用系统动态libc
    在exe.linkLibC()之后添加以下配置,让Zig放弃自带的静态libc,改用系统提供的动态版本:

    exe.libc_implementation = .system;
    
  • 替换链接库的方法
    将linkSystemLibrary替换为linkSystemLibraryNeeded,这个方法会优先选择动态库而非静态库:

    exe.linkSystemLibraryNeeded("mlx5");
    exe.linkSystemLibraryNeeded("efa");
    exe.linkSystemLibraryNeeded("rdmacm");
    exe.linkSystemLibraryNeeded("ibverbs");
    exe.linkSystemLibraryNeeded("pci");
    exe.linkSystemLibraryNeeded("pthread");
    exe.linkSystemLibraryNeeded("nl-route-3");
    exe.linkSystemLibraryNeeded("nl-3");
    
  • 检查动态库是否存在
    确认系统中已安装所需库的动态版本(即.so后缀的文件),如果只有静态库(.a),Zig只能静态链接。可以通过find /usr/lib/x86_64-linux-gnu -name "libmlx5.so*"这类命令验证。

  • 验证链接命令
    开启exe.verbose_link = true后,查看构建输出中的链接命令,确认参数是-lmlx5而非-l:libmlx5.a,后者代表强制链接静态库。如果出现静态库参数,说明Zig没找到动态库,需检查库路径是否正确。


内容的提问来源于stack exchange,提问作者ecwdw 23e3e23e

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 11:55:00