Compile bug: Mac linking bug when compiling with BUILD_SHARED_LIBS=OFF

在 macOS(Apple Silicon)上以 BUILD_SHARED_LIBS=OFF 编译 llama.cpp 时, ggml-rpc 变成静态归档, librdma 的符号不会随静态链接传递,导致链接阶段出现大量 _ibv_* undefined symbols;优先排查 RPC 后端的

快速结论:在 macOS(Apple Silicon)上以 BUILD_SHARED_LIBS=OFF 编译 llama.cpp 时,ggml-rpc 变成静态归档,librdma 的符号不会随静态链接传递,导致链接阶段出现大量 _ibv_* undefined symbols;优先排查 RPC 后端的 RDMA 链接选项是否被正确传递。

适用环境:macOS(arm64 / Apple Silicon),GGML Metal 后端,启用 RPC 后端且 RDMA transport enabled(Apple RDMA-over-Thunderbolt),CMake Release 构建;Issue 中涉及的 commit 为 2bf04151520843e9ea5694e655e7d4a537973b54,llama.cpp 版本显示 0.3.0-dev,ggml 版本 0.22.0。评论中还确认影响官方预编译 macOS arm64 release 包(llama-b10679-bin-macos-arm64.tar.gz,build 10679),环境为 macOS 15.7.9(M1)。

最快修复方案:Issue 正文给出的修复是把 ggml/src/ggml-rpc/CMakeLists.txt 中的 target_link_options(ggml-rpc PRIVATE "LINKER:-weak_library,${RDMA_LIB}") 改为 target_link_options(ggml-rpc PUBLIC "LINKER:-weak_library,${RDMA_LIB}");该问题最终在 PR #28492 完成(另见 #28793)。

注意事项:评论指出 PRIVATEPUBLIC 是必要的,但可能不足以让 release 产物生成 weak import——已发布的 dylib 仍带有对 /usr/lib/librdma.dylib 的硬 LC_LOAD_DYLIB。没有 librdma 的 macOS 15.x 加载该 dylib 会直接 SIGABRT。临时绕过方式是用 install_name_tool -changelibggml-rpc 指向一个导出 17 个 ibv_* 符号的 stub librdma.dylib 并重新签名,但本地推理不会实际走到 RPC 后端,这只适合作为应急手段。

问题场景

用户在 macOS(Apple Silicon)上按常规方式构建 llama.cpp:执行 cmake --build build --config Release,并且在配置阶段启用了 RPC 后端、RDMA transport(Apple RDMA-over-Thunderbolt)以及 Metal 后端。在 BUILD_SHARED_LIBS=OFF 的静态构建下,构建到链接阶段时报错中断,涉及 ggml-rpc-serverggml-metal-tuning 等可执行目标的链接。

评论进一步确认,同样的问题也出现在官方预编译的 macOS arm64 release 二进制中,即使用户没有本地做 BUILD_SHARED_LIBS=OFF 构建,只要下载官方 release 资产并在缺少 librdma 的 macOS 15.x 上启动,就会在加载 libggml-rpc.0.22.0.dylib 时崩溃。

报错原文

Compile bug: Mac linking bug when compiling with BUILD_SHARED_LIBS=OFF

[ 19%] Linking CXX executable ../../bin/ggml-rpc-server
[ 20%] Linking CXX executable ../../bin/ggml-metal-tuning
Undefined symbols for architecture arm64:
  "_ibv_alloc_pd", referenced from:
      apple_rdma::probe(int, unsigned char const*, unsigned char*) in libggml-rpc.a[4](transport-apple.cpp.o)
  "_ibv_close_device", referenced from:
      apple_rdma::probe(int, unsigned char const*, unsigned char*) in libggml-rpc.a[4](transport-apple.cpp.o)
      apple_rdma::impl::~impl() in libggml-rpc.a[4](transport-apple.cpp.o)

ld: symbol(s) not found for architecture arm64
clang++: error: linker command failed with exit code 1 (use -v to see invocation)

make: *** [all] Error 2

评论中给出的运行期报错(官方预编译 macOS arm64 release):

dyld[...]: Library not loaded: /usr/lib/librdma.dylib
  Referenced from: .../libggml-rpc.0.22.0.dylib
  Reason: tried: '/usr/lib/librdma.dylib' (no such file), ... (not in dyld cache)

SIGABRT (rc=-6)

评论中还提到 nm -u libggml-rpc.0.22.0.dylib 显示 17 个 undefined 的 ibv_* 符号,例如 _ibv_alloc_pd_ibv_create_cq_ibv_open_device_ibv_query_device_ibv_create_qp

原因分析

BUILD_SHARED_LIBS=OFF 下,ggml-rpc 被构建为静态归档(libggml-rpc.a),而原 CMake 里针对 RDMA 库使用的是 PRIVATE 链接选项:

target_link_options(ggml-rpc PRIVATE "LINKER:-weak_library,${RDMA_LIB}")

PRIVATE 意味着该链接选项不会被传递给依赖 ggml-rpc 的下游目标。静态归档本身不进行链接,符号解析推迟到最终可执行文件的链接阶段,此时 librdma 的弱链接参数没有跟着传下去,于是 transport-apple.cpp.o 中引用的 ibv_* 符号全部处于 undefined 状态,链接失败。

评论补充的另一层原因:即使改了链接可见性,已发布的 release dylib 里对 /usr/lib/librdma.dylib 仍是硬 LC_LOAD_DYLIB(不是 weak import),说明 -weak_library ${RDMA_LIB} 的意图并没有真正作用到发布产物的 dylib 上。这部分的具体成因 Issue 中没有给出确定结论,属于尚未完全验证的方向。

环境排查

  • 确认操作系统与架构:macOS / arm64(Apple Silicon),Issue 正文为 Mac,评论为 macOS 15.7.9(M1)。
  • 确认 llama.cpp 版本与 commit:Issue 基于 commit 2bf04151520843e9ea5694e655e7d4a537973b54,版本显示 llama.cpp version: 0.3.0-devggml version: 0.22.0;评论中的官方 release 为 build 10679(llama-b10679-bin-macos-arm64.tar.gz)。
  • 确认是否设置 BUILD_SHARED_LIBS=OFF,以及是否启用了 RPC 后端与 RDMA transport(构建日志中的 “Using RPC backend / RDMA transport enabled (Apple RDMA-over-Thunderbolt, UC)”)。
  • 确认 ggml/src/ggml-rpc/CMakeLists.txt 中 RDMA 相关 target_link_options 当前是 PRIVATE 还是 PUBLIC
  • 若是运行官方二进制崩溃,检查目标 macOS 是否存在 /usr/lib/librdma.dylib,并用 nm -u libggml-rpc.0.22.0.dylib 确认是否存在 undefined ibv_* 符号。

解决步骤

  1. 定位到 ggml/src/ggml-rpc/CMakeLists.txt
  2. target_link_options(ggml-rpc PRIVATE "LINKER:-weak_library,${RDMA_LIB}") 改为 target_link_options(ggml-rpc PUBLIC "LINKER:-weak_library,${RDMA_LIB}"),使弱链接选项能传递给依赖 ggml-rpc 的下游目标(此即 Issue 正文给出的修复)。
  3. 重新执行 cmake --build build --config Release,确认链接阶段不再出现 Undefined symbols for architecture arm64: "_ibv_alloc_pd" 等报错。
  4. 如果使用官方预编译 macOS arm64 产物并在 macOS 15.x 上遇到 Library not loaded: /usr/lib/librdma.dylib 崩溃,需要等待包含 PR #28492(后续 #28793)修复的发布版本;应急时可按评论做法,用 install_name_tool -change /usr/lib/librdma.dylib <stub> libggml-rpc.0.22.0.dylib 指向一个导出 17 个 ibv_* 符号的 stub 库并重新签名。
  5. 该 Issue 已关闭,最终完成于 PR #28492,并有 #28793 跟进处理;评论者的原 PR 已让位于 #28492。

验证方法

重新构建后,ggml-rpc-serverggml-metal-tuning 等目标的链接步骤应成功完成,不再出现 ld: symbol(s) not found for architecture arm64make: *** [all] Error 2。对于运行期加载问题,可在缺少 librdma 的 macOS 上启动进程,确认不再出现 Library not loaded: /usr/lib/librdma.dylibSIGABRT (rc=-6),并可用 otool -L / nm -u 检查 libggml-rpc 是否仍带有对 /usr/lib/librdma.dylib 的硬引用。

参考来源

ggml-org/llama.cpp #28491

GamsGo AI

AI 工具推荐

想把多个 AI 模型放在一个入口?

GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。

了解 GamsGo AI

推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。

这个方案解决了吗?

celebrityanime
celebrityanime
文章: 23066

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注