27 февр. 2009 г.

Autotools с нуля

На этот раз, я постараюсь объяснить, возможно, знакомую всем по предыдущим постам тему об использовании Autotools. Мне пришлось этот путь пройти заново, и немного по-другому, для того, чтобы мой проект выглядел так, как того требуют Gnome Games. Так получилось, что я написал им письмо о том, что у меня есть игра Gnome Quod (для Ubuntu вы сможете использовать мой автоматический репозиторий на PPA), и я бы хотел привести её к виду, соответствующему Gnome Games. Автор сборника игр, выделил мне ряд требований, решив которые, я смогу попробовать заново попросить его о включении моей игры в их пакет. Ну да ладно, это будет не скоро, и я сомневаюсь в этом, но давайте приступим к подготовке нового пакета, прежней игры.

Здесь я буду описывать конкретные вещи, что я делал, и по-возможности, что получал. Для подробной информации по тому или иному макросу, советую вам поискать в мануалах.

Для начала создадим папку с названием gnome-quod. Так будет называться мой каталог, где будут находиться все исходники, весь пакет, откуда потом, мы будем создавать пакеты. Затем, создаём файл-шаблон configure.ac. Его будет просматривать скрипт Autotools с названием autoreconf. Этот скрипт занимает одно из главных положений, в нашем проекте. Первоначальное содержание configure.ac будет следующим (комментарии только для осмысления.):

# ======================== initialization ===============================
Здесь будет описываться инициализация проекта: имя, начальный каталог и пр.

# ==================== basic compiler settings ==========================
Основные опции компилятора (например, используемый язык)

# ==================== checks for libraries =============================
Проверка существования библиотек

# ==================== checks for header files ==========================
Проверка существования заголовочных файлов (если нужно)

# ===== checks for typedefs, structures and compiler characteristics ====
Проверка типов, структур, особенностей компилятора

# ==================== checks for library functions =====================
Проверка функций библиотек. Полезно, когда версия библиотеки мало ли соответствует требуемой, но в ней нет функции, или, например, вы не уточняете версию библиотеки, и потому в случае отсутствия функции, можете реализовать её сами.

# ==================== generate files ===================================
Здесь создаются файлы, которые потом используются make'ом

AC_OUTPUT -- эта строка даёт всему начало

Порядок, который я описал, важен, но не существенно. Но главное не путать конец с началом. А вообще лучше придерживаться этого шаблона. Я встречал его во многих исходных файлах. Так что, будет у вас как у всех , если конечно, вам это не мешает. Теперь давайте добавим, в отдельные группы следующие макросы. Они должны описывать наш проект так, чтобы он работал.

# ======================== initialization ===============================
AC_INIT([Gnome Quod],
        [0.4.0],
        [vest@mail.com],
        [gnome-quod]) -- длинное имя, версия пакета, адрес куда стоит писать bug-репорты, краткое имя пакета

AC_CONFIG_SRCDIR([src/main.c]) -- проверка безопасности, что по этому адресу находится заведомо известный исходный файл
AC_CONFIG_HEADERS([config.h]) -- здесь создаётся заголовочный конфигурационный файл, который может быть использован в исходных файлах (в частности, там определена директива NDEBUG, см. ниже)
AM_INIT_AUTOMAKE([-Wall -Werror dist-bzip2]) -- включаем компилятору все предостережения и ошибки, чтобы подробно видеть всё на экране, о процессе компилции, дистрибутив распространяется в виде упакованного файла bz2
AC_DEFINE([NDEBUG], [], [Disable debugging information]) -- эта строка нужна лично мне, так как я использую assert функции, и если что, мне их нужно отключать

# ==================== basic compiler settings ==========================
AC_PROG_CC -- используем только Си компилятор
AM_PROG_CC_C_O -- нужно использовать вместо AC_PROG_CC_C_O, позволяет использовать флаги для каждой цели в Makefile
AC_HEADER_STDC -- проверка стандартных заголовочных файлов "stdlib.h", "stdarg.h", "string.h", "float.h". Это уже не нужно, так как они всегда есть, можно не проверять.

# ==================== generate files ===================================
AC_CONFIG_FILES([
  Makefile
  src/Makefile
]) -- происходит вызов AC_OUTPUT для каждого файла.
AC_OUTPUT -- создаёт много файлов, которые нам нужны

Далее создаём файлы-шаблоны Makefile.am и src/Makefile.am:

# Makefile.am
SUBDIRS = src

# src/Makefile.am
bin_PROGRAMS = quod
quod_SOURCES = main.c

Конечно же нам нужно создать main.c, с неким Hello World'ом.

#include <config.h>
#include <stdio.h>

int main(int argc, char** argv)
{
    printf("Hello World!\n");

    return 0;
}

Вот собственно и всё, на данный момент, далее выполняем следующие команды:

~/gnome-quod$ autoreconf --install
/usr/share/aclocal/lf_x11.m4:33: warning: underquoted definition of LF_PATH_XLIB
/usr/share/aclocal/lf_x11.m4:33: run info '(automake)Extending aclocal'
/usr/share/aclocal/lf_x11.m4:33: or see http://sources.redhat.com/automake/automake.html#Extending-aclocal
configure.ac:14: installing `./compile'
configure.ac:9: installing `./install-sh'
configure.ac:9: installing `./missing'
src/Makefile.am: installing `./depcomp'
Makefile.am: installing `./INSTALL'
Makefile.am: required file `./NEWS' not found
Makefile.am: required file `./README' not found
Makefile.am: required file `./AUTHORS' not found
Makefile.am: required file `./ChangeLog' not found
Makefile.am: installing `./COPYING'
autoreconf: automake failed with exit status: 1

Как вы видите, получили ошибки. Связаны они с тем, что наш проект полностью соответствует GNU стандарту, согласно configure.ac, но на деле таковым не является. Требуется создать самому следующие файлы, и желательно заполнить их. Вы можете посмотреть пример заполнения в любом серьёзном проекте, либо обратившись к Learning the GNU development tools. Создадим их и попробуем ещё раз (я ещё создал файл THANKS, название говорит само за себя):

$ ls
AUTHORS ChangeLog configure.ac Makefile.am NEWS README THANKS src

$ autoreconf --install
/usr/share/aclocal/lf_x11.m4:33: warning: underquoted definition of LF_PATH_XLIB
/usr/share/aclocal/lf_x11.m4:33: run info '(automake)Extending aclocal'
/usr/share/aclocal/lf_x11.m4:33: or see http://sources.redhat.com/automake/automake.html#Extending-aclocal
configure.ac:14: installing `./compile'
configure.ac:9: installing `./install-sh'
configure.ac:9: installing `./missing'
src/Makefile.am: installing `./depcomp'
Makefile.am: installing `./INSTALL'
Makefile.am: installing `./COPYING'

Каждый раз, когда меняется один из шаблонов, следует вызывать autoreconf без параметров. Иногда вы встретите в пакетах файл autogen.sh, по идеи он похож с предыдущим. Не вдаваясь в подробности этапов конфигурирования, здесь осуществляется поочерёдный вызов некоторых скриптов, входящих в состав Autotools.

Можно избежать проблем с тем, что не существует файлов, для этого стоит "сказать", что мы не соответствуем стандарту, для этого следует изменить макрос AM_INIT_AUTOMAKE следующим образом:

...
AM_INIT_AUTOMAKE([-Wall -Werror dist-bzip2 foreign])
...

Теперь поочерёдно выполним следующие команды, и взглянем на результат:

$ ./configure
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
....
checking for ANSI C header files... yes
configure: creating ./config.status
config.status: creating Makefile
config.status: creating src/Makefile
config.status: creating config.h
config.status: config.h is unchanged
config.status: executing depfiles commands

$ make
make all-recursive
make[1]: Вход в каталог `/home/vest/gnome-quod'
Making all in src
make[2]: Вход в каталог `/home/vest/gnome-quod/src'
gcc -DHAVE_CONFIG_H -I. -I.. -g -O2 -MT main.o -MD -MP -MF .deps/main.Tpo -c -o main.o main.c
mv -f .deps/main.Tpo .deps/main.Po
gcc -g -O2 -o quod main.o
make[2]: Выход из каталога `/home/vest/gnome-quod/src'
make[2]: Вход в каталог `/home/vest/gnome-quod'
make[2]: Выход из каталога `/home/vest/gnome-quod'
make[1]: Выход из каталога `/home/vest/gnome-quod'

$ src/quod
Hello World!

Здесь я решил не урезать вывод, чтобы вы могли заметить. Тут поэтапно проходит конфигурирование, компиляция программы и последующий её запуск. Если вам нужен распространяемый пакет, выполните следующую команду make dist, в текущем каталоге вы получите следующие два файла:

$ ls -l gnome-quod-*
-rw-r--r-- 1 vest vest 73173 2009-02-27 01:01 gnome-quod-0.4.0.tar.bz2
-rw-r--r-- 1 vest vest 87568 2009-02-27 01:01 gnome-quod-0.4.0.tar.gz

Итак, на сегодня это пока всё. Вся вышеперечисленная информация, чуть более чем подробно объясняется в этой презентации (http://www.lrde.epita.fr/~adl/autotools.html). Советую с ней ознакомиться.