如何让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

