我想在运行Ubuntu 20.04 Focal的AArch64 Raspberry Pi 4上使用clang-11。我查看了https://apt.llvm.org/,但是AArch64预置的二进制文件似乎不可用?
我尝试直接在Raspberry Pi上构建clang,但速度非常慢,最终我用完了SD卡上的空间。
如何在我的x64笔记本电脑上自己交叉编译clang?
构建LLVM可能很棘手,因为它需要大量的计算资源,因此很难使用不同的构建选项进行迭代。我第一次尝试为我的AArch64 Raspberry PI构建clang的主干版本时,最终还是为ARM7构建了一个版本,并且还有30GB的大小,这恰恰不适合存储卡。哎呀。
第一个相关的Clang文档页面是Building LLVM with CMake。它说明了CMake选项CMAKE_BUILD_TYPE
,CMAKE_INSTALL_PREFIX
和LLVM_TARGETS_TO_BUILD
。
设置-DCMAKE_BUILD_TYPE=MinSizeRel
或其他默认值Debug
以外的其他值是一个好主意。 clang的调试版本运行会明显变慢。必须自定义CMAKE_INSTALL_PREFIX
,因为您不想将Clang安装到主机系统上。将其命名为-DCMAKE_INSTALL_PREFIX=$PWD/install
,然后将安装目录复制到您的AArch64计算机上。
如果要使用最先进的功能,则需要保持启用clang代码中的断言,并且要使用调试符号。它减慢了程序的速度并使它变大,但是值得一提的是它提高了安全性和可调试性。
要减小安装尺寸,请设置-DLLVM_TARGETS_TO_BUILD=AArch64
。默认情况下将构建所有目标。
接下来,阅读Building a Distribution of LLVM。相关建议是通过设置-DLLVM_BUILD_LLVM_DYLIB=On -DLLVM_LINK_LLVM_DYLIB=On -DLLVM_INSTALL_TOOLCHAIN_ONLY=On
进一步减小安装尺寸。
最后,阅读How To Cross-Compile Clang/LLVM using 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_TABLEGEN
和CLANG_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
启动docker
建议将具有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
配置
mkdir build-aarch64 cd build-aarch64 CC=aarch64-linux-gnu-gcc-10 CXX=aarch64-linux-gnu-g++-10 cmake \ ../llvm \ -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=/usr/bin/llvm-tblgen-11 \ -DCLANG_TABLEGEN=/mnt/repos/llvm-project/native/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链接时的内存需求较低。