链接失败时须用-v验证lld是否真正调用,因-fuse-ld=lld可能被覆盖或fallback;lld不自动识别--sysroot,必须显式指定-L路径;LTO生成bitcode需匹配lld版本,且--gc-sections需配合-sections参数使用。

链接失败时先确认 lld 是否真正在干活
clang 命令里写了 -fuse-ld=lld 不代表 lld 就真的被调用了——它可能被后续参数覆盖,或 clang 自动 fallback 到系统 ld。最可靠的方式是加 -v 参数重跑链接命令,观察最后一行输出:"/usr/bin/ld" -o ... 说明还是 GNU ld;"lld" -flavor gnu ... 或 "lld-link" ... 才算成功切入。Windows 下尤其要注意:即使写了 -fuse-ld=lld,若目标为 COFF,clang 实际调用的是 lld-link.exe,不是 lld;而 macOS 上该参数目前基本无效。
cannot find -lc 类错误本质是库路径没喂够
lld 不像 GNU ld 那样自动从 --sysroot 推导库搜索路径(比如 /path/usr/lib、/path/lib),它只认显式的 -L。哪怕你传了 --sysroot=/path/to/sysroot,也必须额外补上:-L/path/to/sysroot/usr/lib 和 -L/path/to/sysroot/lib。C++ 项目还要加 -L/path/to/sysroot/usr/lib/gcc/<triplet>/<version></version></triplet>。漏掉任意一个,就会报 lld: error: unable to find library -lc,哪怕 libc.a 就躺在 sysroot/usr/lib 里。
LTO bitcode 文件导致 file not recognized
启用 -flto 后,clang 编译出的 .o 文件实际是 LLVM IR bitcode,不是 ELF 格式。GNU ld 完全无法识别,但 lld 可以——前提是你要用对版本。常见陷阱:ld.lld(Linux)支持 bitcode,lld-link(Windows)默认不支持,需加 /lldltocache 或改用 clang++ -flto=thin。验证方法很简单:file main.o 输出含 LLVM IR bitcode 字样,就说明必须走 lld 且不能用 lld-link 默认行为。
交叉编译时 --gc-sections 报错或静默丢段
lld 的 --gc-sections 行为比 GNU ld 更激进,尤其在未加 -ffunction-sections -fdata-sections 时可能误删全局符号。想确认哪些段被删了,必须组合使用:-Wl,--gc-sections -Wl,--print-gc-sections。注意:如果用了自定义 linker script 并写了 /DISCARD/ { *(.comment) },这些段不会出现在 --print-gc-sections 输出里——那是显式丢弃,不属于 GC 范畴。另外,--trace-symbol 和 --verbose=sections 要配合看,才能区分是前端没生成引用,还是链接器策略太狠。

















