cross-compiling - 如何在 x64 主机上为 AArch64 交叉编译 LLVM/Clang?
问题描述
我想在我的 AArch64 Raspberry Pi 4 上使用 clang-11,运行 Ubuntu 20.04 Focal。我查看了https://apt.llvm.org/,但 AArch64 预构建的二进制文件似乎不可用?
我尝试直接在 Raspberry Pi 上构建 clang,但速度非常慢,最终我的 SD 卡空间不足。
如何在我的 x64 笔记本电脑上交叉编译 clang?
解决方案
构建 LLVM 可能会很棘手,因为它需要大量的计算资源,这使得使用不同的构建选项进行迭代变得困难。我第一次尝试为我的 AArch64 Raspberry PI 构建主干版本的 clang 最终是为 ARM7 构建的,而且大小也为 30GB,这不适合存储卡。哎呀。
项目 wiki 上的研究文档
第一个相关的 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 机器上。
要减小安装大小,请设置-DLLVM_TARGETS_TO_BUILD=AArch64
. 默认是构建所有目标。
启用断言
如果您想使用最先进的功能,这很可能,否则为什么要编译 clang,您需要启用 clang 代码中的断言,并且您需要调试符号。它会减慢程序速度并使其变得更大,但由于提高了安全性和可调试性,这绝对值得。查看获取源代码和构建 LLVM并-DCMAKE_BUILD_TYPE=RelWithDebInfo -DLLVM_ENABLE_ASSERTIONS=On
在这种情况下进行设置。
接下来,阅读构建 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
那里的选项应该是直截了当的,除了 forLLVM_TABLEGEN
和CLANG_TABLEGEN
。必须指定它们,因为这些二进制文件需要在主机上运行,但是构建会为目标编译它们,因此它不能使用它刚刚构建的内容。现有的二进制文件必须由您提供。虽然 llvm-tblgen 可以与 llvm 软件包一起安装,但 clang-tblgen 不是发行版的一部分。这意味着,您需要进行两次构建。首先,为host构建这两个二进制文件(你不必构建完整的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 焦点上
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 会更好。如果发生多个并行运行的链接任务耗尽您的机器内存,请尝试使用 orso 进行编译ninja -j3
,以将并行任务的数量限制为例如 3。
ninja install -j3
使用不同的链接器应该可以减少内存需求。据说,ld.gold 在链接时对内存的要求较低。
推荐阅读
- r - 映射越过反子午线...(在 ggmap/ggplot2 中)
- python - swig,传递没有指定尺寸的carrays
- python - 如何添加以元组列表形式给出的数字:('name',number)
- angular - 从 Web 应用程序的 Firestore 中删除字段时出错。“不支持的字段值:自定义 DeleteFieldValueImpl 对象”
- algorithm - 如何区分两个 BST
- groovy - 如何在读取 Excel 文件时解决 SoapUI 中的错误
- reactjs - 未捕获的 ReferenceError:在部署 reactjs 应用程序时未定义 ReactDOM
- android - ClosedReceiveChannelException 和数据绑定问题
- java - 从 Android 应用程序使用 Android Google Play Dev API
- r - 如何将我在 R 中的逐步回归转换为许多因变量的 FOR 循环