16 нояб. 2008 г.

Создаём пакет для Ubuntu. Часть 6. Использование Autotools

Итак, небольшое вступление... После многочисленных поисков, был найден небольшой, первый, я бы сказал, шаг к тому, чтобы осознать как же все-таки создаются распространяемые дистрибутивы. Для меня, основной сложностью в усвоении этой методики - это была проблема в познании языка M4, равно как и сама концепция файла configure.in. Видите ли, чтобы создать пакет требуется всего немного: написать вручную файл configure.in, в каждом используемом каталоге создать свой файл Makefile.am, потом выполнить ряд скриптов, сконфигурировать пакет и, если все прошло удачно, собрать его командой make.

Возможно, в этом нет ничего сложного, но многие конфигурационные шаблоны отличаются друг от друга, и для меня оказалось сложным просмотреть некоторую идею языка m4. Ведь, условно, нужно описать пакет, проверить зависимости, указать цели назначения и т.д... Ниже, я опишу простой способ создания пакета, который можно собрать, скомпилировать и даже установить. Если честно, этот способ прост, но во всяком случае позволил мне сдвинуться с, почти, мертвой точки.

Продолжим. Для следующего метода вам понадобятся так называемые autotools или autotoolset. Найти их можно по этому адресу http://autotoolset.sourceforge.net/. Здесь пакет доступен в качестве либо исходных кодов, либо в виде rpm пакета. Я думаю вам не составит труда воспользоваться утилитой alien для преобразования rpm пакета в deb.

После того, как вы установите его, вам следует изменить некоторые скрипты с помощью текстового редактора. А именно, исправить первую строку, где встречается использование sh на bash:

Вместо
#!/bin/sh
...

Записать
#!/bin/bash
...

Если так не сделать, то возможна работа с ошибками таких скриптов, как acmkdir и gpl, генерирующих необходимые файлы и директории.

Далее, когда вы все сделали, и имеете систему подготовленной к использованию, давайте попробуем создать наш первый распространяемый пакет, который так и назовем Hello. Кстати сказать, если вам нужен первоисточник, где я почерпнул необходимую информацию, то советую вам ознакомится с документом Developing software with GNU раздел Hello world with acmkdir.

Перейдите в любой каталог, где бы вы хотели начать создание своего приложения. В моем примере, я решил использовать каталог /tmp и выполните в нем команду acmkdir hello. В качестве аргумента я указал название моего пакета hello. Далее, оно задаст вам ряд вопросов, касающихся разработчика, и, в итоге, вам нужно согласиться с тем, что вы ввели. Вы должны получить на экране следующее:

$ acmkdir hello
Ready to create a new distribution skeleton directory.
The current working directory is:
--> /tmp
If you make a mistake and need to abort, press ctrl-C.

Name of distribution: hello
Your full name: Vest
Your email address: just@ask.me

Do you want to proceed? (y/n) y
+ Mode is default
+ Making directory hello
+ Making src directory
+ Making doc directory
+ Making m4 directory
+ Making config directory
+ Making default text files
+ Making INSTALL file link
+ Running reconf
- aclocal.
/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
- autoconf.
- autoheader.
autoheader: warning: missing template: CXX_HAS_BUGGY_FOR_LOOPS
autoheader: Use AC_DEFINE([CXX_HAS_BUGGY_FOR_LOOPS], [], [Description])
autoheader: warning: missing template: CXX_HAS_NO_BOOL
autoheader: warning: missing template: NDEBUG
autoheader: warning: missing template: YOUR_OS
- automake.
configure.ac:21: installing `config/config.guess'
configure.ac:21: installing `config/config.sub'
configure.ac:17: installing `config/install-sh'
configure.ac:17: installing `config/missing'
Makefile.am: installing `./INSTALL'
Makefile.am: installing `./COPYING'
configure.ac:16: required file `config.h.in' not found

Distribution directory is ready.
Please make sure to keep the files AUTHORS, NEWS, README, THANKS up to
date before cutting a distribution.

В 4-ой строке снизу (или 5-ой, если считать по символам /n :) ), видно, что в автоматически созданном файле configure.ac в строке 16 отсутствует шаблон config.h.in. Нам он, собственно не нужен, потому эту строку можно смело комментировать командой dnl, или совсем удалить её.

После каждого изменения файла configure.ac всегда следует выполнять скрипт reconf

$ ./reconf
- aclocal.
/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
- autoconf.
- autoheader.
autoheader: error: AC_CONFIG_HEADERS not found in configure.ac
- automake.

Для того, чтобы пересобрать все зависящие от него скрипты. Потом можно выполнить сам скрипт ./configure и make. В результате этого должно пройти конфигурирование и компиляция/сборка несуществующих исходных кодов. Теперь давайте создадим некоторый файл в каталоге src, с которого будет выполняться запуск нашего "Привет Мира".

/tmp/hello$ gedit src/main.cxx
// Vest (c) 2008
// Hello World
// main.cxx

#include

int main()
{
std::cout << "Hello World!" << std::endl;
return 0;
}

А потом, подправим шаблон Makefile.am, который по-умолчанию пуст. Приведем некоторые возможные опции файла Makefile.am:

ПеременнаяОписание
bin_PROGRAMS = prog1 prog2 ...Список исполняемых файлов, которые будут скомпилированы с помощью 'make', и установлены с помощью 'make install' в каталог '/prefix/bin', где 'prefix', обычно, это '/usr/local'.
lib_LIBRARIES = libfoo1.a libfoo2.a ...Список всех библиотек, которые будут скомпилированы с помощью 'make', и установлены с помощью 'make install' в каталог '/prefix/lib'.
prog_SOURCES = foo1.c foo2.c ... header1.h header2.h ...Список всех файлов, которые образовывают исходный код программы, включая заголовочные файлы. Присутствие заголовочных файлов не подразумевает того, что они будут установлены в '/prefix/include', но означает то, что они будут добавлены в дистрибутив ('make dist'). Если вы хотите установки публичных заголовочных файлов, вы должны упомянуть их в 'include_HEADERS'. Automake генерирует абстрактные правила для файлов C, C++ и Fortran. Для других языков, Вы должны предоставлять свои собственные правила.
prog_LDADD = $(top_builddir)/dir1/libfoo.a -lbar1 -lbar2 ...Список библиотек, которые должны быть подлинкованы с вашим исходным кодом. Установленные библиотеки должны использоваться с флагами '-l'. Удаляемые библиотеки должны упоминаться с использованием абсолютных имён (пример указан в предыдущем столбце).
prog_LDFLAGS = -L/dir1 -L/dir2 -L/dir3 ...Добавляет флаги '-L', которые нужны для поиска установленных библиотек, которые вы хотите подлинковать в 'prog_LDADD'.

Файл Makefile.am будет иметь вид:

/tmp/hello$ gedit src/Makefile.am
# Copyright (C) 2008 Vest <ваш@почтовый.ящик>
#
# This file is free software; as a special exception the author gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

bin_PROGRAMS = hello
hello_SOURCES = main.cxx

Теперь пакет можно реконфигурировать, и собирать (далее я приведу только последнюю, нужную информацию о том, что компиляция прошла успешно)

$ ./reconf
$ ./configure
$ make
...
Making all in src
make[1]: Вход в каталог `/tmp/hello/src'
g++ -DPACKAGE_NAME=\"hello\" -DPACKAGE_TARNAME=\"hello\" -DPACKAGE_VERSION=\"0.0.1\" -DPACKAGE_STRING=\"hello\ 0.0.1\" -DPACKAGE_BUGREPORT=\"Vest\ just@ask.me\" -DPACKAGE=\"hello\" -DVERSION=\"0.0.1\" -DCXX_HAS_BUGGY_FOR_LOOPS=1 -DYOUR_OS=\"i686-pc-linux-gnu\" -I. -g -O2 -MT main.o -MD -MP -MF .deps/main.Tpo -c -o main.o main.cxx
mv -f .deps/main.Tpo .deps/main.Po
g++ -g -O2 -o hello main.o
make[1]: Выход из каталога `/tmp/hello/src'
...
$ make distcheck
...
=============================================
hello-0.0.1 archives ready for distribution:
hello-0.0.1.tar.gz
hello-0.0.1.tar.bz2
=============================================

Как вы видите, было создано два архива. Внутри каждого из них лежат наши исходные файлы, доступные для распространения. Кстати сказать, внутри архивов наша программа будет лежать в каталоге 'hello-0.0.1'. Это пригодится нам при создании распространяемого пакета скомпилированного приложения. Проверить то, что наше приложение установится и запустится в системе можно следующим образом:

$ sudo make install
...
$ hello
Hello World!
$ whereis hello
hello: /usr/local/bin/hello
$ sudo make uninstall
...
$ hello
bash: /usr/local/bin/hello: No such file or directory

Вот собственно и все. В дальнейшем, я постараюсь описать более сложный пример, равно как и понять, почему после удаления приложения, присутствовала неизвестная ссылка, при повторном его запуске :) Похоже, что она где-то успела прописаться в системе или профиле пользователя.

Комментариев нет: