使用LLVM/Clang作为交叉编译器



我试图理解如何使用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是一个交叉编译器。

不,它不会构建库。它是一个编译器,而不是你需要的其他东西。

最新更新