我试图理解如何使用LLVM/clang作为交叉编译器。这个过程的一些方面还不是很清楚。
LLVM文档经常提到clang是"原生的交叉编译器"。然而,如果它首先被构建为交叉编译器,这是唯一正确的吗?
如果我想为目标armv7a-linux-eabihf
构建,例如,我是否必须在构建LLVM/clang时使用一些选项,将该目标包含在可能的目标列表中?
这是否也会构建所需的运行时库?
我没有尝试交叉编译到ARM,下面的答案是基于我的经验,交叉编译到Windows (x86)与各种MinGW风格。
LLVM文档经常提到clang是"原生的交叉编译器"。然而,如果它首先被构建为交叉编译器,这是唯一正确的吗?
据我所知,任何(?)Clang二进制文件可以在任何支持的平台上编译;您不需要针对不同的平台使用不同的二进制文件。(例如,与GCC不同。)
你需要的是目标平台的各种库。
最小必要标志是--target=?? --sysroot=??
,其中"target"可能是armv7a-linux-eabihf
(通过在目标平台上运行clang --version
来确认这一点),以及"sysroot"是从目标操作系统复制的根目录(/
)。理论上,只有库和头文件是必需的,但复制所有内容更容易。
下面列出了其他有用的标志。其中一些可能具有Clang二进制文件提供的默认值。
-fuse-ld=lld
(或-fuse-ld=lld-$VERSION
)使用Clang自己的链接器-stdlib=libstdc++
或-stdlib=libc++
选择c++标准库。- 我也相信在libstdc++上使用原子需要
-femulated-tls
,在libc++上需要-fno-emulated-tls
。这是Windows x86的情况,不确定ARM。 - 如果目标操作系统没有libgcc,我相信你还需要
-rtlib=compiler-rt -unwindlib=libunwind -resource-dir=$YOUR_SYSROOT/lib/clang/$CLANG_VERSION
,否则你需要-rtlib=libgcc
。
如果有些不工作,添加-v
标志,并比较交叉编译器和直接在目标平台上运行的Clang之间的输出。您可能需要添加一些额外的标志。
Clang本质上是一个交叉编译器,因为它的设计:当您编译Clang时,您必须决定支持哪个目标,并且对于Clang运行的平台来说,目标没有什么特别之处。没有什么特别的,这就是为什么clang是一个交叉编译器。
不,它不会构建库。它是一个编译器,而不是你需要的其他东西。