如何在 x64 主机上交叉编译 AArch64 的 LLVM/Clang?



我想在我的AArch64 Raspberry Pi 4上使用clang-11,运行Ubuntu 20.04 Focal。我看了 https://apt.llvm.org/,但 AArch64 预构建的二进制文件似乎不可用?

我尝试直接在Raspberry Pi上构建crong,但它非常慢,最终我用完了SD卡上的空间。

如何在 x64 笔记本电脑上交叉编译 clang 自己?

Clang 现在有 arm64 (AArch64( 预构建的二进制文件,用于 https://apt.llvm.org/的开发中版本,因此请尽可能使用这些二进制文件。否则,请继续阅读!

构建LLVM 可能很棘手,因为它需要大量的计算资源,这使得使用不同的构建选项进行迭代变得困难。我第一次尝试为我的AArch64 Raspberry PI构建clang的中继版本,最终为ARM7构建了30GB,这不适合存储卡。哎 呦。

项目维基上的学习文档

第一个相关的Clang文档页面是使用CMake构建LLVM。它解释了 CMake 选项CMAKE_BUILD_TYPECMAKE_INSTALL_PREFIXLLVM_TARGETS_TO_BUILD

最好设置-DCMAKE_BUILD_TYPE=MinSizeRel或默认Debug以外的其他值。clang的调试版本将运行得更慢。自定义CMAKE_INSTALL_PREFIX是必要的,因为您不想将 Clang 安装到主机系统上。给它-DCMAKE_INSTALL_PREFIX=$PWD/install,然后将安装目录复制到您的 AArch64 机器。

要减小安装的大小,请设置-DLLVM_TARGETS_TO_BUILD=AArch64。默认设置是构建所有目标。

启用断言(但可能禁用调试信息(

如果你想使用尖端的功能,这很可能,否则,为什么要编译 clang,你会希望保持 clang 代码中的断言启用,并且你会想要调试符号。断言几乎不会花费我们任何东西。调试信息是不同的:它减慢了 clang 二进制文件本身的编译(链接(,使其运行速度稍慢,并使其明显更大,但由于提高了可调试性,这可能是值得的,允许提交带有符号化回溯的错误报告如果出现任何问题。查看获取源代码和构建 LLVM 并在这种情况下设置-DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_ASSERTIONS=On。还要考虑-DCMAKE_BUILD_TYPE=MinSizeRel。(如果您决定使用调试信息,请使用-DCMAKE_BUILD_TYPE=RelWithDebInfo

接下来,阅读构建 LLVM 发行版。相关建议是通过设置-DLLVM_BUILD_LLVM_DYLIB=On -DLLVM_LINK_LLVM_DYLIB=On -DLLVM_INSTALL_TOOLCHAIN_ONLY=On来进一步最小化安装尺寸。

最后,阅读如何使用 Clang/LLVM 交叉编译 Clang/LLVM。即使您计划使用 GCC 进行交叉编译,此页面也很有帮助。如果你使用的是 Ubuntu Focal,无论是直接使用还是在 Docker 容器中构建,你最终可能会得到你的 CMake 命令的这个框架,比如

CC=aarch64-linux-gnu-gcc-10 CXX=aarch64-linux-gnu-g++-10 cmake ../llvm 
-DCMAKE_CROSSCOMPILING=True 
-DLLVM_TARGET_ARCH=AArch64 
-DLLVM_DEFAULT_TARGET_TRIPLE=aarch64-linux-gnueabihf 
-DCMAKE_CXX_FLAGS='-march=armv8-a -mtune=cortex-a72' 
-GNinja

那里的选项应该很简单,除了LLVM_TABLEGENCLANG_TABLEGEN.必须指定它们,因为这些二进制文件需要在主机上运行,但构建会为目标编译它们,因此它不能使用它刚刚构建的内容。现有二进制文件必须由您提供。虽然 llvm-tblgen 可以与 llvm 软件包一起安装,但 clang-tblgen 不是发行版的一部分。这意味着,您需要执行两个构建。首先,为主机构建这两个二进制文件(您不必构建完整的 LLVM,这两个二进制文件就足够了(,然后将交叉编译指向它们。

mkdir build-host
cd build-host
CC=gcc-10 CXX=g++-10 cmake ../llvm -DLLVM_ENABLE_PROJECTS='clang;compiler-rt;lld;clang-tools-extra' -GNinja
ninja llvm-tblgen clang-tblgen

现在,在交叉生成中使用这些二进制文件,因此请添加到 CMake 命令中

-DLLVM_TABLEGEN=/usr/bin/llvm-tblgen-11 -DCLANG_TABLEGEN=/mnt/repos/llvm-project/build-host/bin/clang-tblgen

启动码头工人

建议将包含 llvm 源的目录从文件系统挂载到容器中。这将使编译结果更容易发布,并且本机文件系统比 docker 中的覆盖更快。

docker run -v `pwd`:/mnt --rm -it ubuntu:focal bash

安装依赖项

在 Ubuntu 20.04 Focal 上

apt install g++-10-aarch64-linux-gnu libstdc++-10-dev-arm64-cross gcc-10 g++-10
apt install cmake ninja-build python3

配置

mkdir build-aarch64
cd build-aarch64
CC=aarch64-linux-gnu-gcc-10 CXX=aarch64-linux-gnu-g++-10 cmake ../llvm 
-DCMAKE_BUILD_TYPE=RelWithDebInfo 
-DLLVM_ENABLE_ASSERTIONS=On 
-DCMAKE_CROSSCOMPILING=True 
-DCMAKE_INSTALL_PREFIX=install 
-DLLVM_DEFAULT_TARGET_TRIPLE=aarch64-linux-gnueabihf 
-DLLVM_TARGET_ARCH=AArch64 
-DLLVM_TARGETS_TO_BUILD=AArch64 
-DCMAKE_CXX_FLAGS='-march=armv8-a -mtune=cortex-a72' 
-GNinja 
-DLLVM_ENABLE_PROJECTS='clang;compiler-rt;lld;clang-tools-extra' 
-DLLVM_TABLEGEN=/mnt/repos/llvm-project/build-host/bin/llvm-tblgen 
-DCLANG_TABLEGEN=/mnt/repos/llvm-project/build-host/bin/clang-tblgen 
-DLLVM_BUILD_LLVM_DYLIB=On 
-DLLVM_LINK_LLVM_DYLIB=On 
-DLLVM_INSTALL_TOOLCHAIN_ONLY=On

编译

如果可以的话,请购买功能强大的构建计算机。链接某些二进制文件需要大量 RAM。您应该有 ~20 GB 的可用内存才能在合理的时间内到达任何地方,64 GB 会更好。如果并行运行的多个链接任务会耗尽计算机内存,请尝试使用ninja -j3左右进行编译,以将并行任务的数量限制为 3 个。

ninja install -j3

使用不同的链接器应该可以减少内存需求。据说,ld.gold在链接时具有较低的内存要求。

我的环境是Mac,而不是你的Raspberry Pi,所以仅供参考:

  • 现在是20230429,似乎clang已经支持arm64~=AArch64
    • 我的叮当版
       clang --version         
      Apple clang version 13.0.0 (clang-1300.0.29.30)
      Target: x86_64-apple-darwin20.6.0
      Thread model: posix
      
    • 在 Mac 上使用clang构建arm64
      • clang -arch arm64 main.c -o main_arm64
    • 编译的文件arm64架构
       file main_arm64 
      main_arm64: Mach-O 64-bit executable arm64
      

最新更新