Как выполнить кросс-компиляцию LLVM/Clang для AArch64 на хосте x64?

Я хочу использовать clang-11 на своем AArch64 Raspberry Pi 4 под управлением Ubuntu 20.04 Focal. Я просмотрел https://apt.llvm.org/, но готовые двоичные файлы AArch64 не доступны?

Я пытался создать clang напрямую на Raspberry Pi, но это было очень медленно, и в конце концов у меня закончилось место на SD-карте.

Как мне самостоятельно выполнить кросс-компиляцию clang на моем ноутбуке с архитектурой x64?


person user7610    schedule 13.05.2020    source источник


Ответы (1)


Сборка LLVM может быть сложной, поскольку требует много вычислительных ресурсов, что затрудняет итерацию с различными вариантами сборки. Моя первая попытка собрать транковую версию clang для моего AArch64 Raspberry PI закончилась сборкой для ARM7, да еще и размером 30GB, который просто не помещался на карту памяти. Упс.

Изучите документацию на вики проекта

Первая соответствующая страница документации Clang — это Сборка LLVM с помощью 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

Опции там должны быть простыми, за исключением, может быть, 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

Запустить докер

Директорию с исходниками llvm желательно смонтировать в контейнер из вашей файловой системы. Это облегчит отправку результатов компиляции, а также собственная файловая система будет работать быстрее, чем оверлеи в докере.

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

Компиляция

Получите мощную сборочную машину, если сможете. Связывание некоторых двоичных файлов требует много оперативной памяти. У вас должно быть ~ 20 ГБ памяти, чтобы иметь возможность добраться куда угодно за разумное время, 64 ГБ было бы еще лучше. Если случается так, что несколько параллельных задач связывания исчерпывают память вашего компьютера, попробуйте скомпилировать с ninja -j3 или около того, чтобы ограничить количество параллельных задач, например, 3.

ninja install -j3

Предполагается, что использование другого компоновщика уменьшит требования к памяти. Предположительно, ld.gold имеет меньшие требования к памяти при линковке.

person user7610    schedule 13.05.2020