Aap включает поддержку компиляции программ на языках C и C++. Ниже
приведен пример в одну строчку, который компилирует программу
"myprog" из четырех исходных файлов:
:program myprog : main.c common.c various.c args.c
Пускай вас не вводит в заблуждение простота данного примера, потому что
Aap берет на себя несколько различных проблем:
Зависимости вычисляются автоматически: нет необходимости специально
указывать заголовочные файлы или делать зависимости в стиле make.
Данное описание будет работоспособно без изменений на большинстве
систем. Aap самостоятельно найдет компилятор и линковщик и сформирует
аргументы при их запуске.
Объектные файлы сохраняться в раздельных директориях для каждой сборки,
поэтому вы можете компилировать различные версии без очистки директории.
Aap создает лог файл, находящийся в AAPDIR/log, который содержит всю
информацию о происшедшем. Если возникла ошибка и нет возможности
просмотреть выводимую информацию на тот момент, вам нет необходимости
повторять процесс сборки снова и/или перенаправлять вывод в файл.
Несколько целей уже добавлены автоматически: `aap install` установит
программу, а `aap clean` удалит сгенерированные файлы.
Это же может сделать с помощью нескольких дополнительных утилит и
make. Но в этом случае Makefile будет намного больше и менее портабельный -
проект сложнее поддерживать.
Варианты сборки
Теперь давайте скомпилируем программу в двух вариантах: итоговой (релиз)
и отладочной версиях. Aap имеет инструменты для сборки нескольких
вариантов одной программы. Все что вам нужно это указать варианты, которые
вы хотите скомпилировать и указать отличия между ними. Листинг 5
наглядно показывает данную возможность.
Листинг 5. Сборки релиза и debug вариантов
:variant Build
release
OPTIMIZE = 4
Target = myprog
debug
DEBUG = yes
Target = myprogd
:program $Target : main.c common.c various.c args.c
В первая строке командой :variant указывается имя
переменной, которая будет использовано для выбора конкретного варианта сборки. Вы можете
установить эту переменную в командной строке, например,
`aap Build=debug` соберет отладочную версию. Без аргументов будет собран
вариант 'release', потому что он указан в описании первым.
Замечание: обратите большое внимание на отступы команды :variant - вних
вся соль. Возможные значение имеют более маленький отступ относительно
команды :variant, чем команды для каждого значения, которые имеют
больший отступ. Как мы уже говорили в прошлой статье, данная особенность
- часть синтаксиса языка Python.
Вариант release устанавливает переменную OPTIMIZE. Значением данной
переменной является число от 0 до 9, определяющей степень оптимизации
кода, сгенерированного компилятором. Хочу отметить, что правило "чем
больше, тем лучше" в данном случае не действует: при больших значениях
программа может работать не корректно, а может и вовсе не
скомпилироваться. Разумным максимальным значением является 3. Причем
значение переменной OPTIMIZE автоматически будет превращено в аргумент
того компилятора, который доступен у вас в системе. Вариант debug предает
переменной DEBUG значение 'yes'. По умолчанию, DEBUG равно 'no'. В свою
очередь Target содержит название исполняемого файла, который получиться в
итоге. У двух этих вариантов названия разные, поэтому оба варианта могут
быть работоспособны одновременно.
Приятным моментом использования вариантов служит то, что объектный файл
для каждого варианта сохраняется автоматически в отдельную директорию.
Когда вы переключаетесь между двумя вариантам Aap НЕ пересобирает все
файлы, что значительно экономит ваше время.
Поддержка другими языками
Для языков отличных от C и C++ необходимо импортировать модуль языка.
Несколько стандартных модулей поставляются вместе с Aap. Например, для
сборки программы на языке "D", где "D" - новый язык программирования
необходимо:
:import d
:program myprog : main.d common.d various.d args.d
Команда :import d используется для загрузки поддержки языка "D". В
остальном процесс сборки не имеет отличий.
Для того, что добавить поддержку нужного языка возможно написать модуль
самостоятельно. Т.к Aap - это проект с открытыми исходными текстами, вы
можете поддержать его добавив свой модуль в дистрибутив Aap. Пока этого не
случилось положите файл в директорию, где хранятся модули Aap, и он
будет работать как plugin.
Сборка приложения для KDE
Создание приложения для KDE включает в себя работу с множеством
инструментов: с помощью Qt Designer создаються графический интерфейс,
генерируются header файлы из описаний пользовательского интерфейса
(файл .ui) и генерируется межпроцессный код (обработка событий и
прочие). Тем не менее, описания для сборки KDE-приложения может быть
таким же простым как это:
:import kde
:program logger : main.cpp
logwidget.ui
dcop.h {filetype = skel}
{var_OBJSUF = _skel.o}
Из этих трех файлов только main.cpp может быть скомпилирован
непосредственно. Файл logwidget.ui (Qt Designer) необходимо обработать
первым с помощью `uic`, что бы сгенерировать необходимые для компиляции
файлы. Затем используется `moc`. Aap самостоятельно распознает
расширение .ui и позаботиться обо всем этом сам. Процесс обработки App
выглядит следующим образом: ui -> h -> moc -> объектный файл, заметьте,
Aap сильно облегчает ваш труд. Решение данной задачи в Makefile
выглядело бы большим количеством запутанных правил.
Файл dcop.h содержит специальные элементы KDE, но имеет стандартное
расширение. Это не может быть определенно автоматически, поэтому
специально задается атрибут 'filetype'. Команде :program так же
необходимо знать имя объектного файла, который соответственно
устанавливаеться атрибутом var_OBJSUF. Вам нет необходимости даже знать
какие именно инструменты используются при сборке - все это скрыто
внутри модуля Aap. Данное решение намного проще и результативнее, чем то
что можно было достигнуть с помощью automake.
В чем Aap лучше make
До этого момента мы использовали только высокоуровневые команды Aap для
быстрого решения не очень сложных задач. Для нестандартных задач, нам
нужно чуть иначе посмотреть на зависимости и команды. В основном это
работает так же как и в Makefile. Кроме shell команд, вы можете
использовать более переносимые команды Aap. Если этого недостаточно,
можно использовать скриптинг на Python.
Листинг 6 показывает как могут выглядеть низкоуровневые описания. Все
зависимости хорошо видны: цель 'all' зависит от 'hello', где
'hello' компилируется из файла hello.с, в свою очередь helloc.c создается с
нуля.
Листинг 6. Использование Aap как замену make
all : hello
# Ручная компиляция программы
hello : hello.c
:sys cc -o $target $source
# Способ сгенерировать программу на C (неэффективный, громоздкий)
# просто как пример
hello.c:
:print Generating $target
:print >! $target $(#)include $(<)stdio.h$(>)
:print >> $target main() {
:print >> $target printf("Hello World!
");
:print >> $target return 0;
:print >> $target }
В нашем описании команды для сборки - это Aap команды, поэтому
необходимо использовать команду :sys для выполнения системной команды.
В нашем примере, :sys cc запускает компилятор языка C. К сожалению, это
будет работать только на тех системах, где существует команда `cc`. К
видим, использование shell команд в описаниях уменьшают переносимость.
Файл hello.c генерируется с помощью команд :print. В первой строке
используется '>! $target' для переписать уже существующий файл. Без
восклицательного знака вы получите сообщение о ошибке, если файл уже
существует. Это строка содержит $(#), которые записывают файл
специальный символ #, указывающий в исходном файле начало комментария. По
этому же принципу, $(<) и $(>) используются для записи символов < и >
соответственно.
Файл hello.c генерируется только тогда, когда он не был создан ранее.
Правда, файл может быть сгенерирован снова, в другой ситуации: когда
изменится хоть одна из команд :print, потому что измениться и сигнатура
команд сборки. Когда изменяются команды в описании, Aap самостоятельно
знает какие именно цели нужно пересобрать.
Файл сгенерирован с помощью Aap команд - ни каких shell команд не было
использовано. Эта часть описания гарантированно будет работать на всех
системах. Это большое преимущество, но есть и недостатки: количество Aap
команд ограничено. Когда вам нужно большая функциональность не в ущерб
переносимости скрипта используйте Python.
Полный контроль над происходящим в описаниях Aap возможен с
Python, Листинг 7 содержит пример наложения патчей на Vim. Цикл используется
для генерации списка имен патчей, начиная с vim-6.2.001 и заканчивая
последним номером, указанным в переменной LASTPATCH. Каждый патч
закачивается и применяться.
Листинг 7. Использование Python'а для создания списка имен
LASTPATCH = 144
# Генерирование списка патчей
@Patches = ''
@for i in range(1, int(LASTPATCH) + 1):
@ Patches = Patches + ("6.2.%03d " % i)
# Цель по умолчанию разрешает все патчи
all: done/$*Patches
# Удостоверимся, что две директории существуют
:mkdir {force} patches done
# Правило для применения патча
:rule done/% : patches/% {fetch =
ftp://ftp.vim.org/pub/vim/%file%}
:sys patch < $source
:touch $target
Обычно нет необходимости использовать Python в описаниях, но хорошо
знать как можно просто решить сложные и запутанные задачи, когда они
возникнут.
Установка программ
В прошлой статье (см. ссылку в конце статьи) мы рассмотрели пример, где
rsync инсталлировался в систему средствами Aap, если он не был
установлен. Данный механизм может быть задействован напрямую. Например,
для установки Agide необходимо выполнить команду `aap --install
agide`. Agide - это графическая IDE для Aap, другая часть проекта A-A-P. Вы
можете использовать ее для сборки и отладки программ с помощью Vim и
gdb. Она пока остается на ранней стадии разработки, но этого уже может
быть достаточно для разработки и отладки программ на C.
На данный момент доступно большое количество пакетов, и еще больше будет
добавлено в скором времени. Список доступных программ для установки
(пакетов) можно обнаружить на http://www.a-a-p.org/packages.html . Aap
так же может быть установлен самостоятельно. Обновление до последней
версии программы выполняется с помощью команды `aap --install
aap`. Данная команда переписывает любую существующую версию Aap.
Заключение
Теперь вы имеете представление о задачах, которые вы можете
решить с помощью Aap. Когда вы начнете самостоятельно эксперементировать
большую помощь может оказать документация на официальном сайте проекта.
В документации освещается множество вопросов, которые не вошли в данную
статью, например, использование CVS, автоматическая конфигурации (как
autoconf) и прочие.
Bram Moolenaar - это лидер проекта и главный разработчик Aap. Он больше
известен своей работой над текстовым редактором Vim. Его работу над Aap
спонсирует Stichting NLnet (http://NLnet.nl).
Ссылки
http://moolenaar.net - домашняя страница Bram'a.
http://a-a-p.org - официальный сайт Aap
http://www.vim.org - текстовый редактор, от автора Aap
http://www.xakep.ru/post/22470/default.htm - предыдущая статья