Překlad se závislostmi (make a soubor Makefile)

Z Milan Kerslager
Přejít na: navigace, hledání

Překlad se závislostmi využívá schopnosti příkazu make, která umožňuje porovnávat časy poslední modifikace souborů a na základě toho rozhodnout, zda budou provedeny výkonné řádky příslušného pravidla. Z tohoto důvodu se do pravidla za dvojtečku zapisuje seznam souborů, na kterých vykonání pravidla závisí. Překlad se závislostmi se používá zejména u větších projektů, které je vhodné překládat po menších částech (do tak zvaného object kódu). Při překladu je pak pomocí závislostí přeložena jen ta část, která se změnila a ostatní části jsou použity z minulého překladu.

Příklad

Mějme větší projekt, který se skládá ze tří souborů: ahoj.c (hlavní program), funkce.c (soubor s funkcemi používanými hlavním programem) a funkce.h (prototypy funkcí ve formě hlavičkového souboru).

Zdrojové kódy

Soubor ahoj.c obsahuje hlavní funkci programu main, ze které je volána funkce tiskni(), která má zajistit samotný tisk zprávy na terminál. Tato funkce je záměrně vyvedena do samostatného souboru tiskni.c. V úvodu zdrojového kódu je volána direktiva preprocesoru pro vložení hlavičkového souboru funkce.h, protože při překladu je potřeba prototyp funkce tiskni(), která je následně kódu použita. Direktiva preprocesoru je použita se znaky uvozovek ("..."), protože v takovém případě je relativní cesta k souboru vztažena k aktuálním adresáři.

#include "funkce.h"

int main()
{
  tiskni();
  return 0;
}

Soubor funkce.c obsahuje výkonný kód funkcí, které používáme v hlavním programu. Je v něm realizována funkce tiskni(). V rámci souboru je nutné volat pomocí direktivy preprocesoru vložení hlavičkového souboru stdio.h, protože při překladu je potřeba prototyp funkce printf(), která je dále ve funkci tiskni() používána. Direktiva preprocesoru je použita se znaky vran (<...>), protože mezi nimi uvedená relativní cesta je vztažena k adresáři se systémovými hlavičkovými soubory (FHS stanovuje adresář /usr/include).

#include <stdio.h>

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

Hlavičkový soubor funkce.h obsahuje prototypy funkcí, které jsou umístěny v souboru tiskni.c:

void tiskni()

Makefile

Následující soubor Makefile bude na základě nadefinovaných závislostí schopen přeložit výše uvedené programy po jednotlivých částech tak, že z nich nejprve vytvoří polotovary (object kód, tj. soubory s příponou .o). Výsledné polotovary jsou na závěr spojeny dohromady a je vytvořen výsledný spustitelný soubor ahoj.

První pravidlo all je implicitní a definuje přeložení celého projektu. Jako závislost má definován cíl (soubor) ahoj. Druhé pravidlo (ahoj) předepisuje závislost na souborech ahoj.o a funkce.o, ze kterých je následujícím výkonným řádkem vyroben spustitelný soubor. Výkonný řádek bude spuštěn jen v případě, že některý z těchto souborů nebude existovat nebo když bude některý z nich novější, než cílový spustitelný soubor ahoj. Třetí pravidlo ahoj.o definuje výkonný řádek, který bude proveden v závislosti na stavu souborů ahoj.c a funkce.h. Čtvrté pravidlo funkce.o definuje postup pro vytvoření stejnojmenného souboru v závislosti na stavu souboru funkce.c:

Pravidlo clean slouží ke smazání produktů kompilace (object soubory a výsledný binární soubor).

CC      = gcc
ARGS    = -Wall

all: ahoj

ahoj: ahoj.o funkce.o
	$(CC) $(ARGS) ahoj.o funkce.o -o ahoj

ahoj.o: ahoj.c funkce.h
	$(CC) $(ARGS) -c ahoj.c

funkce.o: funkce.c
	$(CC) $(ARGS) -c funkce.c

clean:
	rm -fv *.o ahoj

Napíšeme-li make bude projekt podle splnění závislostí přeložen.