html текст
All interests
  • All interests
  • Design
  • Food
  • Gadgets
  • Humor
  • News
  • Photo
  • Travel
  • Video
Click to see the next recommended page
Like it
Don't like
Add to Favorites

Краткое введение в GNU autoconf из песочницы

I saw a book entitled «Die GNU Autotools» and I thought «My feelings exactly». Turns out the book was in German1. ©

Можно долго рассуждать о несовершенстве сего инструментария, о превосходстве CMake/QMake/подставьте_вашу_любимую систему сборки, но проекты, использующие autotools, окружают нас повсюду, и стоит как минимум знать, что это за зверь и с чем его едят, чтобы при попытке сделать, а то и отправить разработчикам патч, не править автосгенерированные файлы, чем я не так давно занимался.

Так же следует понимать, что именно autoconf системой сборки не является вообще, это система конфигурации перед сборкой. autoconf почему-то многие считают неким монстром, «проверяющим 15 давно несуществующих версий компилятора Fortran, а потом поддержку ключей этими компиляторами», что не совсем верно, ибо оно делает ровно то, что ему скажут. Другое дело, что многие просто копипастят его конфиг из проекта в проект, в итоге результат получается ужасающим.

В данной статье (планируется всё же осилить цикл) я хотел бы рассказать про autoconf, зачем он нужен и как его использовать.

N. B. К статье я подготовил архив с исходниками, можно его скачать.

Лучше всего пояснить, зачем используется autoconf на простом примере сферической программы в POSIX-окружении.

Итак, предположим, у вас есть программа, состоящая из одного исполняемого файла, которая читает строку из конфига и пишет в лог. Это неплохой сферический пример, так как очень многие программы помимо своей полезной нагрузки именно это и делают:
#include <stdlib.h>
#include <stdio.h>

void main (int argc, char**argv[])
{
        FILE* config = fopen ("/etc/hellolog.conf", "r");
        FILE* log = fopen ("/var/log/hellolog.log", "a");
        char*line;
        getline (&line, NULL, config);
        fprintf (log, "Line from config %s", line);
        fclose(config);
        fclose(log);
        free(line);
}


И простой Makefile для её сборки:
#!/usr/bin/make -f
SOURCES = main.c
all: hellolog
hellolog: $(SOURCES)
        gcc -o $@ $(SOURCES)
clean:
        rm hellolog

.PHONY: all clean


Если в процессе прочтения будут какие-то вопросы по Makefile-ам, настоятельно рекомендуется прочитать доку по make.

В принципе, бери да пользуйся, но по-хорошему программу надо бы в систему ещё и установить. Догадаться о том, что надо скопировать исполняемый файл в /bin можно, но лучше всё же сделать цели install и uninstall заодно:

install:
        install hellolog $(DESTDIR)/usr/bin/hellolog
uninstall:
        rm $(DESTDIR)/usr/bin/hellolog


install — *nix-овая утилита, которая помимо копирования файла выполняет манипуляции с правами доступа к нему.
DESTDIR здесь нужен, чтобы была возможность проводить установку не сразу в систему, а во временную директорию, чтобы система сборки пакетов могла их оттуда вычитать и упаковать. Мы же помним, что использовать make install напрямую — это очень плохо, правда?

Остаётся одна немаловажная проблема — все пути у нас захардкодены. Если кому-то нужно установить программу в домашнюю директорию, в /opt/ или просто используется дистрибутив, чихать хотевший на FHS, возникнут проблемы.

В принципе, мы можем принимать пути к нужным директориям в качестве аргументов make как делаем это с DESTDIR (make переопределяет заданные в Makefile значения, так что можно сделать и умолчания. Для начала модифицируем исходный код:

...
#define CONFIG_PATH CONFDIR"/hellolog.conf"
#define LOG_PATH LOCALSTATEDIR"/helloconf.log"

void main (int argc, char**argv[])
{
        printf ("Config %s Log %s\n", CONFIG_PATH, LOG_PATH);
        FILE* config = fopen (CONFIG_PATH, "r");
        FILE* log = fopen (LOG_PATH, "a");
...


Теперь добавим определения нужных путей в Makefile, попутно вынеся их в CFLAGS, чтобы было удобнее реиспользовать при компиляции нескольких файлов, а так же модифицируем цели install и uninstall:

#!/usr/bin/make -f
SOURCES = main.c
prefix = /usr/local
bindir = $(prefix)/bin
sysconfdir = $(prefix)/etc
sharedstatedir = $(prefix)/var
CFLAGS = -DCONFDIR='"$(sysconfdir)"' -DLOCALSTATEDIR='"$(sharedstatedir)"'
all: hellolog
hellolog: $(SOURCES)
        gcc $(CFLAGS) -o $@ $(SOURCES)
clean:
        rm hellolog
install:
        install hellolog $(DESTDIR)$(bindir)/hellolog
uninstall:
        rm $(DESTDIR)$(bindir)/hellolog
.PHONY: all clean install uninstall


Уже намного лучше. Мы можем сделать make prefix=/opt/hellolog && make install prefix=/opt/hellolog и изолировать файлы своей программы в этой директории. Проблема теперь в том, что целей сборки может быть больше, и каждый раз писать кучу параметров не вполне удобно. По-хорошему всё надо вынести в некий настроечный скрипт, который получит параметры конфигурации, а в дальнейшем просто использовать make.

В бородатые времена такие скрипты писались вручную, заодно в целях переносимости кода (это у нас тут только POSIX используется, в настоящих программах ещё куча библиотек, причём некоторые из них взаимозаменяемы в какой-то части) в него включали проверки зависимостей и платформозависимые изменения логики Makefile. В какой-то момент количество скриптового кода, который передовой китайской техникой реиспользования кода под названием «копипаст» переносился из проекта в проект, стало превышать мыслимые пределы. В итоге один находчивый человек решил вынести часто используемые куски в макросы на M4 (M+4 буквы слова Macro, язык макросов разработанный Керниганом и Ритчи), что вылилось в autoconf. В дальнейшем он получил большое распространение, а затем на его инфраструктуре были созданы инструменты automake и libtool. Тем не менее, суть autoconf осталась прежней (набор макросов) и он может с успехом использоваться отдельно.

Посмотрим, что мы можем сделать с нашей игрушечной программой. В принципе, набор изменений крайне небольшой и касается только Makefile. Предопределёные значения путей заменим на placeholder-ы, а сам Makefile переименуем в Makefile.in:

prefix = @prefix@
exec_prefix = @exec_prefix@
bindir = @bindir@
sysconfdir = @sysconfdir@
sharedstatedir = @sharedstatedir@


Так же добавим минимально полезный конфигурационный файл configure.ac:

AC_INIT([hellolog], [1.0])
AC_CONFIG_FILES([Makefile])
AC_OUTPUT


Запускаем autoreconf и получаем в текущей директории файл configure, который имеет всем привычный формат командной строки. Делаем ./configure --prefix=/opt && make && ./hellolog и видим, что все пути прописаны правильно. Теперь посмотрим, что же произошло «под капотом».

Единственный файл, который принимает autoconf — это configure.ac, являющийся обычный Bourne-shell скриптом, использующим макросы, соответственно AC_INIT и AC_OUTPUT являются обязательным скелетом, AC_CONFIG_FILES же указывает список файлов, в которых необходимо провести подстановки. Тут же можно сделать ещё кучу разных действий наподобие проверки наличия зависимостей. Я рекомендую для этого использовать pkg-config, для него существует отдельный набор макросов. Далее генерируется скрипт configure, которому не нужно ничего кроме Bourne-совместимого шелла и awk (раньше использовался sed).

./configure в свою очередь после проверок генерирует скрипт config.status, содержащий нужные параметры подстановки и запускает его. А тот уже в свою очередь генерирует файлы со значениями этих подстановок. Так что если у вас поменялся только Makefile, то достаточно запустить лишь config.status.

Итого, тулчейн выглядит так: autoreconf + configure.ac -> configure -> config.status -> итоговые файлы.

В принципе, ничто не мешает использовать autoconf вместе с вашей любимой средой сборки. Я, например, использую с MSBuild для своих программ, заточенных под Mono, Makefile-враппер для этого тривиален.

Ссылки
Мануал по GNU Make
Мануал по M4
Мануал по Autoconf (на английском)

Примечания
1. die (читается как «ди») — определённый артикль множественного числа в немецком.
Читать дальше
Twitter
Одноклассники
Мой Мир

материал с habrahabr.ru

1

      Add

      You can create thematic collections and keep, for instance, all recipes in one place so you will never lose them.

      No images found
      Previous Next 0 / 0
      500
      • Advertisement
      • Animals
      • Architecture
      • Art
      • Auto
      • Aviation
      • Books
      • Cartoons
      • Celebrities
      • Children
      • Culture
      • Design
      • Economics
      • Education
      • Entertainment
      • Fashion
      • Fitness
      • Food
      • Gadgets
      • Games
      • Health
      • History
      • Hobby
      • Humor
      • Interior
      • Moto
      • Movies
      • Music
      • Nature
      • News
      • Photo
      • Pictures
      • Politics
      • Psychology
      • Science
      • Society
      • Sport
      • Technology
      • Travel
      • Video
      • Weapons
      • Web
      • Work
        Submit
        Valid formats are JPG, PNG, GIF.
        Not more than 5 Мb, please.
        30
        surfingbird.ru/site/
        RSS format guidelines
        500
        • Advertisement
        • Animals
        • Architecture
        • Art
        • Auto
        • Aviation
        • Books
        • Cartoons
        • Celebrities
        • Children
        • Culture
        • Design
        • Economics
        • Education
        • Entertainment
        • Fashion
        • Fitness
        • Food
        • Gadgets
        • Games
        • Health
        • History
        • Hobby
        • Humor
        • Interior
        • Moto
        • Movies
        • Music
        • Nature
        • News
        • Photo
        • Pictures
        • Politics
        • Psychology
        • Science
        • Society
        • Sport
        • Technology
        • Travel
        • Video
        • Weapons
        • Web
        • Work

          Submit

          Thank you! Wait for moderation.

          Тебе это не нравится?

          You can block the domain, tag, user or channel, and we'll stop recommend it to you. You can always unblock them in your settings.

          • habrahabr.ru
          • домен habrahabr.ru

          Get a link

          Спасибо, твоя жалоба принята.

          Log on to Surfingbird

          Recover
          Sign up

          or

          Welcome to Surfingbird.com!

          You'll find thousands of interesting pages, photos, and videos inside.
          Join!

          • Personal
            recommendations

          • Stash
            interesting and useful stuff

          • Anywhere,
            anytime

          Do we already know you? Login or restore the password.

          Close

          Add to collection

             

            Facebook

            Ваш профиль на рассмотрении, обновите страницу через несколько секунд

            Facebook

            К сожалению, вы не попадаете под условия акции