Не так давно я заинтересовался вопросом сборки последней версии CLang и сопутствующих проектов LLVM-стека из исходных кодов. Не то, чтобы это было неописуемо захватывающим занятием. Но чисто с точки зрения практики сборки достаточно крупного проекта на C++ процесс показался мне интересным и имеющим практическую ценность. Поэтому в этом посте я постараюсь коротко рассказать о нем, пока еще что-то помню.
Итак, на Linux понадобятся следующие зависимости:
libedit-dev libncurses5-dev libxml2-dev libedit-dev
На FreeBSD я доустановил такие пакеты:
Интересный момент номер первый. Нельзя просто так взять и собрать проект с отладочными символами. Скорее всего, линковка завершится неуспешно, так как ld будет прибит с OOM . Для решения этой проблемы программисты на C++ используют вместо штатного ld линковщик gold.
Установка gold в Linux:
cd / usr / bin
sudo mv ld ld.backup
sudo ln -s ld.gold ld
Во FreeBSD:
cd / usr / bin
sudo mv ld ld.backup
sudo ln -s / usr / local / bin / ld.gold ld
Проверка — команда ld --version
должна выводить что-то вроде:
Интересный момент номер два. В Ubuntu по умолчанию идет древний CMake версии 2.8. Для более быстрой компиляции при помощи Ninja настоятельно рекомендуется использовать CMake 3.2 или старше.
Говорим:
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 и компиляция. Я лично написал для этой цели такой скрипт:
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 после установки я также создал руками несколько симлинков, для порядку:
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 ? 🙂