← На главную

Сборка LLVM-стека из исходников и чем она так интересна

Не так давно я заинтересовался вопросом сборки последней версии CLang и сопутствующих проектов LLVM-стека из исходных кодов. Не то, чтобы это было неописуемо захватывающим занятием. Но чисто с точки зрения практики сборки достаточно крупного проекта на C++ процесс показался мне интересным и имеющим практическую ценность. Поэтому в этом посте я постараюсь коротко рассказать о нем, пока еще что-то помню.

Итак, на Linux понадобятся следующие зависимости:

sudo apt-get install subversion cmake ninja-build doxygen swig \ libedit-dev libncurses5-dev libxml2-dev libedit-dev

На FreeBSD я доустановил такие пакеты:

sudo pkg install subversion cmake ninja doxygen swig

Интересный момент номер первый. Нельзя просто так взять и собрать проект с отладочными символами. Скорее всего, линковка завершится неуспешно, так как ld будет прибит с OOM. Для решения этой проблемы программисты на C++ используют вместо штатного ld линковщик gold.

Установка gold в Linux:

sudo apt-get install binutils cd /usr/bin sudo mv ld ld.backup sudo ln -s ld.gold ld

Во FreeBSD:

sudo pkg install binutils cd /usr/bin sudo mv ld ld.backup sudo ln -s /usr/local/bin/ld.gold ld

Проверка – команда ld --version должна выводить что-то вроде:

GNU gold (GNU Binutils for Ubuntu 2.24) 1.11

Интересный момент номер два. В Ubuntu по умолчанию идет древний CMake версии 2.8. Для более быстрой компиляции при помощи Ninja настоятельно рекомендуется использовать CMake 3.2 или старше.

Говорим:

sudo apt-get remove --purge cmake sudo apt-get autoremove --purge sudo apt-add-repository ppa:george-edison55/cmake-3.x sudo apt-get update sudo apt-get install -V cmake

Во FreeBSD никаких дополнительных телодвижений не требуется, там CMake и так свежий.

Наконец, получение исходных кодов из SVN и компиляция. Я лично написал для этой цели такой скрипт:

#!/bin/sh set -e # Checkout LLVM svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm cd llvm/tools # Checkout Clang svn co http://llvm.org/svn/llvm-project/cfe/trunk clang # Checkout LLDB svn co http://llvm.org/svn/llvm-project/lldb/trunk lldb cd clang/tools # Checkout extra Clang Tools svn co http://llvm.org/svn/llvm-project/clang-tools-extra/trunk extra cd ../../../projects # Checkout Compiler-RT (required to build sanitizers) svn co http://llvm.org/svn/llvm-project/compiler-rt/trunk compiler-rt # Checkout Libomp (required for OpenMP support) svn co http://llvm.org/svn/llvm-project/openmp/trunk openmp # Checkout libcxx and libcxxabi svn co http://llvm.org/svn/llvm-project/libcxx/trunk libcxx svn co http://llvm.org/svn/llvm-project/libcxxabi/trunk libcxxabi # Get the Test Suite Source Code (be patient!) svn co http://llvm.org/svn/llvm-project/test-suite/trunk test-suite cd ../.. mkdir build cd build cmake ../llvm -G Ninja -DLLDB_DISABLE_CURSES:BOOL=TRUE \ -DCMAKE_BUILD_TYPE=Debug \ -DCMAKE_INSTALL_PREFIX=/home/ubuntu/llvm-trunk/ \ -DCMAKE_C_COMPILER=/usr/local/bin/clang37 \ -DCMAKE_CXX_COMPILER=/usr/local/bin/clang++37 \ -DCMAKE_C_FLAGS="-O0 -g" -DCMAKE_CXX_FLAGS="-O0 -g" ninja -j1 # ninja -j1 check-all # sudo ninja install

Во FreeBSD после установки я также создал руками несколько симлинков, для порядку:

cd /usr/local/bin sudo ln -s clang-3.9 clang++-3.9 sudo ln -s clang-3.9 clang-cpp-3.9

Замечания:

  • Насколько я понимаю, все, кроме самого LLVM, является опциональным и при необходимости можно не скачивать.
  • Помимо trunk можно указать, например, branches/release_38 или tags/RELEASE_380/final.
  • Флаг -j1 нужен для того, чтобы ninja ничего не распараллеливал и таким образом уместился по памяти. Своими глазами видел, как ninja -j4 съедает 10 Гб оперативы, а ведь в системе еще работает браузер и другие процессы. При сборке Release-версии можно смело делать -j4.
  • Какие бы опции вы не указали, все тесты все равно прогоняются в параллель.
  • Таргета uninstall не предусмотренно, поэтому либо выбирайте prefix с умом, либо используйте LXC. Вариант с checkinstall не рекомендую. Состаритесь, пока дождетесь завершения.
  • В хорошую погоду и с хорошим инетом исходники качаются 22 минуты. Сборка проекта на типичном железе занимает 1 час 59 минут. При этом требуется 25 Гб места на диске.

Вот так приходится страдать при сборке передовых проектов на C++. Вы все еще удивляетесь, почему я предпочитаю писать на C? :)