如何用CMake交叉编译适配musl的Clang/LLVM?
为musl构建Clang/LLVM的问题
我一直在尝试为musl这个C标准库构建Clang/LLVM。目前在x86_64 Linux(glibc)主机上构建的Clang,通过传递--target=x86_64-unknown-linux-musl参数,能编译出可在安装musl库的虚拟机中正常运行的C程序,但用类似方法构建Clang本身以实现自举时失败了。
参考相关文档后,我使用了以下CMake命令(执行前已通过export将CC和CXX指向本机的clang和clang++二进制文件):
cmake -DCMAKE_CROSSCOMPILING=True -DLLVM_DEFAULT_TARGET_TRIPLE=x86_64-unknown-linux-musl -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_PROJECTS="clang" -DCMAKE_SYSTEM_NAME=Linux -DLLVM_HOST_TRIPLE=x86_64-unknown-linux-musl -G Ninja -DCMAKE_CXX_FLAGS='--target=x86_64-unknown-linux-musl' -DCMAKE_C_FLAGS='--target=x86_64-unknown-linux-musl' ../llvm
用file工具检查生成的clang-19二进制文件,输出如下:
$ file bin/clang-19 bin/clang-19: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-musl-x86_64.so.1, for GNU/Linux 3.2.0, not stripped
看起来结果符合预期,但运行ldd后得到的结果却显示依赖glibc库:
$ ldd bin/clang-19 linux-vdso.so.1 (0x00007ffe651a4000) libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f0b34da8000) libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f0b34d89000) libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f0b2ac00000) libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f0b34d69000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f0b2ae1f000) /lib/ld-musl-x86_64.so.1 => /lib64/ld-linux-x86-64.so.2 (0x00007f0b34e9b000)
对比之前在musl虚拟机上能正常运行的“hello world”动态链接二进制文件,用file检查的结果是:
$ file ../../musl-test/hello_dynamic ../../musl-test/hello_dynamic: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-musl-x86_64.so.1, not stripped
但在本机用ldd检查该文件时会报错:
$ ldd ../../musl-test/hello_dynamic ../../musl-test/hello_dynamic: error while loading shared libraries: /lib/x86_64-linux-gnu/libc.so: invalid ELF header
推测这是因为本机未安装musl导致的,但该二进制文件确实能在musl虚拟机中正常运行。
我的目标是“交叉编译”(因架构相同但C库不同,不确定是否完全属于交叉编译范畴)出可在musl虚拟机中运行的Clang版本。
内容的提问来源于stack exchange,提问作者popovicu
相关产品推荐
相关产品推荐

