在Clang命令中指定--target=aarch64时为何调用GCC而非ld.lld?
解决clang指定
--target=aarch64时调用gcc而非指定ld.lld的问题 这个问题我之前交叉编译时也碰到过,核心原因是clang处理交叉编译目标的工具链查找逻辑在搞鬼:当你只给clang传--target=aarch64这个不完整的目标标识时,clang会将其判定为裸机目标,此时它会自动 fallback 调用系统的gcc来负责链接环节。但gcc对-fuse-ld参数的语法要求和clang不一样——gcc不允许直接指定链接器的绝对路径(只能写链接器的名称,比如-fuse-ld=lld),这就直接触发了报错。
下面给你几个可行的解决方案,按推荐程度排序:
方案1:使用完整的musl目标三元组(最推荐)
既然你正在编译musl库,直接用完整的目标三元组aarch64-linux-musl告诉clang你要编译的目标平台,这样clang会正确识别目标并直接使用你指定的ld.lld,不会再调用gcc:
clang -fuse-ld=/usr/local/bin/ld.lld --target=aarch64-linux-musl -v obj/src/unistd/writev.lo
方案2:强制clang跳过gcc中转,直接调用lld
如果你确实需要针对裸机aarch64编译,可以添加-nostdlib选项(告诉clang不要自动链接标准库),同时保持指定的链接器参数:
clang -fuse-ld=/usr/local/bin/ld.lld --target=aarch64 -nostdlib -v obj/src/unistd/writev.lo
另外,你也可以用-B选项指定链接器所在的目录,让clang优先从这个目录查找工具链组件(结合你已经把/usr/bin/ld软链到ld.lld的操作,这个方法也能生效):
clang -B/usr/local/bin/ --target=aarch64 -v obj/src/unistd/writev.lo
方案3:适配gcc的-fuse-ld写法(不推荐)
如果一定要让gcc来处理链接,你可以调整-fuse-ld的写法为gcc支持的格式,同时确保/usr/local/bin在PATH的最前面,让gcc能找到你的ld.lld:
export PATH=/usr/local/bin:$PATH clang -fuse-ld=lld --target=aarch64 -v obj/src/unistd/writev.lo
不过这种方案依赖gcc的行为,不如直接让clang处理链接来得可靠,除非你有特殊需求,否则不建议用。
内容的提问来源于stack exchange,提问作者simon




