3. Autoconf 2.12

3.1 Úvod do Autoconf

Autoconf je soubor skriptů pro shell a maker pro m4. M4 je vedle cpp tradiční UNIXový preprocesor maker. Je dobré jej znát, zvlášť pokud byste chtěli psát pro Autoconf nová makra, avšak v běžných případech se při používání Autoconfu zcela obejdete bez jeho znalosti.

Mít preprocesor M4 nainstalovaný je pro programátora podmínkou pro použítí Autoconfu - avšak koncový uživatel M4 nepotřebuje. Zjednodušené schema použití Autoconfu je následující:

  1. vytvoříte configure.in - soubor obsahující příkazy shellu a již připravená makra (již naprogramované testy zkoumající různé vlastnosti systému).
  2. příkazem autoconf vytvoříte soubor configure. O configure jsme si již řekli v předchozích kapitolách. Jedná se o soubor shellovských příkazů, které před vlastním překladem programu instalující spustí). Tento skript musí být maximálně přenositelný - proto je nepřípustné používat konstrukce specifické pouze pro určitý druh shellu (například bash). V opačném případě bychom ztratili velikou výhodu configure skriptů: přenositelnost.

3.2 Soubory a adresáře spřízněné s autoconf

/usr/share/aclocal/
V tomto adresáři jsou umístěny soubory obsahující rozličná standardní M4 makra a testy.
aclocal.m4
Soubor určený pro Vaše makra, která nejsou ve standardní distribuci Autoconfu.
config.cache
Provést některé testy bývá časově náročné, provedení mnoha testů několikrát za sebou úmorné. Proto si ./configure kešuje výsledky testů do tohoto souboru a testy tedy provede pouze poprvé.
config.log
Do tohoto souboru ./configure zaznamenává výsledky testů. Pokud nějaký test selhal (například se nezdařilo nalézt nějakou knihovnu), pak zde jistě naleznete proč.
config.status
Skript, který testy neprovádí testy, pouze zapíše (již získané) výsledky do souborů.

3.3 configure.in

3.3.1 autoscan

Autoscan je v Perlu napsaný skript, jenž může sloužit jako berlička pro začínajícího autokonfiguristu (ehm, ... slibuji, že podobné střílení si z/do českého jazyka se již nebude opakovad =), který chce získat přibližný přehled o testech, které by měl ve svém configure.in použít. Autoscan prošmejdí vaše zdrojáky a vytvoří configure.in, který může sloužit jako základ pro vaše další experimenty. Rozhodne však nebuďte zklamáni, pokud autoscan za Vás neudělá všechnu práci - je to pouze berlička, nikoliv náhrada za programátora.

3.3.2 Struktura configure.in

Naše studium hlubin souboru configure.in začneme obecným přehledem doporučené struktury tohoto souboru:

AC_INIT( src/kopretina.c )
     testy programů
     testy knihoven
     testy hlavičkových souborů
     testy typedef
     testy structur
     testy charakteristik překladače
     testy funkcí knihoven
     testy služeb systému
AC_OUTPUT( Makefile ... )

V následujících odstavcích si přiblížíme význam jednotlivých maker.

3.3.3 AC_INIT

AC_INIT(jméno_souboru)
Jak již jméno napovídá, jedná se o makro, které configure inicialisuje - tedy makro, které musíte v configure.in použít jako prvé. Parametr (jméno souboru) umožňuje configure skriptu zkontrolovat, zda se při jeho spuštění nacházíte na pravém místě (v nejvyšším adresáři zdrojáků). Nastavuje mimo jiné též proměnnou top_srcdir (lze ovlivnit parametrem ./configure --srcdir).

3.3.4 AC_OUTPUT

 AC_OUTPUT(soubor:šablona ...)
Jestliže předchozí makro se používá v configure.in souborech jako první, AC_OUTPUT je vždy tím posledním. AC_OUTPUT zapíše výsledky svého bádání do zadaných souborů. Jak zápis probíhá?

Během svého tápání po systému configure ukládá výsledky testů do proměnných (například CC - překladač C, LIBS - knihovny atp). Po ukončení všech testů příkaz AC_OUTPUT v šablonách nahradí výskyt všech řetězců @PROMĚNNÁ@ obsahem této proměnné. Není-li šablona v příkazu AC_OUTPUT zadána (například AC_OUTPUT(Makefile), použije se jako šablona implicitně soubor s příponou .in (v našem případě tedy Makefile.in).

Makefile.in:                       Makefile

CFLAGS = @CFLAGS@ @MY_CFLAGS@      CFLAGS = -g -Wall 
CC = @CC@                          CC = gcc

(příklad samo sebou pouze demonstrativní - záhy poznáte, že podobou práci za Vás rád udělá automake :)

3.3.5 Proměnné

Autoconf Vám nabízí již spoustu standardních proměnných - například bin_dir, data_dir, exec_prefix, libdir, mandir, srcdir, CFLAGS, CC,.... Mimo ně můžete ve svém configure skriptu též používat proměnné vlastní (je to přece skript pro shell). Pokud byste chtěli obsah své proměnné zapsat pomocí AC_OUTPUT, musíte však Autoconf s touto proměnnou seznámit makrem AC_SUBST:

AC_SUBST(MY_CFLAGS)

3.3.6 Komentáře

Pro snadnou orientaci a přehlednost lze v configure.in používat komentáře. Jednak lze použít klasické komentáře shellu (#) - které budou bez změny zapsány při vytvoření configure, nebo můžete použít příkaz M4 dnl (discard to new line). Je dobrým zvykem napsat na začátek každého configure.in:

dnl Process this file with autoconf to produce a configure script

3.3.7 Define a hlavičkové soubory

Pomocí maker AC_DEFINE a AC_DEFINE_UNQUOTED lze v configure definovat symboly pro preprocesor C. configure zařadí do proměnné DEFS řetězec "-DSYMBOL[=VALUE]" pro každý definovaný symbol.

Pokud jste nabyli dojmu, že Vašich definic je pro příkazovou řádku přespříliš, můžete použitím AC_CONFIGURE_HEADER stanovit, do kterého hlavičkového souboru budou všechny definice zapsány. Program autoheader Vám pomůže takový hlavičkový soubor připravit.

3.3.8 Podadresáře

Někdy se může stát, že obsahem Vašeho balíčku budou dvě nebo tři více méně nezávislé části. Makrem AC_CONFIG_SUBDIRS určíte, ve kterých podadresářích je třeba spustit skript configure. Tyto zároveň spuštěné configure skripty pak například sdílejí config.cache soubory a podobně.

3.4 Standardní testy

Když jsme se nyní seznámili s některými základními rysy configure.in souboru, můžeme se více ponořit do přehršle standardních testů, které nám configure.in nabízí.

Jak jste si již jistě všimli v části určené doporučené struktuře configure.in souboru, bylo by možné rozdělit testy do několika skupin. V každé skupině naleznete bohatou úrodu testů - snažil jsem se proto vystihnout pouze testy nejpoužívanější či obecné testy - připravené šablony - s jejichž pomocí lehce napíšete testy vlastní.

3.4.1 Program

AC_PROG_AWK, AC_PROG_CC, AC_PROG_CPP, AC_PROG_CXX, AC_PROG_INSTALL, AC_PROG_LEX..

Jsou jména alespoň některých standardních testů, které vyzkouší, zda daný program existuje a nastaví příslušné proměnné potřebné při jeho použití (například CC a CFLAGS v případě AC_PROG_CC).

Jak jsem slíbil, tak ke každému okruhu specialisovaných testů existuje několik testů obecných:

AC_CHECK_PROG (VARIABLE, PROG-TO-CHECK-FOR, VALUE-IF-FOUND [, VALUE-IF-NOT-FOUND [, PATH, [ REJECT ]]])

dnl Check for perl
AC_CHECK_PROG(PERL, perl, yes, no)

VARIABLE
Do této proměnné bude uložen výsledek testu (VALUE-IF-FOUND pokud byl program nalezen, v opačném případě VALUE-IF-NOT-FOUND). Proměnná bude automaticky exportována makrem AC_SUBST.
PROG-TO-CHECK-FOR
Jaký program hledat
PATH
Kde jej hledat
REJECT
Jaké výsledky zamítnout

Mimo tento test autoconf zná ještě mnoho dalších: podobný AC_CHECK_PROG je například AC_PATH_PROG, který do proměnné uloží plnou cestu k programu. AC_CHECK_PROGS a AC_PATH_PROGS slouží k hledání více než jednoho programu.

3.4.2 Knihovny

Existenci libovolné knihovny prověříme následujícím testem:

AC_CHECK_LIB((LIBRARY, FUNCTION [, ACTION-IF-FOUND [,ACTION-IF-NOT-FOUND [, OTHER-LIBRARIES]]])

dnl Check for math library
AC_CHECK_LIB(m, sin)

LIBRARY
je jméno knihovny, kterou hledáme.
FUNCTION
funkce, kterou v knihovně hledáme, abychom se ujistili, že jsme našli správnou knihovnu a nikoliv pouze knihovnu se shodným názvem (stává se: například GUI knihovna Qt (-lqt) a Quick Threads knihovna pro Guile (v předešlých versích též -lqt)). Pokud jsme si jménem jistí či nám na funkcí nezáleží, postačí, pokud zde napíšeme main.
ACTION-IF-FOUND, ACTION-IF-NOT-FOUND
jsou shellovské příkazy, které budou vykonány podle výsledku testu. Pokud žádné příkazy nespecifikujeme, pak configure přidá "-lLIBRARY" do proměnné LIBS a definuje symbol HAVE_LIBLIBRARY.
OTHER-LIBRARIES
Pokud přilinkování jiné knihovny je podmínkou pro úspěšné použití testované knihovny, pak toto je pravé místo pro seznam požadovaných knihoven.

Jak celý test funguje? configure vytvoří malý prográmek stavající se z funkce main a volání funkce, kterou hledáte. Nakonec se celý zdroják pokusí přeložit. Pokud je program sestaven bez potíží, je knihovna považována za nalezenou.

3.4.3 Funkce v knihovnách

AC_FUNC_ALLOCA, AC_FUNC_MEMCMP, AC_FUNC_MMAP, AC_FUNC_VFORK...

je jen malá ukázka z velké plejády testů, které hledají různé funkce po rozličných knihovnách. Pokud je naleznou, definují symboly HAVE_... - například HAVE_MMAP a podobně.

AC_CHECK_FUNC (FUNCTION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]])

Je obecnější obdobou výše zmíněných funkcí. ACTION-IF-FOUND a jeho průvodce ACTION-IF-NOT-FOUND jsou v autoconf velmi časté konstrukce, proto dále již jejich význam nebudu vysvětlovat.

3.4.4 Hlavičkové soubory

Mezi testy, které zkoumají přítomnost různých hlavičkovách souborů patří například AC_HEADER_STDC, jímž ověříte existenci standardních hlavičkových souborů (stdlib.h, string.h, ...), nebo AC_HEADER_DIRENT, který Vám pomůže ze zmatků panujících s různě pojmenovanými soubory dirent.h, sys/ndir.h, sys/dir.h, ndir.h. Není nad standardy, že?

Pokud v pestré škále testů autoconfu nenaleznete test právě pro ten Váš hlavičkový soubor, z nesnází Vám pomůže toto makro:

AC_CHECK_HEADER (HEADER-FILE, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]])

3.4.5 Typy

AC_HEADER_STAT, AC_HEADER_TIME, AC_STRUCT_TM, AC_TYPE_PID_T, AC_TYPE_SIZE_T, ...

... jistě nebudou jediné typy, jejichž existenci lze testovat pomocí autoconf. S AC_CHECK_TYPE si můžete posvítit i na ty nejneobvyklejší typy, které si dovedete představit.

AC_CHECK_TYPE (TYPE, DEFAULT)

3.4.6 Vlastnosti překladače a systému

Přestože tato kapitola nebyla uvedena mezi prvními, testy v ní uvedené patří mezi nejdůležitější.

AC_C_BIGENDIAN
v závislosti na architektuře (a pořadí, ve kterém jsou uloženy bajty) definuje WORD_BIGENDIAN.
AC_C_CONST, AC_C_INLINE
Vyzkoumá, zda překladač C podporuje klíčová slova const a inline
AC_CHECK_SIZEOF (type,cross-type)
V mnoha případech se bez tohoto testu neobejdeme. AC_CHECK_SIZEOF zjistí velikost daného typu a definuje příslušný symbol pro překladač


AC_CHECK_SIZEOF(double) => #define SIZEOF_DOUBLE 8

AC_CHECK_SIZEOF(int *) => #define SIZEOF_INT_P 4

3.4.7 Makra, která se nevešla do škatulek

Zřejmě budou trošku zklamáni ti, kteří z názvu kapitolky usuzovali na postmoderní pohádku či název nového večerníčku pro děti :*) Na druhou stranu zcela jistě oblažíme programátorská srdéčka, jež si již stačila oblíbit makra, které autoconf nabízí:

AC_PATH_XTRA
hledá X Windows, nastaví X_CFLAGS, X_LIBS,..
AC_TRY_LINK, AC_TRY_COMPILE, AC_TRY_RUN
Těžko si představit makra, která by předčila tato v universálností.
AC_MSG_CHECKING, AC_MSG_RESULT, AC_MSG_ERROR, AC_MSG_WARN
Těmito makry můžete uživatele informovat, co se právě v configure skriptu kutíte, popřípadě upozornit, že vzhledem ke zjištěným skutečnostem nebudou některé funkce programu dostupné.

3.4.8 Škatulka poslední: parametry configure skriptu

Jestliže jste již někdy spustili configure skript s parametrem --help a byli jste zaskočeni poněkud rozsáhlejším seznamem možných parametrů tohoto skriptu, pak vězte, že tento nemalý katalog můžete obohatit též o vlastní exempláře.

Tato možnost přijde vhod, zejména pokud Vaš balíček obsahuje volitelné komponenty, které nejsou k provozu programu nezbytné, či komponenty, které jsou "nadstandardní" (například X front-end). Rovněž je vhodné těmito parametry dát uživateli možnost zakázat (povolit) některé vlastnosti programů (podpora locales ...)

AC_ARG_WITH (PACKAGE, HELP-STRING, ACTION-IF-GIVEN, ACTION-IF-NOT-GIVEN)
AC_ARG_ENABLE (FEATURE, HELP-STRING, ACTION-IF-GIVEN, ACTION-IF-NOT-GIVEN)

 AC_ARG_WITH(pomnenka, podpora pro pomněnky, POMNENKY=jo, POMNENKY=NE) 

3.5 Závěr, příklady

Ač se to na první pohled nezdá, autoconf je velmi mocný nástroj v boji proti zmatkům v dnešních taky-standardech a úspěšně pomáhá správcům projektů zápolit s nepřehlednou džunglí různých obskurních konfigurací.

Myslím, že je zbytečné vytvářet až do konce configure.in pro pomyslný projekt Kopretina. Nejlepší učebnicí v psaní configure.in souborů Vám budou již hotové projekty, které ve své distribuci autoconf aktivně používají (například GIMP, Gtk, GNOME,...). Napsat configure.in zabere i nezkušenému uživateli velmi málo času (zvlášť pokud si představíme, kolik bolení hlavy ušetříme jak sobě, tak uživatelům našeho projektu).

Pro Vaši přibližnou představu, jaké testy by se mohly objevit v configure.in středně malého projektu, začlenil jsem configure.in, který jsem napsal pro GAG (plug-in pro GIMP).

Následující kapitola pojednává o hlavních rysech Automake, který ušetří další fůru práce programátorům (tedy, alespoň těm, kteří mají otevřené hlavy a jsou připraveni se něco nového naučit :)


(c) 1998 0rfelyus