FreshSourcing. Čerstvé nápady. Kreatívne riešenia.

» Domov » Auto Tools » 9. časť

9. časť: Viacadresárové projekty

Zdokonalíme si program "Hello, world!", ktorý sme v minulej časti začali tvoriť, a pozrieme sa na to, ako používať viacero adresárov v jednom projekte.

Podadresáre

Podadresáre slúžia na sprehľadnenie a usporiadanie súborov. My budeme najčastejšie oddeľovať zdrojové súbory napríklad od dokumentácie, testovacích programov (hlavne pri knižniciach) a pomocných skriptov. Skúste si všimnúť pri inštalácii nejakého programu, ako vyzerá jeho adresárová štruktúra. Tie najmenšie programy môžu vyzerať ako náš príklad z minulej časti - všetko je v jednom (hlavnom) adresári. Má to aj svoje výhody (nemá zmysel dávať jediný zdrojový súbor, z ktorého program pozostáva, do samostatného adresára), ale aj nevýhody (obrovský neporiadok pri programoch s väčším počtom súborov).

Štruktúra

Najčastejšie si môžete všimnúť adresár src. Ten obsahuje zdrojové súbory programu a teda mohla by ho mať každá distribúcia (balíček so zdrojákmi) ľubovoľného programu. Trochu menej častý je adresár doc, obsahujúci dokumentáciu k programu (knižnici). Bohužiaľ doteraz neexistuje nijaký štandardný formát, v ktorom by mala byť dokumentácia dodávaná, a tak sa stáva, že v tomto adresári nájdete kadečo. Na detailný prehľad formátov sa pozrieme niekedy inokedy, teraz si ich iba vymenujeme a stručne popíšeme:

TXT (plain text - čistý text): Najstarší formát, pri ktorom máte zároveň záruku, že ho prečíta každý.

HTML (hyper-text markup language): Môžete ho použiť, ak chcete užívateľom dožičiť trošku vyšší komfort pri študovaní dokumentácie. Prečítať by ho mal byť schopný tiež zrejme každý.

SGML (structured generalised markup language) alebo LinuxDoc: Na prvý pohľad sa súbory podobajú na HTML, keby ste sa však pokúsili prezrieť si ich len tak priamo v prehliadači, asi by vás ich výstup nenadchol. Súbory SGML majú totiž špeciálnu štruktúru a odlišné tagy (značky) ako tie v HTML. Pomocou programov na spracovanie týchto súborov z nich môžete vytvoriť rôzne iné súbory, konkrétne spomínané HTML, čistý text, RTF (rich text format - otvoríte ho napríklad aj vo Worde), LaTeX (na profesionálnu sadzbu a následnú tlač), PDF, info (poznáte rovnomenný unixový program na čítanie dokumentácie?) a mnoho iných. Pri spracovaní týchto súborov sa automaticky môže vygenerovať aj obsah, index, hypertextové odkazy (ak to zvolený výstupný formát dovoľuje - napríklad HTML alebo PDF), hlavičky a päty strán a mnoho iných zaujímavých a užitočných vecí. Na prácu s týmto formátom si však musíte nainštalovať sgml-tools, súbor programov na spracovanie SGML súborov. Aj keď vo väčšine novších distribúcií sú tieto nástroje obsiahnuté, môže byť dobré k vášmu programu pribaliť aj vygenerovanú dokumentáciu v nejakom čitateľnom formáte, nie iba v SGML (napríklad pribalíte aj HTML ekvivalent). Takisto je dobrým zvykom do Makefile, ktorý je v adresári s dokumentáciou, pridať aj správne riadky, ktorými si cieľový užívateľ môže sám vygenerovať taký dokument v takom formáte, aký mu najviac vyhovuje. O tom, ako to spraviť, si povieme neskôr.

TeX, LaTeX: Ako som už spomenul, môžete ho použiť na profesionálnu tlač - výstupom je PostScript, DVI alebo PDF (Portable Document Format od Adobe). Ak by ste sa však rozhodli pre tento formát, skúste tak, ako v predchádzajúcom prípade, do Makefile pridať pravidlá na vytvorenie spomínaných výstupných súborov (ps, dvi, pdf), alebo rovno pribaliť aj pdf.

Info: Akiste poznáte program na čítanie dokumentácie info. Mnoho zložitejších programov má dokumentáciu práve v tomto formáte (jedná sa hlavne o programy z projektu GNU). Skúste napríklad spustíť info gcc a môžete si prečítať niečo o prekladači jazyka C. Program info umožňuje aj celkom pohodlnú navigáciu v týchto súboroch - stránky môžu obsahovať menu, z ktorého sa môžete dostať na iné podstránky. Použiť môžete aj poznámky pod čiarou, odkazy (niečo ako hypertext) a mnoho iných zaujímavostí.

Texinfo: Tento formát má niečo z každého z predchádzajúcich troch formátov - jeho príkazy či značky vyzerajú ako (La)TeX, sám o sebe je nepoužiteľný a umožňuje výstup rôznych formátov (ako SGML) a umožňuje navigáciu ako Info. Ako výstupný formát môžete použiť prakticky všetko z už spomenutého - info, html, plain text, TeX, pdf a mnoho iných. O pridaní pravidiel do Makefile platí to, čo sme si povedali pri SGML.

Man: Tento formát sa od ostatných (okrem info) líši aj tým, že sa inštaluje do systému. Potom stačí spustiť man x.y.z a už môžete čítať. O tom, ako pridať do Makefile pravidlá pre inštaláciu (aby sa nainštaloval pri spustení make install), si povieme neskôr.

Prešli sme si teda najpoužívanejšie formáty dokumentácie programov. Dokumentácia sa, ako sme si už povedali, nachádza v adresári doc. Existujú však aj ďalšie adresáre. Napríklad v adresári test sa často nachádzajú rôzne testy, ktoré majú za cieľ vyskúšať jednotlivé vlastnosti programu alebo knižnice. Názvy ostatných adresárov zväčša závisia na autorovi - ani tu neexistuje nijaký štandard, ktorý by uznávala väčšina tvorcov. Na druhej strane mnoho programov si vystačí s dvoma podadresármi - src a doc.

Ako na to

Základom je, aby v každom podadresári existoval Makefile.am. Druhá vec je, aby všetky zainteresované programy a súbory o vašom podadresári vedeli: configure.in, ktorý je iba v hlavnom adresári, a Makefile.am - tak v hlavnom adresári, ako aj v každom podadresári, ktorý obsahuje ďalšie vnorené podadresáre. V súbore configure.in zmeníme posledný riadok - do zátvoriek umiestnime medzerami oddelený zoznam všetkých generovaných súborov Makefile (s relatívnou cestou vzhľadom k hlavnému adresáru projektu). Napríklad ak máme spolu tri súbory, ktoré chceme vygenerovať, napíšeme:

AC_OUTPUT(Makefile doc/Makefile src/Makefile)

Súbory sa budú generovať v takom poradí, v akom ich uvedieme v zátvorkách. Poradie kompilácie to vôbec neovplyvní. Samozrejme, zmena v configure.in nestačí. Najprv musíme do každého vnoreného podadresára vytvoriť jeden Makefile.am a okrem toho - v každom Makefile.am, ktorý sa nachádza v adresári, ktorý obsahuje aj ďalšie vnorené podadresáre, musíme doplniť riadok podobný tomuto:

SUBDIRS = . doc src

Premenná SUBDIRS obsahuje zoznam všetkých podadresárov, ktoré má program make spracovať (skompilovať alebo zabaliť do balíčka, a pod.). Pozor - záleží na poradí! Ak by ste napríklad pri nejakej knižnice, ktorá by v distribúcii mala aj nejaké tie self-testy, skúsili toto:

SUBDIRS = . test src

asi by ste veľmi nepochodili, pretože testy by nemali čo ostestovať - knižnica by v čase testovania ešte nebola skompilovaná!

Hello, world! 1.1

Znova sa pustíme do praktickej časti - vylepšíme si program uvedený v minulej časti a využijeme nové znalosti. Tu je listing súborov, ktoré boli súčasťou nášho projektu a nachádzali sa všetky v hlavnom adresári:

Makefile.am
Makefile.in
aclocal.m4
bootstrap
configure
configure.in
hello.c
hello.h
install-sh
main.c
missing
mkinstalldirs

Význam jednotlivých súborov sme si opísali v minulej časti. Teraz však dôjde k veľkému sťahovaniu súborov... Takže: vytvoríme podadresáre doc a src. Do druhého podadresára presunieme súbory:

hello.c
hello.h
main.c

Zároveň tam vytvoríme Makefile.am s nasledujúcim obsahom:

## Process this file with automake to produce Makefile.in

bin_PROGRAMS = hello
hello_SOURCES = hello.c main.c
noinst_HEADERS = hello.h

Skúste si ho porovnať so súborom Makefile.am z predchádzajúceho čísla - vynechali sme tieto dva riadky:

AUTOMAKE_OPTIONS = foreign
EXTRA_DIST = bootstrap

Prečo? Pretože prvý riadok by mal byť iba v súbore v hlavnom adresári. A druhý riadok zase stratil zmysel, pretože bootstrap sa v našom podadresári nenachádza (je iba v hlavnom podadresári). Teraz sa pozrime na podadresár doc. Ten by mal obsahovať dokumentáciu, ale keďže náš program je naozaj veľmi jednoduchý, vytvoríme zatiaľ iba prázdny súbor, napríklad hello.html. Samozrejme, aj tento podadresár potrebuje Makefile.am - tu je:

## Process this file with automake to produce Makefile.in

EXTRA_DIST = hello.html

Ak by sme mali viacero súborov (napríklad ďalšie html súbory), jednoducho ich pridáme na koniec premennej EXTRA_DIST (názvy súborov odďeľujeme medzerami). Neskôr si ukážeme, ako pridať pravidlá pre generovanie rôznych výstupných súborov napríklad zo spomínaných súborov vo formáte SGML, TeX, Texinfo a iných. Vráťme sa však do nášho hlavného adresára. V ňom sa budú odteraz nachádzať iba súbory potrebné pre programy z našej skupiny auto tools, ako aj rôzne "štandardné" súbory, ktoré by mali byť v každom slušnom balíku - README, NEWS, ChangeLog a podobné. Tie si však pridáme až v budúcej časti. Dnes sa ešte pozrieme na súbory configure.in a Makefile.am v hlavnom adresári. Prvý z nich bude vyzerať takto:

dnl Process this file with autoconf to produce a configure script.

AC_INIT(src/main.c)
AM_INIT_AUTOMAKE(hello, 1.1)
AC_PREFIX_DEFAULT(/usr/local)
AC_PROG_CC
AC_OUTPUT(Makefile doc/Makefile src/Makefile)

Okrem tretieho riadku sme si už vysvetlili všetko. Tento riadok nastavuje, kde sa má program nainštalovať pri zadaní príkazu make install. Samozrejme, každý užívateľ si to môže zmeniť pri spustení programu configure s parametrom --prefix=... a takto ho nainštalovať do prakticky ľubovoľného adresára. Napríklad binárne súbory (náš spustiteľný súbor src/hello) sa nainštalujú do prefix/bin (v štandardnom prípade /usr/local/bin). Samozrejme okrem prefixu sa dajú meniť aj konkrétne adresáre (pre binárky, pre hlavičkové súbory a pod.), skúste si preštudovať ./configure --help. Posledný riadok sme od minulej časti takisto pridali, avšak už sme si ho vysvetlili predtým. Okrem toho nastala ešte malá kozmetická úprava - v druhom riadku sme zvýšili verziu z 1.0 na 1.1.

Nakonic sa pozrieme na Makefile.am v hlavnom adresári:

## Process this file with automake to produce Makefile.in

SUBDIRS = . doc src

To by bolo všetko, čo potrebujeme, aby náš projekt mohol obsahovať viacero podadresárov s rôznymi typmi súborov. Pri zmene configure.in je potrebné spustiť náš skript bootstrap, ktorý sa (okrem iného) postará aj o spustenie programu autoconf (práve on má na starosti vytvoriť configure skript zo súboru configure.in). Pri zmenách v súboroch Makefiel.am sa o všetko postará samotný program make, ktorý si vlastne sám svoje súbory Makefile vytvára.

config.h

Na koniec tejto časti som si nechal súbor config.h Tento súbor je jeden z najdôležitejších, pretože spolu s configure (je vygenerovaný pri jeho spustení) sa stará o jednu vec, pre ktorú vlastne celé auto tools vznikli - je ňou potrabilita (prenositeľnosť). Je to normálny hlavičkový súbor, ktorý obsahuje #define makrá. Tento súbor sa vygeneruje pri spustení configure na konci celého procesu (všimnite si výstup ./configure) a obsahuje informácie o tom, čo na danom počítači nainštalované je a čo zase nie je. Tento súbor môžete vkladat pomocou #include ako každý iný hlavičkový súbor, najčastejšie takto:

!-#ifdef HAVE_CONFIG_H
#include
#endif

Tento text vložíte niekde na začiatok zdrojového súboru medzi ostatné vkladané súbory. Ak používame tento súbor, trošku sa zmenia príkazy kompilácie, ktoré sa spustia po zadaní make: namiesto parametrov prekladača -DPACKAGE="hello" -DVERSION="1.1", ktoré sú obdobou #define makier, pri preklade sa použije parameter -DHAVE_CONVIG_H. Ten zabezpečí, aby sa vykonalo podmienené #include (tie tri riadky vyššie). Aby sa však súbor config.h aj naozaj vytvoril, musíme zmeniť jednak configure.in, ale aj bootstrap. Do prvého pridáme jeden, riadok, takže bude nakoniec vyzerať takto:

dnl Process this file with autoconf to produce a configure script.

AC_INIT(src/main.c)
AM_INIT_AUTOMAKE(hello, 1.1)
AM_CONFIG_HEADER(config.h)
AC_PREFIX_DEFAULT(/usr/local)
AC_PROG_CC
AC_OUTPUT(Makefile doc/Makefile src/Makefile)

Pridali sme tretí riadok s názvom súboru config.h. Všimnite si, že je to makro pre Automake (AM_ na začiatku názvu makra). Súbor config.h sa, ako sme si už povedali, vytvára na konci behu programu configure. Nevytvára ho však "len tak", ako základ si berie súbor config.h.in. Tento súbor tiež nemusíte písať ručne, pomôže vám autoheader, ktorý jednoducho pridáte do bootstrap-u, ktorý bude potom vyzerať takto:

aclocal && \
autoheader && \
automake --add-missing --copy && \
autoconf

Po spustení autoheader-u sa preskenuje configure.in a vytvorí sa config.h.in. Pri sputení configure sa skontroluje počítač, jeho nainštalované programy a konfigurácia. Ak to vyhovuje vášmu programu, vytvoria sa súbory Makefile (zo súborov Makefile.in) a config.h (zo súboru config.h.in). Ak je váš program závislý na konkrétnej knižnici a configure ju nenájde, tak sa skončí s chybovým hlásením. Je však aj iná cesta, založená práve na config.h - ak sa nájde podobná knižnica, alebo knižnica s trošku odlišným API apod., configure to dokáže zistiť a vytvoriť config.h s potrebnými #define makrami. Vo svojich zdrojákoch tento súbor vložíte a program napíšete tak, aby sa choval inak v závislosti od používanej knižnice. Napríklad, ak nájde nejakú staršiu verziu požadovanej knižnice, podľa tých definícií to dokážete zistiť a potom obmedziť niektoré vlastnosti vášho programu. Ak by tá knižnica bola naozaj veľmi stará a vám by nepostačovala, tak to jednoducho oznámite už prostredníctvom configure. Ako to spraviť? To si ukážeme až o niekoľko častí ďalej.

Tu je listing upravených zdrojových súborov tak, aby pracovali správne s config.h:

hello.h:

#include

#ifdef HAVE_CONFIG_H
#include
#endif

void hello(char* name);
hello.c:

void hello(char* name)
{
printf("hello, %s\n", name);
}
main.c:

#include "hello.h"

int main(int argc, char* argv[])
{
if (argc < 2) {
printf("Usage: %s \"text\"\n", argv[0]);
return 1;
}

hello(argv[1]);

return 0;
}



Oto Komiňák


Článok bol uverejnený v magazíne PC Revue 10/2002.