LLVM+Clang 3.2: собираем самим собой под Windows

от автора

LLVM — это набор «кирпичиков» для построения компиляторов, а clang — новый компилятор C++ на его основе. По сравнению с gcc — обеспечивается большая скорость компиляции при сравнимом качестве кода (но это пожалуй нужно будет протестировать), более человеко-понятные исходники (т.к. они не несут десятилетия жесточайшей C-only разработки).

Помимо этого, Clang и llvm распространяются под лицензией BSD, в отличии от GPLv3 у GCC. BSD позволяет не открывать исходники при распространении исполняемых файлов.

С LLVM+CLang будет интересно поиграть любому кто когда-либо хотел написать свой компилятор, или считает, что компилятор собранный своими руками дает более теплый бинарный код.

БОльшая часть часть разработчиков llvm/clang используют его под Linux/MacOS — и там его сборка/установка не вызывает каких либо проблем, путь основательно протоптан. А вот в случае windows ситуация несколько осложняется (голову пришлось поломать изрядно, пока разбирался) — об обходе нескольких граблей при сборке, о том, что связывает clang и gcc, и какие баги придется фиксить в релизе — под катом.

Сборка

Существуют 2 основных способа собирать llvm+clang под windows:

CMake позволяет сгенерировать solution для Visual Studio. clang+llvm до сих пор зависит от компонент gcc (стандартной библиотеки например, но работа над устранением зависимости идет), потому даже собирая clang в Visual Studio эта зависимость останется, и у вас получится дичайшая солянка из кусков clang, VS и gcc, где все компоненты со временем будут случайно менять версии. Помимо этого, на данный момент Visual Studio 2012 падает при сборке clang 3.2 с оптимизацией — Microsoft работает над фиксом. В свете этого, я решил Visual Studio не использовать.

Mingw32+MSYS. Mingw32 — содержит gcc и тонкую обертку, реализующую linux-подобное окружение для программ, трансляцию путей windows<>linux style. Специфичные функции (вроде fork) полностью не реализованы, потому совместимость хуже чем у cygwin, но работает все быстрее. Частичное описание процесса сборки — на сайте llvm.

MSYS — дает нам «linux» shell, в котором можно запускать стандартные билд-скрипты. Именно по этому пути мы и пойдем.

Запускаем консоль MSYS, качаем исходники llvm, clang, compiler-rt (низкоуровневый системный код для сборки), распаковываем llvm в корень вашей папки с исходниками, clang — в llvm/tools, compiler-rt — в llvm/projects. Проверяем версию gcc — для llvm 3.2 подойдет gcc не новее 4.6.2 (с 4.7.2 у меня он сам себя не смог собрать, но и слишком старый тоже нельзя).

После этого создаем каталог для бинарников, например llvm/bin, переходим туда, и выполняем команду:

../configure --disable-docs --enable-optimized --enable-targets=x86 --prefix=/newclang 

После завершения конфигурации — пишем make, и начнется сборка проекта. Когда закончится make — можем сделать make install, и наши скомпилированные бинарники запишутся в каталог newclang в корне файловой системы MSYS.

Далее — самосборка. Она нужна чтобы убедиться, что компилятор работает надежно, мы не упустили каких-либо проблем, и чтобы устранить одну переменную: «версия ксенокомпилятора». Перключаем систему на использование только что собранного clang для дальнейшей сборки им самого себя:

export CXX=/newclang/bin/clang++.exe export CC=/newclang/bin/clang.exe

Создаем новый каталог для компиляции, снова запускаем там ../configure… и затем make. Но clang не соберется самим собой так просто, иначе в чем был бы смысл этой статьи?

Исправляем проблемы

Скорость работы
Первое что бросается в глаза — собранный clang чудовищно тормозит, и это при релизной сборке и очень хорошем железе! Даже простейший «clang++ —version» может выполнятся несколько секунд. Решение простое: нужно собирать его со статической линковкой, тогда все работает быстро, но ценой увеличенного размера бинарников (десятки мегабайт).

Export LDFLAGS=-static

Ошибка «Only alloca-wide stores can be split and recomposed»
Это баг в llvm, который уже пофикшен в репозитории и войдет в 3.3. Но да, релиз clang 3.2 из-за этого не может собрать себя.

Нужно накатить на файл \lib\Transforms\Scalar\SROA.cpp фикс из ревизии svn 170270:

=================================================================== --- SROA.cpp	(revision 170269) +++ SROA.cpp	(revision 170270) @@ -2607,7 +2607,7 @@               TD.getTypeStoreSizeInBits(V->getType()) &&               "Non-byte-multiple bit width");        assert(V->getType()->getIntegerBitWidth() == -             TD.getTypeSizeInBits(OldAI.getAllocatedType()) && +             TD.getTypeAllocSizeInBits(OldAI.getAllocatedType()) &&               "Only alloca-wide stores can be split and recomposed");        IntegerType *NarrowTy = Type::getIntNTy(SI.getContext(), Size * 8);        V = extractInteger(TD, IRB, V, NarrowTy, BeginOffset, 

Многопроцессорная сборка зависает
Если вы используете make -j 8 для ускорения сборки — то да, mingw32 может под настроение намертво виснуть в середине сборки. Решения я не нашел.

clang не может найти стандартные библиотеки
Как мы помним, он использует стандартные библиотеки из gcc. Для того, чтобы он их нашел — они должны быть правильной версии, и лежать в ожидаемом clang-ом месте.

Не падайте со стула, пути для поиска файлов «захардкожены» в файле \tools\clang\lib\Frontend\InitHeaderSearch.cpp. Если у вас MinGW стоит не в папке по умолчанию, clang его точно не найдет. Затем, clang проверяет только некоторые версии gcc для поиска директории с заголовочными файлами, убедитесь что у вас стоит подходящая версия gcc.

Устанавливать пакеты нужной версии в MSYS можно так:

mingw-get install "gcc=4.6.*" mingw-get install "g++=4.6.*"

Вот теперь clang сможет собрать сам себя, и вы получите свежий и быстрый, собранный самим собой компилятор.

Резюме

Open source software — это узкая протоптанная тропинка в дремучем лесу. Пока вы ходите там же, где и все — у вас все прекрасно. Но стоит сделать шаг в сторону — и придется работать бензопилой.

ссылка на оригинал статьи http://habrahabr.ru/post/167281/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *