Řízení překladu (make a soubor Makefile): Porovnání verzí

Z Milan Kerslager
Přejít na: navigace, hledání
m (Závislosti: fix)
(Další cíle příkazu make: zjednodušení)
Řádka 56: Řádka 56:
  
 
=== Další cíle příkazu make ===
 
=== Další cíle příkazu make ===
Cíle jsou v souboru <code>Makefile</code> pravidla (návěští), která lze provést tak, že jejich název přidáme jako parametr příkazu <code>make</code>. Následující soubor <code>Makefile</code> definuje pravidla ''help'' a ''clean'':
+
Cíle jsou v souboru <code>Makefile</code> pravidla (návěští), která lze provést tak, že jejich název přidáme jako parametr příkazu <code>make</code>. Následující soubor <code>Makefile</code> definuje pravidla ''ahoj'' a ''clean'':
  
help:
 
        @echo "Program $(NAZEV) verze $(VERZE)"
 
        @echo "Pouziti: make prikaz"
 
        @echo "prikaz:  help  - napoveda"
 
        @echo "        ahoj  - prelozit program"
 
        @echo "        clean - smazat binárku"
 
 
 
  ahoj: ahoj.c
 
  ahoj: ahoj.c
 
         gcc -Wall -o ahoj ahoj.c
 
         gcc -Wall -o ahoj ahoj.c
 
   
 
   
 
  clean:
 
  clean:
         rm -f ahoj
+
         @rm -fv ahoj
  
Zadáme-li příkaz <code>make</code> bez parametru, provede se implicitní pravidlo (první pravidlo v souboru), což je ''help''. Pro vyvolání dalších pravidel je potřeba, aby bylo pravidlo zadáno příkazu <code>make</code> jako parametr. Zavináč před příkazy <code>echo</code> způsobí, že se prováděný příkaz nebude vypisovat (tj. nebude vidět řádek s příkazem) a bude tedy vypsán pouze výstup tohoto příkazu.
+
Zadáme-li příkaz <code>make</code> bez parametru, provede se implicitní pravidlo (první pravidlo v souboru), což je zde pravidlo ''ahoj''. Pro vyvolání dalších pravidel, které jsou v souboru uvedeny, je potřeba, aby bylo pravidlo zadáno příkazu <code>make</code> jako parametr. Zavináč před příkazy <code>echo</code> způsobí, že se prováděný příkaz nebude vypisovat (tj. nebude vidět řádek s příkazem) a bude tedy vypsán pouze výstup tohoto příkazu.
  
 
Vyzkoušejte a porovnejte výstup následujících příkazů:
 
Vyzkoušejte a porovnejte výstup následujících příkazů:
  
 
  make
 
  make
  make help
+
  make clean
 
  make ahoj
 
  make ahoj
make clean
 
  
První příkaz provede implicitní pravidlo, takže je vypsána nápověda, což provede též druhý řádek. Třetí řádek způsobí překlad programu. Čtvrtý řádek smaže přeložený soubor, takže po novém vyvolání překladu dojde k novému překladu. Pravidlo ''clean'' smaže vytvořený binární soubor. Takové pravidlo zpravidla maže všechny soubory, které lze znovu získat ze zdrojových souborů, které jsou ponechány.
+
První příkaz provede implicitní pravidlo, takže je spuštěn překlad programu. Druhý řádek s vyvoláním pravidla ''clean'' smaže přeložený soubor, takže po novém vyvolání překladu voláním pravidla ''ahoj'' dojde k novému překladu (pravidlo s názvem ''clean'' obvykle maže vše, co lze ze zdrojových kódů znovu snadno získat).
  
 
=== Použití maker ===
 
=== Použití maker ===

Verze z 25. 2. 2014, 07:15

Nástroj make umožňuje pomocí předisů provádět jednoduše podmíněnou kompilaci. Předpisy se obvykle umisťují do souboru Makefile.

Ruční překlad programu

Mějme jednoduchý program v souboru ahoj.c:

#include <stdio.h>

void main()
{
  printf("Ahoj svete!\n");
}

Kompilaci provedeme příkazem:

gcc -Wall -o ahoj ahoj.c

Přeložený program můžeme spustit:

./ahoj

Soubor Makefile

Automatický překlad pak může obstarat níže uvedený jednoduchý soubor Makefile<code>. Tento soubor <code>Makefile<code> obsahuje pravidlo s názvem all (název pravidla začíná v prvním sloupci a je ukončen znakem dvojtečka). Protože je v souboru uvedeno toto pravidlo jako první, je tzv. implicitním pravidlem. Při přepisování souboru je důležité dát pozor na to, že výkonné řádky MUSÍ začínat znakem tabelátor (tj. tabelátor je na začátku řádku s příkazem <code>gcc). Například v editoru mcedit je nutné stisknout na začátku řádku dvakrát klávesu tabelátoru, aby byl do textu skutečný tabelátor vložen (editor mcedit ho pro zvýraznění obarví červeně). V editoru vim (i jiných) však vše funguje dle očekávání. Následuje příklad obsahu souboru Makefile<code>:

all:
        gcc -Wall -o ahoj ahoj.c

Po vytvoření souboru spusťte ve stejném adresáři příkaz <code>make. Pokud není příkazu make předán žádný parametr, dojde k vykonání implicitního pravidla (zde pravidlo all). Zároveň příkaz make vypisuje příkazy, které provádí (tučně je zvýrazněn vstup uživatele):

$ make
gcc -Wall -o ahoj ahoj.c

Pomocí příkazu ls -l zkontrolujte, zda vnikl spustitelný soubor (zde s názvem ahoj) a spusťte ho (tučně je zvýrazněn vstup uživatele):

$ date
Út bře 29 13:18:31 CEST 2011
$ ls -l
celkem 28
-rwxrwxr-x 1 kerslage kerslage 6851 bře 29 13:17 ahoj
-rw-rw-r-- 1 kerslage kerslage  172 bře 29 13:09 ahoj.c
-rw-rw-r-- 1 kerslage kerslage   52 bře 29 13:16 Makefile
$ ./ahoj
Ahoj svete!
$

Závislosti

Není nutné provádět dokola překlad souboru, který již byl jednou přeložen. Příkaz make proto umí porovnávat časy poslední změny v souborech. Pokud je zdrojový kód starší (byl naposledy změněn dříve), než soubor s přeloženým programem (tzv. binárka), může se příkaz make oprávněně domnívat, že překlad je zbytečný, protože musí mít stejný výsledek (vstupující zdrojový kód se od posledního překladu nezměnil). Proto jsou podporovány tak zvané závislosti, podle kterých může příkaz make rozhodnout, zda je překlad podle daného pravidla nutný. Samozřejmě musí být všechny závislosti správně nadeklarovány.

Závislosti se zapisují za dvojtečkou, která ukončuje název pravidla. Protože ve výše uvedeném příkladu žádná pravidla nebyla uvedena, překlad proběhl vždy. V následujícím souboru Makefile bude doplněno pravidlo o závislost na zdrojovém kódu ahoj.c. Příkaz make bude předpokládat, že výsledný přeložený soubor bude stejného jména, jako TODO.

V tomto případě se posuzuje, zda soubor ahoj je novější, než soubor ahoj.c.

Zavoláme-li příkaz make (bez parametru), dojde k přeložení programu podle implicitního pravidla (zde prvního uvedeného, tj. podle pravidla ahoj). Zavoláme-li jej znovu, oznámí nám, že překlad není nutný („“). Důvodem je fakt, že soubor ahoj.c je staší, než soubor ahoj (zdrojový text je starší, než přeložený program). Budeme-li editovat soubor ahoj.c, bude čas jeho poslední změny novější, než čas poslední změny přeloženého programu (soubor ahoj). Proto bude po zavolání příkazu make opět provedena kompilace. Aby nebylo nutné editorem soubor otevřít, provést změnu a výsledek uložit, lze využít příkaz touch ahoj.c, který změní čas poslední modifikace souboru.

Další cíle příkazu make

Cíle jsou v souboru Makefile pravidla (návěští), která lze provést tak, že jejich název přidáme jako parametr příkazu make. Následující soubor Makefile definuje pravidla ahoj a clean:

ahoj: ahoj.c
        gcc -Wall -o ahoj ahoj.c

clean:
       @rm -fv ahoj

Zadáme-li příkaz make bez parametru, provede se implicitní pravidlo (první pravidlo v souboru), což je zde pravidlo ahoj. Pro vyvolání dalších pravidel, které jsou v souboru uvedeny, je potřeba, aby bylo pravidlo zadáno příkazu make jako parametr. Zavináč před příkazy echo způsobí, že se prováděný příkaz nebude vypisovat (tj. nebude vidět řádek s příkazem) a bude tedy vypsán pouze výstup tohoto příkazu.

Vyzkoušejte a porovnejte výstup následujících příkazů:

make
make clean
make ahoj

První příkaz provede implicitní pravidlo, takže je spuštěn překlad programu. Druhý řádek s vyvoláním pravidla clean smaže přeložený soubor, takže po novém vyvolání překladu voláním pravidla ahoj dojde k novému překladu (pravidlo s názvem clean obvykle maže vše, co lze ze zdrojových kódů znovu snadno získat).

Použití maker

Makra umožňují používat uvnitř souborů Makefile používat proměnné a též přenášet hodnoty jejich hodnoty do překládaných programů (proto jsou označovány jako makra – stejně jako pro preprocesor jazyka C). Níže uvedený příklad rozvíjí předchozí soubor Makefile o použití maker. Zavedeno je makro NAZEV se jménem programu, VERZE pro číselné vyjádření verze programu a je též použito standardní makro CFLAGS, které obvykle obsahuje parametry pro překladač. Všimněte si použití maker v pravidlu help a v pravidlu ahoj.

NAZEV=Ahoj
VERZE=2
CFLAGS=-Wall

all: ahoj

help:
        @echo "Program $(NAZEV) verze $(VERZE)"
        @echo "Pouziti: make prikaz"
        @echo "prikaz:  help  - napoveda"
        @echo "         ahoj  - prelozit program"
        @echo "         clean - smazat binárku"

ahoj: ahoj.c
        $(CC) $(CFLAGS) -DVERZE=$(VERZE) -o ahoj ahoj.c

clean:
        rm -f ahoj

Ve výše zmíněném příkladu je použito pravidlo all, které obvykle slouží k zajištění úplného překladu celého projektu, který se může skládat z více kroků (z volání více jednotlivých pravidel). Makra je možné pomocí volání kompilátoru předat i do překládaného programu (viz pravidlo ahoj ve výše zmíněném překladu). Makro lze předefinovat při volání příkazu make:

make VERZE=3

Cvičení

Příklad 1
Vytvořte Makefile pro svůj program.
Příklad 2
Vytvořte soubor Makefile, který bude umět tyto činnosti: all, program, test, debug, clean. Cíl all přeloží a otestuje vás program, cíl program (tj. název vašeho programu) program jen přeloží, cíl test ho otestuje (tj. spustí s různými parametry a zkontroluje výstup), cíl debug program přeloží včetně ladících informací a cíl clean smaže všechny soubory (včetně dočasných ze sekce test), kromě souborů nutných pro opětovný překlad programu.
Příklad 3
Vytvořte soubory Makefile ve stromové struktuře adresářů. Hlavní soubor Makefile v kořenovém adresáři této struktury bude volat soubory Makefile v podadresářích.

Externí odkazy