make a Makefile

http://kvik.sh.cvut.cz/~fidlej/cecko/makefile/referat.html
Upozornění:
Popisuji GNU verzi make.

Úlohou utility make je rozpoznat jaká část projektu potřebuje
překompilovat a provést potřebné kroky k překompilování.

"make" bez parametrů hledá v aktuálním adresáři soubor GNUMakefile,
makefile nebo Makefile.
Bude se snažit provést první pravidlo tvaru:

cíl: předpoklady
<tab>příkazy

Cíl musí být rekompilován jestliže neexistuje, nebo je starší než
předpoklady.

Ukázka Makefile:
------------------------------------------------------------------------
# vse za '#' je komentar
CFLAGS = -Wall

program: main.o net.o gui.o
$(CC) $(CFLAGS) -o $@ main.o net.o gui.o

main.o: main.c net.h gui.h
net.o: net.c net.h
gui.o: gui.c gui.h

clean:
rm -f program main.o net.o gui.o
------------------------------------------------------------------------
ukazka.tar.gz adresář s ukázkou Vysvětlení - nastavení proměnné CFLAGS. - na čem je závislý 'program', souborech main.o, net.o a guio. Následující řádek je příkaz, který se provede pokud bude některý soubor novějšího data než 'program'. Musí byt odsazen tabulatorem! $(CC) znamená obsah proměnné CC, defaultně nastavené CC=cc $@ se rozvine jako text před dvojtečkou. Takže: cc -Wall -o program main.o net.o gui.o Pro každou řádku příkazů se spustí nový shell. Pokud chceme, aby se příkazy ovlivňovaly napíšeme je za sebou. ./mimo/zde: cd mimo; touch zde Další řádky definují závislosti jednotlivých .o souborů. Pokud zkusíme "make", uvidíme cc -Wall -c -o main.o main.c cc -Wall -c -o net.o net.c cc -Wall -c -o gui.o gui.c cc -Wall -o program main.o net.o gui.o Pokud nyní změníme soubor net.c, "make" provede již jen cc -Wall -c -o net.o net.c cc -Wall -o program main.o net.o gui.o Možná se divíte, jak přišel make na příkazy pro vytvoření main.o, net.o a gui.o. Použije totiž implicitní pravidlo %.o: %.c $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $< $< se rozvine ve jméno prvního předpokladu CFLAGS a CPPFLAGS jsou defaultně prázdné, my jsme si však CFLAGS nastavili na '-Wall' Poslední pravidlo v našem Makefile, pravidlo 'clean', poslouží k odstranění vzniklých souborů. "make" nám při ponechání zdrojáků jen vypíše hlášení: make: `program' is up to date. make clean však vytvořené soubory smaže, a můžeme si znovu prohlédnout kompilaci. Make není jen pro programátory v jazyce C. Stejně dobře pomůže Javě, TeXu, ... ------------------------------------------------------------------------ Manuál ------------------------------------------------------------------------ Proměnné Doporučeno z písmenek, číslic a '_'. Rozlišuje se velikost písmen (case-sensitive). pomocí $(foo) dostaneme obsah proměnné foo $$ je dolar přiřazení: foo = hodnota foo = $(CC) -g $(CC) se však expanduje až později foo = $(foo) -neco nelze, vzniká rekurze foo := $(foo) -neco funguje, použije se hodnota $(foo) definovaná na řádcích výše ------------------------------------------------------------------------ Automatické proměnné $@ jméno cíle $< jméno prvního předpokladu $? jména předpokladů jenž jsou novější než cíl $^ jména všech předpokladů, oddělená mezerami ------------------------------------------------------------------------ Jak prochází make Makefile 1. fáze: projde všechny i vložené makefile, čte proměnné, implicitní a explicitní pravidla a sestaví graf závisloti cílů na jejich předpokladech. 2. fáze: použije tyto strukturu k určení jaké cíle je nutné překompilovat Co se kdy expanduje hned = později hned := hned hned : hned později ------------------------------------------------------------------------ Užitečné přepínače -f soubor použije se `soubor` namísto Makefile -n nevykonává, jen vypisuje průběh -p současně vypíše kompletní nastavení proměnných, implicitních pravidel, ... ------------------------------------------------------------------------ Funkce pro zpracování textu Volají se podobně jako proměnné $(funkce argumenty) $(subst from,to,text) substituce $(patsubst pattern,replacement,text) % v pattern představuje lib. posloupnost znaků % v replacement odpovídá této množině př.: $(patsubst %.c,%.o,main.c bar.c) $(var:pattern=replacement) je ekvivalentní $(patsubst pattern,replacement,$(var)) př.: CLASSES = $(SOURCES:.java=.class) $(wildcard pattern) názvy souborů odpovídají pattern, jako v shellu př.: SOURCES = $(wildcard *.java) ------------------------------------------------------------------------ Nakonec předkládám můj oblíbený Makefile.
# Univerzalni Makefile pro jednoduche projekty
# Zkompiluje vsechny *.cpp do jedne binarky.

# Our program name
PROGRAMS = ourprogram

# C++ compiler
CC = g++
CFLAGS = -g # -pg -O2 # -I/usr/X11R6/include

# The linker flags
LDFLAGS = # -L/usr/X11R6/lib

# Added library
LOADLIBES = # -lm -lGL -lGLU


# Warning flags for C programs
WARNCFLAGS = -Wall -Wshadow -Wpointer-arith \
-Wcast-qual -Wcast-align -Wmissing-prototypes \
-Woverloaded-virtual # -W

# Warning for linker
WARNLD = -Wbad-function-cast -Wstrict-prototypes -Wmissing-declarations


# All the .cpp files
SOURCES = $(wildcard *.cpp)
# And the corresponding .o files
OBJECTS = $(SOURCES:.cpp=.o)


# The first target in the makefile is the default target. It's usually called
# "all".
all: $(PROGRAMS)


# We assume we have one program (`ourprogram') to build, from all the object
# files derived from .cpp files in the current directory.
$(PROGRAMS): $(OBJECTS)
$(CC) $(WARNCFLAGS) $(WARNLD) $(CFLAGS) $(LDFLAGS) -o $(PROGRAMS) $(OBJECTS) $(LOADLIBES)

# Include known dependecies from -MMD
-include $(OBJECTS:.o=.d)

# How to make *.o files
%.o: %.cpp
$(CC) -MMD $(WARNCFLAGS) $(CFLAGS) -c $<

# "clean" removes files not needed after a build.
clean:
rm -f $(OBJECTS) *.d tags gmon.out
Napsal:
Ivo Danihelka Zdroj informaci: GNU Make Manual