mold 可显著加速大型 C++ 项目链接,但需确认构建系统兼容性、避开其不支持的特性(如 COFF、部分 ld flag、ICF、symbol interposition),并在 CMake 或环境变量中正确配置,同时注意默认行为差异(如 --gc-sections)及调试局限。

用 mold 替代 ld 或 lld 能显著加速大型 C++ 项目的链接,尤其在增量构建和 CI 场景下效果明显——但前提是正确集成且避开其当前限制。
确认 mold 是否适合你的构建系统
mold 是一个从零编写的、支持 ELF 和 Mach-O 的现代链接器,主打速度与内存效率。它不兼容 Windows(无 COFF 支持),也不支持所有 ld 的 obscure flag(比如部分 --wrap 行为、某些插件机制)。如果你的项目依赖:
-
-Wl,--undefined-version或自定义 version script 的精细符号版本控制 -
ld.gold特有的--icf=all(mold 不做 ICF) - 运行时加载
.so时依赖ld的 symbol interposition 行为(mold 默认禁用)
那直接替换可能引发链接失败或运行时符号解析异常。建议先用 mold --help 检查关键 flag 是否被支持,再在非关键分支试跑完整构建 + 测试。
在 CMake 中启用 mold(最常见场景)
CMake 3.18+ 原生支持 CMAKE_LINKER,但要注意:必须同时指定 CMAKE_CXX_LINK_EXECUTABLE 才能覆盖链接命令模板,否则只换 linker 二进制,仍走旧逻辑。
立即学习“C++免费学习笔记(深入)”;
set(CMAKE_LINKER "/usr/local/bin/mold")
set(CMAKE_CXX_LINK_EXECUTABLE
"${CMAKE_LINKER} -o "
)
更稳妥的做法是通过环境变量注入(避免修改 CMakeLists.txt):
- Linux:运行
CC=clang CXX=clang++ LD=mold cmake -G Ninja -DCMAKE_BUILD_TYPE=RelWithDebInfo .. - Ninja 会自动识别
LD并用于所有链接步骤(包括可执行文件和 shared library) - 若用 GCC,需额外加
-fuse-ld=mold(GCC 12+ 支持;低于此版本会报错 unrecognized option)
处理 mold 的默认行为差异
mold 默认开启 --no-as-needed 和 --gc-sections,这和 ld 不同,可能导致:
- 未使用的库被静默丢弃(
--no-as-needed让-lfoo总是生效,但--gc-sections可能删掉你认为“有用”的弱符号) - 某些依赖循环或间接符号引用失败(尤其是用
dlsym动态获取符号时)
遇到链接错误如 undefined reference to `xxx',优先尝试:
- 加
-Wl,--no-gc-sections关闭段裁剪 - 加
-Wl,--as-needed恢复传统依赖判断逻辑 - 检查是否漏传了
-rdynamic(mold 不自动导出符号给 dlopen,需显式加)
验证加速效果与排查卡点
别只看 time make —— mold 的优势集中在链接阶段本身。用 ninja -t trace 或 cmake --build . --verbose 提取实际链接命令,再单独计时:
time /usr/local/bin/mold -o myapp main.o util.o -Llib -lcore time ld.lld -o myapp main.o util.o -Llib -lcore
典型提速范围是 2–5×(取决于目标文件数、符号数量、SSD 速度),但注意:
- 首次链接可能略慢(mold 构建内部哈希表开销)
- 若项目大量使用
thin LTO(-flto=thin),mold 尚不支持 thin archive 合并,此时必须回退到lld - mold 的 debug info 处理不如 lld 成熟,
gdb加载极大型.dwo文件时偶发卡顿
真正卡住的地方往往不是 mold 本身,而是构建系统没把所有链接动作都导向它——比如第三方子项目硬编码了 ld,或 pkg-config 返回的 -Wl,--dynamic-list mold 不识别,得手动 patch。











