# Výuka sestavování v IDE Anjuta

## Úvod

Když přicházíte ze světa Windows a poprvé spustíte aplikaci Anjuta, můžete si říct: „Jé, to vypadá jak MS Visual C++, to dobře znám. Takže pochopit Anjutu bude pro mě malina.“ Anjuta opravdu vypadá jak Microsoft Visual Studio nebo Borland's C++ Builder. Jsou zde ale významné rozdíly v samotném sestavovacím systému.

Jestli jste s programováním začali z příkazové řádky, nejspíše jste již slyšeli o Autotools. Jedná se o hlavní a pravděpodobně trochu zastrašující část vývojářského prostředí.

Cílem Anjuty je usnadnit používání již existujících vývojářských nástrojů. Její hlavní sestavovací systém používá standardní sestavovací systém Linuxu: Autotools. Tato příručka je aktualizovanou verzí pokročilé příručky k IDE Anjuta od Oliviera Pinçona. Vysvětluje, jak sestavovací systém funguje bez Anjuty a jak se používá s ní. Předpokládá u vás jen základní znalosti C nebo C++ a byla napsán pro použití s verzí Anjuta 2.6 (září 2008).

Když najdete chybu, budete potřebovat podrobnější vysvětlení nebo budete mít nápad na vylepšení této příručky nebo Anjuty obecně, můžete:

- Vyplnit chybové hlášení do databáze bugzilla pro projekt Anjuta.

- Poslat zprávu do vývojářské poštovní konference projektu Anjuta na adrese anjuta-devel@lists.sourceforge.net.

- Připojit se ke kanálu IRC projektu Anjuta na adrese #anjuta on irc.gnome.org

## Sestavení projektu

Tato kapitola objasňuje, jak sestavit program, počínaje úplně základním nástrojem – kompilátorem. Je důležité začít takto, abyste pochopili, jak to funguje, protože každý další nástroj přidává novou vrstvu nad ten předchozí.

### Použití GCC

Zde je typický příkaz pro vygenerování spustitelného souboru ze zdrojových kódů v jazyce C pomocí GCC:

    $gcc -g -Wall -I/usr/include/libxml2/libxml -lxml2 main.c aux.c -o tut_prog

Tento příkaz říká GCC, aby zkompiloval zdrojové kódy main.c a aux.c a vytvořil binární soubor nazvaný „tut_prog“ (zkráceni z „tutorial program“ – „výukový program“). Jednotlivé přepínače mají následující význam:

`-g`

- Říká GCC, aby do výsledného programu přidal ladicí informace.

`-Wall`

- „Warning all“, což znamená vypisovat všechna varování. Tento přepínač používá jen kompilátor jazyka C.

`-Idir `složka``

- Zajistí, že se hlavičkové soubory (jako je #include <myheader.h>) budou hledat ve složce `složka`. Tento přepínač používá pouze preprocesor jazyka C.

`-llib `knihovna``

- Odkaz na `knihovnu`, zde konkrétně libxml2, pro potřeby linkeru.

Ve skutečnosti kompilaci neprovádí přímo GCC. Jen převezme parametry zadané uživatelem a zavolá jiné programy a předá jim potřebné parametry, případně včetně některých výchozích. Takto se postupně provedou čtyři fáze kompilace.

#### Fáze kompilace pomocí GCC

#### Preprocesor

Každý soubor se zdrojovým kódem v jazyce C projde přes preprocesor nazvaný cpp. V této fázy se rozvinou všechny vložené soubory a makra – zdrojový kód se předpřipraví (anglicky preproces). Výsledný soubor s příponou `.i` se generuje jen výjimečně, ale může být zajímavé se podívat, jak složitě a rozsáhle se makra rozvíjejí. Nechast si soubor vytvořit se dá zavoláním cpp přímo nebo zavoláním `-E` s přepínačem GCC. Druhé zmíněné je lepší, protože preprocesoru předá navíc některé výchozí hodnoty.

#### Kompilátor

V této fázi jsou jednotlivé soubory zkompilovány do assemblerového kódu. Použitý kompilátor odvisí od použitého jazyka ve zdrojovém kódu, zde je to C. Jedná se o složitý program, protože neexistuje přepis jedna k jedné mezi instrukcí C a instrukcí assembleru. Například, požadavek na co nejrychlejší a na co nejmenší program vygenerují různou posloupnost assemblerových instrukcí. Assembler je jazyk závislý na použitém počítači, nejčastěji to asi bude x86. Výstupem je pro člověka čitelný zdrojový kód v assembleru v souboru s příponou `.s`. Stejně jako u výstupu z preprocesoru, ani tyto soubory se normálně nezapisují na disk. Jestli se ale chcete na soubory podívat, můžete kompilaci v této fázi zastavit spuštěním GCC s přepínačem `-S`.

#### Assembler

V této fázi jsou jednotlivé soubory zpracovány assemblerem: kód je převeden to objektových souborů s příponou `.o`. To je podstatně jednodušší než kompilace, protože každá instrukce odpovídá jedna k jedné unikátnímu kódu. Objektový soubor obsahuje doplňující informace pro ladění a linkovací program. Objektový soubor má binární formát, na počítačích s novými verzemi Linuxu nazývaný ELF. Abyste si jej mohli prohlédnou, potřebujete speciální program, jako je třeba objdump. Můžete psát programy v assembleru i přímo ručně do souborů s příponou `.s` a pak je převádět programem as, stejně jako to dělá GCC. Výsledné objektové soubory se běžné zapisují na disk, protože závisí jen na příslušném souboru se zdrojovým kódem C (včetně všech vložených souborů). Když změníte jeden zdrojový soubor, stačí nově vygenerovat jen příslušné objektové soubory. Skončit v této fázi, bez následného slinkování, můžete použitím přepínače `-c` pro GCC.

#### Linker

Tato fáze slouží ke zkombinování všech objektových souborů a knihoven do jednoho spustitelného souboru. Výsledkem je binární soubor ve formátu velmi podobném objektovým souborům, v Linuxu je to dokonce tentýž formát.

### Použití make

V situaci, kdy se program skládá z velkého množství zdrojových souborů, je mnohem rychlejší objektové soubory zachovávat a znovu kompilovat jen ty zdrojové soubory, které je potřeba. To se dá automatizovat pomocí programu make. Ten spouští program napsaný ve formátu makefile, normálně pojmenovaný `Makefile`. Příklad pro předchozí ukázkový program by mohl vypadat takto:

#### Jednoduchý soubor Makefile

    CC=gcc 	# kompilátor je gcc
    CFLAGS=-g -Wall -I/usr/include/libxml2
    LIBS=-lxml2

    tut_prog: main.o aux.o   # co je potřeba pro získání „tut_prog“…
    	$(CC) $(LIBS) main.o aux.o -o tut_prog # … a jak jej získat z jednotlivých dílků.

    main.o: main.c
    	$(CC) -c $(CFLAGS) main.c

    aux.o: aux.c
    	$(CC) -c $(CFLAGS) aux.c

Soubory Makefile jsou jistým druhem skriptových programů, ale místo zapsané posloupnosti toho, co se má udělat, aby se dospělo k výsledku, definují určitá pravidla. Program make pak tato pravidla používá v různém pořadí, aby dosáhl žádaného výsledku.

#### Proměnné

Stejně jako v jiných programovacích jazycích, můžete i souborech makefile definovat proměnné. Všechny proměnné obsahují řetězec nebo seznam řetězců oddělených bílými znaky. Proměnná je definovaná pomocí následující syntaxe: `nazev`=`hodnota`. Její hodnotu pak můžete získat zápisem $(`nazev`) nebo ${`nazev`}. V předchozím příkladu jsou definované tři proměnné – CC, CFLAGS a LIBS.

Proměnné je možné předefinovat, když se volá make, v příkazové řádce nebo pomocí hodnot z proměnných prostředí. Navíc make obsahuje některá výchozí pravidla používající předdefinované proměnné. Zde je seznam nejběžnějších z nich:

`CC`

- Program pro kompilaci z jazyka C; výchozí je „cc“

`CXX`

- Program pro kompilaci z jazyka C++; výchozí je „g++“

`CPP`

- Program použitý jako preprocesor jazyka C; výchozí je „$(CC) -E“

`FC`

- Program pro kompilaci z jazyka Fortran; výchozí je „f77“

`RM`

- Program pro odtraňování souborů; výchozí je „rm -f“

`CFLAGS`

- Doplňující přepínače pro kompilátor jazyka C

`CXXFLAGS`

- Doplňující přepínače pro kompilátor jazyka C++

`CPPFLAGS`

- Doplňující přepínače pro kompilátor jazyka C++

`CXXFLAGS`

- Doplňující přepínače pro preprocesor jazyka C

`FFLAGS`

- Doplňující přepínače pro kompilátor jazyka Fortran

`LDFLAGS`

- Doplňující přepínače pro linker

#### Pravidla

Základní syntax pro pravidla make je:

    cíl: předpoklady
    	příkazy
    	…

Údaje `cíl` a `předpoklady` jsou normálně soubory, ale mohou to být i akce. Pravidlo je interpretováno, když je potřeba vytvořit cíl, případně jej aktualizovat, pokud je starší než předpoklad. Pro interpretaci je potřeba mít splněné všechny předpoklady a následně jsou pak provedeny všechny příkazy.

make začne s prvním cílem v souboru Makefile, nebo s tím, který je předaný z příkazové řádky, a hledá pro něj pravidlo. Pokud nemá pravidlo žádné předpoklady, provedou se související příkazy a tím vše skončí. Pokud ale existují, před spuštěním příkazů hledá make pravidla, která mají jednotlivé předpoklady jako cíle a pro ně celý postup opakuje.

Když v příkladu výše spustíte `make` nebo `make tut_prog`, provede make následující:

    Hledá pravidlo s cílem tut_prog
    Najde jej s předpoklady mani.o aux.o
    	Hledá pravidlo s cílem main.o
    	Najde jej s předpokladem main.c
    		Hledá pravidlo s cílem main.c
    		Nenajde jej (main.c je zdrojový soubor)
    	Pokud main.o neexistuje nebo je starší než main.c
    		Zkompiluje main.c, bez linkování (-c switch)
    	Hledá pravidlo s cílem aux.o
    	Najde jej s předpokladem aux.c
    		Hledá pravidlo s cílem aux.c
    		Nenajde jej (aux.c je zdrojový soubor)
    	Pokud aux.o neexistuje nebo je starší než aux.c
    		Zkompiluje aux.c, bez linkování (-c switch)
    Pokud je tut_prog starší než main.o nebo aux.o
    	Slinkuje main.o, aux.o a libxml2

Podobně, jako je tomu u proměnných, i u cílů je definováno několik obedně používaných názvů:

`all`

- Provést vše

`check`

- Po sestavené programu provést automatizované testy

`clean`

- Odstranit všechny soubory, které make vytvořil

`distclean`

- Odstranit více souborů, než clean; může odstranit i Makefile samotný

`dist`

- Vytvořit distribuční balíček, například komprimovaný tar

`install`

- Nainstalovat cíl vytvořený pomocí make; kvůli instalaci do systémových složek je potřeba spustit pod uživatelem root

`uninstall`

- Odstranit soubory, které make nainstaloval

Program zkompilovaný ze zdrojových kódů se standardně nainstaluje do `/usr/local`. Když chcete to takovéto systémové složky instalovat (nebo z ní naopak něco odinstalovat), musíte být pře spuštěním `make install` přihlášení jako uživatel root, nejlépe pomocí `su` nebo `sudo`.

### Použití Autotools

Pokud chcete sestavit program na jiném systému, mohlo by být použití samotného make poněkud obtížné. Mohl by být potřeba jiný kompilátor jazyka C. Některé funkce C by mohly scházet, mít jiný název, být deklarované s jinou hlavičkou apod. Dalo by se to sice řešit povolováním různých částí kód pomocí direktiv #if, #ifdef a podobných ve zdrojovém kódu, ale uživatel by se musel o vše postarat sám. A takové úpravy nejsou triviální, protože existuje spousta systémů ve spoustě variací.

Svobodný software se často šíří v podobě zdrojových kódů. Je podstatné, aby jej bylo možné zkompilovat na různých systémech bez technických znalostí. Autotools jsou navržené k tomu, aby to řešily, a nejspíše jste se již setkali s magickou kombinací `„./configure; make; make install“`. Možná jste si všimli, že v sestavovacím procesu figuruje spousta souborů. Celkově se zdá všechno poněkud komplikované. Takže, co se vlastně děje, když kompilujete software?

#### Vstupní soubory

Projekt Autotools přichází přinejmenším s konfiguračním skriptem nazvaným `configure` a se šablonou pro Makefile nazvanou `Makefile.in`. Normálně bývá v každé složce projektu jedna šablona. Mimo to bývá v projektu ještě několik dalších souborů používaných Autotools, ale ty nejsou vysloveně nutné, nebo se generují automaticky.

Když se do těchto souborů podíváte, zjistíte, že jsou trochu komplikovanější. Ale nebojte se, jsou generované automaticky pomocí Autotools ze šablon, které jsou pro napsání mnohem jednoduší, jak je vysvětleno v create-autotools. V tuto chvíli se jimi nebudeme zabývat a budeme předpokládat, že ve chvíli, kdy stáhneme zdrojový balíček, již existují.

#### Configure

Ve skutečnosti na sestavení balíčku založeného na autotools nepotřebujete Autotools, protože configure je shellový skript běžící běžící na nejzákladnějším shellu: `sh`. Zkoumá váš systém pomocí kontroly jednotlivých vlastností a podle šablony zapisuje Makefile.

Abyste mohli sestavit projekt používající knihovnu, potřebujete o knihovně více informací, tj. další soubory. Pro knihovny, které se používají v programech napsaných v C, potřebujete příslušné hlavičkové soubory. Ty musí být nainstalované v systému a typicky je najdete v tzv. vývojářských balíčcích. Například pro knihovnu libxml2 existují dva balíčky:

- `libxml2` nutný ke spuštění programu, který jej používá, a instalovaný automaticky jako závislost takového programu.

- `libxml2-devel` nutný k sestavení programu, který jej používá. Pokud jej nemáte nainstalovaný, zobrazí configure chybové hlášení.

##### Zpracování pomocí configure

configure vytvoří všechny soubory ve složce, ze které je zavolán. Tato složka je pak složkou sestavení. Když jej spustíte ze složky se zdrojovými soubory, pomocí `./configure`, bude složka sestavení tamtéž.

configure přijímá na příkazové řádce několik přepínačů. Používají se k instalaci souborů do různých složek, k zakázání některých částí projektu, aby měl menší výslednou velikost a nebo se vynechala nechtěná knihovna, nebo k vynucení hodnot pro některé proměnné make (viz build-make-vars). Seznam přepínačů získáte spuštěním `configure --help`. Zde je seznam nejběžnějších z nich:

`--help`

- Seznam dostupných voleb

`--host `hostitel``

- Zkompilovat pro spuštění na jiném systému (tzv. křížová kompilace)

`--prefix `složka``

- Určí kořenovou složku pro instalaci projektu; výchozí je /usr/local

configure vytváří pár dodatečných souborů, které nejsou až tak důležité. `config.log` je záznam, který se může hodit k dohledání podrobností, když je něco špatně. `config.status` je další shellový skript, pomocí kterého se dá obnovit aktuální konfigurace. `config.h` je hlavičkový soubor generovaný podobně jako `Makefile` ze šablony, konkrétně z `config.h.in`, pokud existuje.

#### make

Soubory Makefile vygenerované příkazem configure jsou sice trochu komplikovanější, ale pořád to jsou standardní soubory ve formátu makefile. Definují všechny standardní cíle požadované standardem GNU.

- `make` nebo `make all` sestaví program.

- `make install` nainstaluje program.

- `make distclean` odstraní všechny soubory vygenerované příkazem configure, takže dostanete projekt do stavu, jako byl před rozbalení distribučního balíčku.

### Použití IDE Anjuta

Nyní se podíváme na uživatelské rozhraní Anjuty, ve kterém můžete spouštět všechny tyto příkazy bez použití příkazové řádky.

#### Configure

Protože Anjuta používá Autotools, je první krok podobný – potřebujete spustit skript configure. Vyberte Sestavit Konfigurovat projekt… a objeví se následující dialogové okno:

##### Dialogové okno konfigurace

Zaškrtávací políčko Přegenerovat projekt v tuto chvíli popisovat nebudeme, protože to patří k tématu vytváření projektu (viz create-autotools-generate).

Pole Konfigurace slouží pro uživatelský název, podle kterého uživatel danou konfiguraci rozpozná a může se na ni později přepnout. V Anjutě každá konfigurace odpovídá jedné složce sestavení a sadě konfiguračních voleb. Anjuta má připravených několik výchozích konfiguraci, ze kterých si zde můžete zvolit.

Pro ladění se doporučuje použít konfiguraci Ladění. Zkompiluje váš program s vypnutými veškerými optimalizacemi. Když jsou optimalizace zapnuté, některé proměnné a funkce jsou odstraněny a nemůžete je tak vidět v ladicím programu. Navíc se mění pořadí řádků ve zdrojovém kódu, takže byste pak při krokování posouvali i zpět.

Pole Složka sestavení slouží k výběru složky používané k sestavení projektu. Musí být pro každou konfiguraci jiná.

Když sestavujete projekt ve zdrojové složce (tj. když ponecháte pole Složka sestavení prázdné), nemůžete vytvořit novou konfiguraci. Jde o omezení Autotools. Musíte nejprve použít Sestavit Odstranit konfiguraci, čímž se ve zdrojové složce spustí `make distclean`.

Pole Volby příkazu configure umožňuje předat konfiguračnímu skriptu další přepínače.

Kliknutím na Spustit se spustí konfigurační skript. Všechny jeho výstupy se objeví v zobrazení zpráv přímo v aplikaci Anjuta. V případě, že skript projde bez chyb, zpřístupní se všechny další položky v nabídce Sestavit.

#### Položky nabídky

Operace sestavení v Ajutě spoléhá pouze na make, stejné jako v Autotools. Funguje to i u projektů, které nejsou založené na Autotools. Příkaz pro kompilaci pak pracuje jen se zdrojovými soubory v jazyce C, protože make má vestavěná pravidla pro jejich kompilaci. Zde je uvedeno, která položka nabídky aplikace Anjuta odpovídá kterému příkazu make.

Sestavit Zkompilovat

- make `aktuální_soubor`

Sestavit Sestavit

- cd `složka_aktuálního_souboru`; make

Sestavit Sestavit projekt

- cd `složka_projektu`; make

Sestavit Sestavit balíček TAR

- cd `složka_projektu`; make dist

Sestavit Nainstalovat

- cd `složka_aktuálního_souboru`; make install

Sestavit Nainstalovat projekt

- cd `složka_projektu`; make install

Sestavit Vyčistit

- cd `složka_aktuálního_souboru`; make clean

Sestavit Vyčistit projekt

- cd `složka_projektu`; make clean

Sestavit Odstranit konfiguraci

- cd `složka_projektu`; make distclean

Poslední položka nabídky Sestavit Vybrat konfiguraci, které nebyla výše popsána, umožňuje přepnout mezi různými konfiguracemi a také mezi různými složkami sestavení.

#### Volby

Pár běžných voleb sestavení najdete na stránce s předvolbami, ke které se dostanete pomocí Upravit Předvolby Autotools pro sestavení.

##### Předvolby sestavení

## Vytvoření projektu

Tato kapitola vysvětluje, jak vytvořit nový projekt. Obdobně jako v předchozí kapitole, začneme s Autotools a teprve pak se podíváme na Anjutu.

### Použití Autotools

V první kapitole jsme ve skutečnosti nepoužili nástroj Autotools. Při kompilaci ze zdrojových kódů není nutný. Ale všechny soubory v sestavovacím procesu se nepíšou ručně. Generují se ze šablon pomocí Autotools.

Autotools se ve skutečnosti skládají z několika nástrojů: `aclocal`, `autoconf`, `automake` a z dalších, které zde neuvidíme a které patří do dvou balíčků: Automake a Autoconf.

- Autoconf se používá ke generování konfiguračního skriptu ze šablony nazvané `configure.ac`. Konfigurační skript zkontroluje všechny vlastnosti hostitelského systému a vygeneruje soubor `Makefile` ze šablony `Makefile.in`.

- Automake se používá ke generování úplných šablon Makefile.in, které splňují standardy GNU, z velmi jednoduchých šablon Makefile.am.

#### Zpracování pomocí Autotools

Nyní se pojďme podívat na minimalistický příklad, abychom pochopili vztahy mezi jednotlivými soubory.

#### Psaní zdrojových kódů

1. Vytvořte prázdnou složku s názvem `tut_prog` a přepněte se do ní.

2. V této nové složce vytvořte nový soubor s názvem `main.c`, který bude obsahovat:

##### main.c:

    #include <stdio.h>

    int main()
    {
    	printf("Hello world!\n");
    	return 0;
    }

#### Spuštění Autoconf

1. Zapište následující do souboru nazvaného `configure.ac`:

##### minimální configure.ac:

    AC_INIT([Tutorial Program], 1.0)
    AM_INIT_AUTOMAKE
    AC_PROG_CC
    AC_CONFIG_FILES(Makefile)
    AC_OUTPUT

Šablona konfiguračního skriptu by se mohla jmenovat `configure.in`. Tento název se skutečně používal ve starší verzi Autoconf (před rokem 2001). Nicméně doporučujeme použít `configure.ac`, protože přípona `.in` je již používaná soubory zpracovávanými pomocí configure a generovanými pomocí Automake (`Makefile.in`) a pomocí autoheader (`config.h.in`).

AC_INIT, AM_INIT_AUTOMAKE, atd. jsou makra M4. M4 je software pro rozvíjení maker používaný Autotools. V zásadě o něm ani nepotřebujeme vědět. Když Autoconf zpracovává tento configure.in, makra se rozvíjí a nakonec dostaneme čistý dlouhý skript configure.

AC_INIT

- Jedná se o povinné první makro. Musíte mu zadat název projektu a jeho verzi.

AM_INIT_AUTOMAKE

- Inicializuje prostředí proměnných pro Automake. Je zapotřebí ve všech projektech používajících Automake.

AC_PROG_CC

- Určuje, který kompilátor jazyka C se má použít.

AC_CONFIG_FILES

- Vytvoří jednotlivé soubory zkopírováním příslušných šablonových souborů (s příponou .in) a nahrazením hodnot výstupních proměnných.

AC_OUTPUT

- Označuje konec šablony pro skript configure.

Používání některých maker se změnilo mezi jednotlivými verzemi Autoconf:

- Název balíčku býval definován jako argument AM_INIT_AUTOMAKE namísto AC_INIT.

- AC_OUTPUT přebíralo seznam generovaných souborů namísto použití přídavného makra AC_CONFIG_FILES.

Autoconf zná jen svá vlastní makra, ale čte i další v souboru nazvaném `aclocal.m4`. Tato makra se používají k rozšíření funkčnosti Autoconf. Patří k nim makra z Automake (začínající AM_) a další makra od třetích stran. Například, když vyvíjíte knihovnu foo, můžete chtít napsat makro AC_CHECK_FOR_FOO, aby vývojáři, kteří budou knihovnu používat, mohli pomocí Autoconf kontrolovat její přítomnost v systému.

aclocal prochází `configure.ac` a vytváří soubor `aclocal.m4`, který obsahuje makra použitá v `configure.ac`. aclocal je součástí balíčku Automake a standardně hledá v makrech Automake a v nějaké systémové cestě, typicky `/usr/share/aclocal`.

1. Spusťte `aclocal`. Vytvoří se tím v aktuální složce nový soubor s názvem `aclocal.m4`.

2. Spusťte `autoconf`. Vytvoří se tím nový konfigurační skript `configure`.

Ve skutečnosti se vám vytvoří ještě další složka s názvem `autom4te.cache`. Ta je pro interní účely Autoconf a nemusíte se jí zabývat.

#### Spuštění Automake

1. Do souboru s názvem `Makefile.am` zapište následující:

##### minimální Makefile.am:

    bin_PROGRAMS = tut_prog
    tut_prog_SOURCES = main.c

V Makefile.am jsou nejzákladnější data potřebná k sestavení projektu: cíl programu, nazvaný tut_prog, bude umístěn do složky $prefix/bin/ a k jeho sestavení potřebujeme main.c. Všimněte si, že není řečeno, jak bude sestaven. Automake si to zjistí. V tomto předchůdci Makefile není zmíněn ani kompilátor.

Makefile.am bude zpracován pomocí Automake a výsledkem bude Makefile.in. Ten už se hodně podobá skutečnému souboru makefile, ale obsahuje názvy proměnných, které budou při spuštění skriptu configure nahrazené, a výsledkem se stane skutečný makefile (nazvaný Makefile). Skript `configure` kupříkladu zapíše do výsledného souboru Makefile, který kompilátor se má použít (což je ten, který nalezlo makro AC_PROG_CC).

1. Spusťte příkaz `automake --add-missing --foreign`. Vytvoří nový soubor nazvaný, podle očekávání, `Makefile.in`. Navíc, díky přepínači `--add-missing` získáte několik odkazů na na skripty nutné pro sestavení projektu: `depcomp`, `install.sh` a `missing`. Druhý přepínač `--foreign` říká Automake, že se nechcete držet standardů GNU a nepotřebujete povinné dokumentační soubory: `INSTALL`, `NEWS`, `README`, `AUTHORS`, `ChangeLog` a `COPYING`. Zde jsme jej použili, abychom udrželi počet vytvořených souborů na minimu, ale jinak je dobré tyto soubory poskytovat a začít můžete klidně s prázdnými.

#### Sestavení projektu

1. Nyní spusťte nový konfigurační skript: `./configure`. Objeví se následující výstup a vytvoří se `Makefile` pro váš program.

       checking for a BSD-compatible install... /usr/bin/install -c
       checking whether build environment is sane... yes
       checking for a thread-safe mkdir -p... /bin/mkdir -p
       checking for gawk... gawk
       checking whether make sets $(MAKE)... yes
       checking for gcc... gcc
       checking for C compiler default output file name... a.out
       checking whether the C compiler works... yes
       checking whether we are cross compiling... no
       checking for suffix of executables...
       checking for suffix of object files... o
       checking whether we are using the GNU C compiler... yes
       checking whether gcc accepts -g... yes
       checking for gcc option to accept ISO C89... none needed
       checking for style of include used by make... GNU
       checking dependency style of gcc... gcc3
       configure: creating ./config.status
       config.status: creating Makefile
       config.status: executing depfiles commands

2. Nyní spusťte `make`, aby se váš program sestavil. Objeví se následující výstup a nový spustitelný soubor tut_prog.

       gcc -DPACKAGE_NAME=\"Tutorial\ Program\" -DPACKAGE_TARNAME=\"tutorial-program\"   \
               -DPACKAGE_VERSION=\"1.0\" -DPACKAGE_STRING=\"Tutorial\ Program\ 1.0\"     \
               -DPACKAGE_BUGREPORT=\"\" -DPACKAGE=\"tutorial-program\" -DVERSION=\"1.0\" \
               -I.     -g -O2 -MT main.o -MD -MP -MF .deps/main.Tpo -c -o main.o main.c
       main.c: In function ‘main’:
       main.c:5: warning: return type of ‘main’ is not ‘int’
       mv -f .deps/main.Tpo .deps/main.Po
       gcc  -g -O2   -o tut_prog main.o

3. Nyní, za předpokladu, že máte právo zápisu do `/usr/local/bin`, můžete spustit `make install`, aby se program nainstaloval. Pokud jej nemáte, musíte se nejprve přihlásit jako uživatel root nebo použít sudo a spustit `sudo make install`. Mělo by se objevit:

       make[1]: Vstupuje se do složky „/home/seb/Projects/Tutorial“
       test -z "/usr/local/bin" || /bin/mkdir -p "/usr/local/bin"
         /usr/bin/install -c 'tut_prog' '/usr/local/bin/tut_prog'
       make[1]: Pro „install-data-am“ nebude nic uděláno.
       make[1]: Opouští se složka „/home/seb/Projects/Tutorial“

   Jestliže je `/user/local/bin` součástí prohledávaných cest, můžete svůj program potom spustit odkudkoliv.

#### Promazání projektu

1. Program je nainstalovaný, takže složku sestavení můžete klidně promazat spuštěním `make clean`. Tím se odstraní všechny objektové soubory a program, ale ne už soubory Makefile.

       test -z "tut_prog" || rm -f tut_prog
       rm -f *.o

   Program nainstalovaný v `/user/local/bin` ale můžete samozřejmě nadále spouštět.

2. Pokud byste chtěli odstranit nainstalovaný program, spusťte `make uninstall`. Podobně jako u instalace, musíte mít práva zápisu do složky, nebo použít su nebo sudo.

       rm -f '/usr/local/bin/tut_prog'

#### Vygenerování projektu

Abyste pochopili, co přesně se děje, je nejlepší si v rámci této výuky spustit jeden po druhém `aclocal`, `automake` a `autoconf`. Při skutečné práci by to ale bylo poněkud únavné, nehledě na další nástroje, které mohou být zapotřebí, jako `autoheader`, `autopoint` nebo `libtoolize`. Po vytvoření projektu by se o přegenerování souboru `configure` a všech souborů `Makefile.in` měly postarat speciální soubory `Makefile` vygenerované aplikací configure. Každopádně tu zůstává prostor k vylepšování a na výzvu existují i dvě odpovědi:

autoreconf

- Jedná se o další nástroj z balíčku Autoconf, který spustí všechny skripty ve správném pořadí. Když chcete začít nový projekt, stačí spustit `autoreconf --install` a zavolají se všechny potřebné příkazy.

autogen.sh

- Jedná se o skript, který není součástí Autotools, ale dělá stejné věci. Se základním vývojářským balíčkem GNOME je šířen jeden takový, s názvem `gnome-autogen.sh`. Jiné projekty mohou mít napsaný svůj vlastní.

### Použití IDE Anjuta

Vytvoření projektu a IDE Anjuta vyžaduje jen pár kliknutí, ale pak si vytvořené soubory probereme.

#### Vytvoření nového projektu

1. Klikněte na Soubor Nový Projekt. Objeví se průvodce novým projektem.

2. Klikněte na Následující. Objeví se stránka pro výběr projektu:

   ##### Stránka pro výběr projektu

3. Vyberte Obecný (minimální) projekt na kartě C.

4. Klikněte na Následující.

   ##### Stránka se základními informacemi o projektu

   Změňte Název projektu na `tutprog`. Název by měl obsahovat jen písmena a číslice, případně podtržítko. Vyplňte zbývající pole.

5. Klikněte na Následující.

   ##### Stránka s volbami projektu

   Klikněte na Cíl a vytvořte pro svůj nový projekt novou složku nazvanou tutprog. V názvu složky se vyvarujte mezer a diakritiky. Všechny ostatní volby ponechejte na výchozích hodnotách, abychom dostali co nejmenší projekt.

6. Klikněte na Následující.

   ##### Stránka se souhrnným přehledem o projektu

   Jedná se o poslední stránku průvodce, na které si zkontrolujte, jestli je vše správně.

7. Klikněte na Použít. Anjuta vytvoří všechny potřebné soubory a složky a v okně zpráv uvidíte následující:

   ##### Zprávy o vytváření projektu

   Po té je zavolán skript autogen.sh a spuštěn konfigurační skript. Nakonec Anjuta otevře nový projekt. Jelikož hlavní zdrojový kód již obsahuje pár řádků a proběhla konfigurace, můžete projekt přímo sestavit.

#### Pohled do configure.ac

##### Nejzákladnější configure.ac v Anjutě:

    dnl Process this file with autoconf to produce a configure script.
    dnl Created by Anjuta application wizard.

    AC_INIT(tutprog, 0.1)

    AM_INIT_AUTOMAKE(AC_PACKAGE_NAME, AC_PACKAGE_VERSION)
    AC_CONFIG_HEADERS([config.h])

    AC_PROG_CC

    AC_OUTPUT([
    Makefile
    ])

Stále je to docela jednoduché s pár makry navíc. Pojďme se podívat na ty, co ještě neznáme:

dnl

- Nejedná se o makro, ale jen o značku začínající komentář v M4, což je jazyk použitý pro psaní `configure.ac`. Je to obdoba „#“ ve skriptech nebo „//“ v C++.

AM_INIT_AUTOMAKE

- Makro AC_INIT používá novou podobu s balíčkem a verzí, zatímco AM_INIT_AUTOMAKE se drží staré a v současnosti již není zapotřebí.

AC_CONFIG_HEADERS

- Říká nástroji Autoconf, aby předal všechny definice v souboru s názvem `config.h`, místo toho, aby použil několik přepínačů -Dxxxx na příkazové řádce (viz create-autotools-build). Když je jich hodně, je to jednodušší. Soubor s názvem `config.h.in` se vytvoří automaticky z `configure.ac` pomocí autoheader. Soubor `config.h` je pak vytvořen automaticky pomocí configure, podobně jako soubory makefile. Takže je to pro vývojáře bezbolestné.

AC_OUTPUT

- Jedná se o starou podobu AC_OUTPUT, ve které určujete všechny výstupní soubory, místo aby se použilo makro AC_CONFIG_FILES.

#### Pohled do Makefile.am

##### Nejzákladní Makefile.am v Anjutě:

    ## Process this file with automake to produce Makefile.in
    ## Created by Anjuta

    AM_CPPFLAGS = \
            -DPACKAGE_DATA_DIR=\""$(datadir)"\"

    AM_CFLAGS =\
             -Wall\
             -g

    bin_PROGRAMS = tutprog

    tutprog_SOURCES = \
            main.c

    tutprog_LDFLAGS =

    tutprog_LDADD =

Moc toho v `Makefile.am` není:

AM_CPPFLAGS

- Používá se k předání dodatečných přepínačů preprocesoru C. Zde definuje dodatečnou konstantu PACKAGE_DATA_DIR nastavenou pomocí configure.

AM_CFLAGS

- Definuje některé dodatečné přepínače pro kompilátor C: zapíná všechna varování a ladicí informace, které jsme již viděli na začátku tohoto výukového materiálu (viz build-gcc).

tutprog_LDFLAGS

- Přidává místo, do kterého můžete doplnit pro program tutprog dodatečné přepínače linkeru.

tutprog_LDADD

- Přidává místo, do kterého můžete doplnit pro program tutprog dodatečné knihovny.

## Přidání knihovny

Tato kapitola vysvětluje, jak přidat do projektu novou knihovnu. Než se podíváme na Anjutu, začneme s Autotools.

### Použití Autotools

Přidání nové knihovny do projektu založeného na Autotools může být více či méně snadné, záleží na tom, jak je knihovna zabalená. Abychom měli příklad, představte si, že chcete číst soubor XML pomocí libxml2 (viz domovská stránka knihovny na www.xmlsoft.org).

1. Otevřete starý projekt z tohoto výukového materiálu a nahraďte `main.c` následujícím:

   #### main.c používající libxml2:

       #include <libxml/parser.h>
       #include <stdio.h>

       int main()
       {
       	xmlDocPtr doc;
       	doc = xmlParseFile ("testfile.xml");

       	if (doc == NULL) {
       		printf ("Document not parsed successfully. \n");
       		return -1;
       	}
       	else {
       		printf ("Document parsed successfully.\n");
       		xmlFreeDoc(doc);
       		return 0;
       	}
       }

Naším cílem je nyní zkompilovat jej a aby správně fungoval. Za tímto účelem musíme říci GCC dvě věci: kde najít libxml/parser.h (tzn. dát GCC správnou cestu k hlavičkovým souborům) a s jakou knihovnu (tj. sdíleným objektem) by se měl náš projekt slinkovat. Je několik způsobů, jak to udělat, tak začneme tím nejjednodušším.

#### Pomocí pkg-config

pkg-config je nástroj, který se snaží poskytnout vývojářům jednotné rozhraní pro dotazování nainstalovaných knihoven na jejich verzi a všechny přepínače potřebné ke kompilaci a slinkování s nimi. Patří k němu i makro pro Autoconf, nazvané PKG_CHECK_MODULES, pomocí kterého se kontroluje přítomnost knihovny a nastavují všechny potřebné přepínače.

1. Přidejte následujíc řádek do `configure.ac`.

       PKG_CHECK_MODULES(XML, libxml-2.0 >= 2.4)

   Toto makro kontroluje přítomnost libxml2 ve verzi vyšší nebo rovné 2.4 a vytvoří dvě proměnné, XML_CFLAGS a XML_LIBS, které budou obsahovat přepínače pro kompilátor C, respektive linker. `XML` je uživatelem definovaný název. `libxml-2.0` je název knihovny. Pro vypsání všech nainstalovaných knihoven můžete spustit `pkg-config --list-all`.

2. Přidejte následujíc řádek do `Makefile.am`.

       tut_prog_CPPFLAGS = $(XML_CFLAGS)
       tut_prog_LDFLAGS= $(XML_LIBS)

   Pro kompilaci vašeho programu se použijí přepínače, které našel skript configure, když spustil makro PKG_CHECK_MODULES.

3. Toť vše. Můžete znovu spustit `make`.

       cd . && /bin/sh /home/seb2008.1/Projects/tutprog/missing --run aclocal-1.10
       cd . && /bin/sh /home/seb2008.1/Projects/tutprog/missing --run automake-1.10 --foreign
       cd . && /bin/sh /home/seb2008.1/Projects/tutprog/missing --run autoconf
       /bin/sh ./config.status --recheck
       running CONFIG_SHELL=/bin/sh /bin/sh ./configure  --no-create --no-recursion
       checking for a BSD-compatible install... /usr/bin/install -c
       checking whether build environment is sane... yes
       checking for a thread-safe mkdir -p... /bin/mkdir -p
       checking for gawk... gawk
       checking whether make sets $(MAKE)... yes
       checking whether to enable maintainer-specific portions of Makefiles... yes
       checking for style of include used by make... GNU
       checking for gcc... gcc
       checking for C compiler default output file name... a.out
       checking whether the C compiler works... yes
       checking whether we are cross compiling... no
       checking for suffix of executables...
       checking for suffix of object files... o
       checking whether we are using the GNU C compiler... yes
       checking whether gcc accepts -g... yes
       checking for gcc option to accept ISO C89... none needed
       checking dependency style of gcc... gcc3
       checking for library containing strerror... none required
       checking for gcc... (cached) gcc
       checking whether we are using the GNU C compiler... (cached) yes
       checking whether gcc accepts -g... (cached) yes
       checking for gcc option to accept ISO C89... (cached) none needed
       checking dependency style of gcc... (cached) gcc3
       checking for gcc... (cached) gcc
       checking whether we are using the GNU C compiler... (cached) yes
       checking whether gcc accepts -g... (cached) yes
       checking for gcc option to accept ISO C89... (cached) none needed
       checking dependency style of gcc... (cached) gcc3
       checking how to run the C preprocessor... gcc -E
       checking for grep that handles long lines and -e... /bin/grep
       checking for egrep... /bin/grep -E
       checking for ANSI C header files... yes
       checking for pkg-config... /usr/bin/pkg-config
       checking pkg-config is at least version 0.9.0... yes
       checking for XML... yes
       configure: creating ./config.status
        /bin/sh ./config.status
       config.status: creating Makefile
       config.status: creating config.h
       config.status: config.h is unchanged
       config.status: executing depfiles commands
       cd . && /bin/sh /home/seb2008.1/Projects/tutprog/missing --run autoheader
       rm -f stamp-h1
       touch config.h.in
       cd . && /bin/sh ./config.status config.h
       config.status: creating config.h
       config.status: config.h is unchanged
       make  all-am
       make[1]: Entering directory `/home/seb/Projects/tutprog'
       gcc -DHAVE_CONFIG_H -I.  -DPACKAGE_DATA_DIR=\""/usr/local/share"\" -I/usr/include/libxml2  \
               -Wall -g -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 -Wall -g -g -O2   -o tutprog main.o -lxml2
       make[1]: Leaving directory `/home/seb/Projects/tutprog'

   Není potřeba znovu spouštět Autoconf nebo Automake, protože vygenerovaný Makefile již obsahuje nějaká pravidla, která to udělají.

Když se instaluje knihovna podporující pkg-config, zkopíruje se spolu s ní do systémové složky, obvykle `/usr/lib/pkgconfig`, malý textový soubor s příponou .pc. Při instalaci ze zdrojových kódů je předvolenou složkou `/usr/local/lib/pkgconfig`. Můžete požádat pkg-config, aby hledal i v této složce, nastavením proměnné prostředí `PKG_CONFIG_PATH=/usr/local/lib/pkgconfig`.

#### S nějakým makrem z Autoconf

Pokud knihovna nepodporuje pkg-config, tj. neobjevuje se ve výpise vráceném příkazem `pkg-config --list-all`, potřebujete makro z Autoconf:

- Podívejte se, jestli autor knihovny šíří i makro M4, a pokud ano, použijte jej. Jedná se o textový soubor nazvaný stejně jako knihovna, akorát s příponou .m4, a často je nainstalován v `/usr/share/aclocal`.

- Pokud se jedná o některou ze základních knihoven, může se kontrolovat pomocí standardních maker Autoconf (viz seznam zde).

- Možná makro M4, které potřebujete, již někdo jiný naprogramoval. Podívejte se na příspěvky zde.

- Pokud všechno selže, zanořte se do M4 hlouběji, vytvořte své vlastní makro a přispějte jím autorovi knihovny!

Pokud makro máte, můžete jej nakopírovat do `/usr/share/aclocal`, aby jej aclocal našel. Pak už se jen stačí podívat do souboru s makrem, jak jej použít. libxml2 instaluje makro s názvem AM_PATH_XML2, které najdete v `/usr/share/aclocal/libxml.m4`.

1. Přidejte následujíc řádek do `configure.ac`.

       AM_PATH_XML2(2.4.0)

   Tohle makro bude kontrolovat přítomnost knihovny s verzí vyšší nebo rovnou 2.4 a vytvoří dvě proměnné, XML_CPPFLAGS and XML_LIBS, které budou obsahovat přepínače pro kompilátor C, respektive pro linker. Tyhle informace získáte z komentářů v souboru s makrem.

2. Přidejte následujíc řádek do `Makefile.am`.

       tut_prog_CPPFLAGS = $(XML_CPPFLAGS)
       tut_prog_LDFLAGS= $(XML_LIBS)

   Pro kompilaci programu se použijí přepínače nalezené skriptem configure. Všimněte si, že makro pomocí pkg-config definovalo XML_CPPFLAGS, a ne XML_CFLAGS. Použití CPPFLAGS dává větší smysl, protože tyto přepínače jsou používány preprocesorem C, nejčastěji jen k nastavení cesty k hlavičkovým souborům.

3. Toť vše. Můžete znovu spustit `make`. Vygenerovaný `Makefile` je téměř stejný.

#### Pomocí pevně určených cest ke knihovnám

Jde o přístup, který by člověka přirozeně napadl – přímo GCC předat to, co potřebuje. Například bývá v linuxových systémech `libxml/parser.h` uložený v `/usr/include/libxml2` a sdílený objekt „libxml.so“ v `/usr/lib`. (Budeme předpokládat, že to máte stejně.)

1. Přidejte následujíc řádek do `Makefile.am`.

       tut_prog_CPPFLAGS = -I /usr/include/libxml2
       tut_prog_LDFLAGS= -lxml2

   Není potřeba měnit `configure.ac`, protože nic nekontrolujete a prostě předpokládáte, že všechny hostitelské systémy budou mít správné knihovny na stejném místě, jako vy.

2. Můžete spustit `make` a pokud to máte v systému stejně, jak bylo zmíněno, mělo by to fungovat.

        cd . && /bin/sh /home/seb2008.1/Projects/tutprog/missing --run automake-1.10 --foreign  Makefile
        cd . && /bin/sh ./config.status Makefile depfiles
       config.status: creating Makefile
       config.status: executing depfiles commands
       make  all-am
       make[1]: Entering directory `/home/seb/Projects/tutprog'
       gcc -DHAVE_CONFIG_H -I.  -DPACKAGE_DATA_DIR=\""/usr/local/share"\" -I /usr/include/libxml2  \
           -Wall -g -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 -Wall -g -g -O2   -o tutprog main.o -lxml2
       make[1]: Leaving directory `/home/seb/Projects/tutprog'

Tohle jsme si zde popsali, abychom viděli, jak jednoduše se to dá udělat s pomocí Autotools. Tento přístup má ale několik nevýhod:

- Není to univerzálně přenositelné na jiné verze linuxu: v jiné distribuci je třeba cesta k hlavičkovým souborům jiná.

- Když bude mít příští verze knihovny libxml jiné cesty nebo jiné závislosti na knihovnách, budeme muset projekt aktualizovat.

- Netestujeme, jestli má systém balíčkáře/uživatele knihovnu.

- Nemůžeme zkontrolovat, kterou verzi libxml2 používáme.

### Použití IDE Anjuta

Při použití Anjuty jde přidat knihovnu podporující pkg-config téměř bez použití klávesnice.

#### Pomocí pkg-config

1. Otevřete soubor `main.c` z projektu, který jsem v Anjutě vytvořili v předchozí kapitole. Nahraďte jeho obsah následujícím textem:

   ##### main.c používající libxml2:

       #include <libxml/parser.h>
       #include <stdio.h>

       int main()
       {
       	xmlDocPtr doc;
       	doc = xmlParseFile ("testfile.xml");

       	if (doc == NULL) {
       		printf ("Document not parsed successfully. \n");
       		return -1;
       	}
       	else {
       		printf ("Document parsed successfully.\n");
       		xmlFreeDoc(doc);
       		return 0;
       	}
       }

2. Vyberte Projekt Vlastnosti Balíčky a objeví se dialogové okno s vlastnostmi balíčku.

3. Klikněte na tlačítko Přidat modul a do sloupce Modul/balíček zadejte název, např. „XML“.

4. Klikněte na tlačítko Přidat balíček, které by teď mělo být přístupné. Objeví se dialogové okno, ve kterém můžete vybrat knihovnu, kterou chcete použít. V tomto dialogovém okně jsou vypsané všechny knihovny podporující pkg-config. Vyberte `libxml-2.0`. Pak klikněte na tlačítko Přidat.

5. Dialogové okno s vlastnostmi balíčku by mělo vypadat nějak následovně:

   ##### Dialogové okno s vlastnosti projektového balíčku

   Modul XML obsahuje knihovnu s názvem libxml-2.0. Můžete určit minimální požadovanou verzi kliknutím ve sloupci verze a napsáním `>= 2.4`. Tím se zapíší potřebné řádky do souboru `configure.ac`.

6. Zavřete dialogové okno a vyberte Projekt Aktualizovat. Nemělo by to být potřeba, ale u aktuální verze Anjuty je to bohužel nutné. Bylo to již nahlášeno jako chyba (#541694) a bude to opraveno.

7. V zobrazení projektu vyberte cíl projektu tutprog a klikněte na něj pravým tlačítkem, aby se objevila kontextová nabídka, ve které vyberte Vlastnosti. Objeví se dialogové okno s vlastnostmi cíle.

8. V dialogovém okně jsou uvedené všechny moduly dostupné ve vašem projektu, takže stačí jednoduše zaškrtnout modul XML. Tím se příslušně změní soubor `Makefile.am`, aby používal správnou knihovnu.

   ##### Dialogové okno s vlastnostmi cíle

9. Klikněte na Zavřít a tím je vše hotovo. Můžete vybrat Sestavit Sestavit, aby se váš projekt znovu sestavil.

#### Bez pkg-config

Anjuta nemá skutečnou podporu pro knihovny, které nepoužívají pkg-config. Abyste přidali potřebná makra, musíte upravit `configure.ac` přímo. Pro předání přepínačů do jednotlivých cílů můžete použít tlačítko Pokročilé v dialogovém okně s vlastnostmi cíle.

## Odkazy

Zde jsou odkazy na dokumentaci, která se zabývá Autotools obecně a konkrétně pak nástroji Autoconf a Automake.

V anličtině

- - Pro začátek se můžete podívat do referenčních příruček k Autoconf, Automake, Libtool, make a M4.

  - V Autobook je podrobně rozebráno, jak fungují Autotools.

  - Mezi různými vývojářskými nástroji GNU, o kterých jsme mluvili zde, jsou Autoconf a Automake.

  - Zde a zde jsou dva základní výukové materiály k Autotools.

V češtině

- Na server ROOT vyšel seriál o nástrojích GNU s kapitolami Autoconf a Automake.

Ve slovenštině

- Zde je jeden kratší článek o Automake.

Tento výukový materiál používá Autoconf 2.61 (z listopadu 2006) a Automake 1.10.1 (leden 2008). Některé z těchto dokumentů používají starší verze a syntax se mohla trochu změnit. Starší syntax obvykle stále funguje a používá se ve starších projektech. Je dobré ji znát, ale není dobrý nápad ji používat v nových projektech.