В некоторых случаях бывает необходимо самому собрать компилятор GNAT из исходных текстов. Например, если вы решили поэкспериментировать с компилятором и разобраться в его устройстве, или желаете получить более новую версию GNAT, чем предусмотрено в вашей операционной системе, или для вашей ОС нет бинарного дистрибутива. В этой статье мы попробуем осветить некоторые практические моменты построения компилятора GNAT.
Так как исходные тексты GNAT находятся в CVS дереве компилятора GCC (Gnu Compiler Collection) и его разработчики используют ОС Linux, то, очевидно, простейшим случаем является сборка GNAT под Linux из исходных текстов одной из последних версий GCC. Для построения вам понадобится
Для построения обычно используют две директории:
Выполните следующие команды:
tar xjf gcc-core-3.4.1.tar.bz2 tar xjf gcc-ada-3.4.1.tar.bz2 mkdir build cd build ../gcc-3.4.1/configure \ --prefix=/usr/local/gnat-3.4.1 \ --program-prefix=gnat \ --enable-languages="c,ada" make bootstrap make -C gcc gnatlib_and_tools make install
Далее начнется процесс построения и «make bootstrap» будет запускать скрипт configure в поддиректориях. Желательно проконтролировать определение работоспособности установленного Ада компилятора, иначе довольно длительная процедура построения будет безрезультатна. Для этого вскоре после надписи
Configuring in gcc
найдите строки
checking for gnatbind... gnatbind checking whether compiler driver understands Ada... yes
Если вместо yes стоит no, необходимо уточнить расположение и имя Ада компилятора. Если он называется gcc поставьте его в пути вперед стандартного gcc. Либо подскажите системе полный путь к компилятору
export CC=/usr/local/gnat-3.15p/bin/gcc make bootstrap
Процесс построения компилятора проходит в 3 стадии, в которых сначала строится компилятор при помощи системного gcc, затем строится вторая версия компилятора при помощи той, что получена на первой стадии, затем третья версия собирается при помощи второй. Это дает возможность проверить работу компилятора, сравнив результаты второй и третьей стадий компиляции. Процесс построения занимает около часа на современных машинах.
По окончании компиляции желательно запустить набор тестов ACATS, который распространяется вместе с исходными тестами компилятора начиная с версии gcc-3.4.
make check
Это займет еще 20 минут, и результат должен выглядеть примерно так:
=== acats Summary === # of expected passes 2322 # of unexpected failures 0
Все действия производятся под обычным (не root) пользователем системы, если не оговорено другое.
Исходные тексты компилятора были разархивированы в каталог /home/obj/gcc-3.4.3. (Вы конечно же можете выбрать любой другой каталог вместо /home/obj).
Перед построением компилятора настоятельно рекомендуется ознакомиться с инструкцией построения, индекс которой расположен в /home/obj/gcc-3.4.3/INSTALL/index.html
Создан каталог ~/setup/gcc-obj для файлов, созданных в процессе построения компилятора (Вы конечно же можете выбрать любой другой каталог вместо ~/setup/gcc-obj).
Необходимо инсталировать и поставить первым в пути GNAT-3.15p ссылка на него со страницы http://www.freebsd.org/ports/lang.html. Так же обязательно надо инсталировать GNU Make.
Конфигурирование производилось из каталога ~/setup/gcc-obj командой
/home/obj/gcc-3.4.3/configure --prefix=/usr/gcc-3.4.3 --enable-languages=ada,c
После конфигурирования запускался не
make bootstrap
а GNU Make
gmake bootstrap
Была непонятная проблема. gmake сразу не проходил, запинался на каком‐то этапе, не находил какую‐то библиотеку. Повторно запускался
make bootstrap
проходил эту ошибку, запинался несколько дальше, потому что makefile расчитан на GNU Make. В очередной раз запускался
gmake bootstrap
который уже доходил до конца.
После построения GCC, согласно инструкции, достраивались GNAT библиотеки и инструменты
cd gcc gmake gnatlib_and_tools cd ..
После построения запустились тесты
make check
В силу того, что для Cи‐тестов необходимы дополнительные инструменты, запустились только тесты Ada компилятора ACATS.
Некоторые тесты с префиксом cxg (Annex G.) не прошли, потому что использовался пакет по умолчанию a-numaux.ad? с недостаточной точностью вместо специфичного для платформы i386 86numaux.ad?. После копирования
cp /home/obj/gcc-3.4.3/gcc/ada/86numaux.ads \ ~/setup/gcc-obj/gcc/ada/rts/a-numaux.ads cp /home/obj/gcc-3.4.3/gcc/ada/86numaux.adb \ ~/setup/gcc-obj/gcc/ada/rts/a-numaux.adb
и перестройки Ада библиотек
cd gcc gmake gnatlib_and_tools cd ..
тесты ACATS прошли полностью.
Новый компилятор был инсталирован и прописан первым в пути. Инсталяцию необходимо производить под пользователем root
su gmake install exit
При использовании файлов проектов .gpr оказалось, что project manager не поддерживает библиотеки. После копирования
cp /home/obj/gcc-3.4.3/gcc/ada/5lml-tgt.adb \ ~/setup/gcc-obj/gcc/ada/tools/mlib-tgt.adb
перестройки Ада библиотек
cd gcc gmake gnatlib_and_tools cd ..
и инсталяции
su gmake install exit
поддержка библиотек менеджером проектов образовалась.
Утилита gnatmem предназначена для тестирования утечки памяти. В фирменной сборке ее построение требует библиотеки libaddr2line. Эта же библиотека нужна для функционирования пакета GNAT.Traceback.Symbolic, позволяющего расшифровывать трасировку стека в список номеров строк и имен файлов в исходном тексте программы.
В исходных текстах версии 3.15 есть патч на binutils который позволяет создать эту библиотеку. Для более поздних версий компилятора такого патча нет. В замен мы предлагаем другой способ получения утилиты gnatmem. Вместо корректировки binutils мы предлагаем процедуру, которая вызовет стандартную программу (из пакета binutils) addr2line и расшифрует ее результат.
Процедура построения gnatmake, предложенная Вадимом Годунко, выглядит следующим образом:
gnatmake gnatmem.adb -largs gmem.c version.c mya2l.c
Аналогичный метод был использован в сборках GNAT 3.13p Ada Linux Team и GNAT 3.15p Александром Гаввой. Аналогичная процедура, автор которой Juergen Pfeifer, в файле convert_addresses.c вызывает шел скрипт gnat_addr2line, обвертку вокруг addr2line, позволяет использовать addr2line из разных версий binutils.
Вадим Годунко, Дмитрий Анисимков, Максим Резник