Pokud chcete spustit nebo aktualizovat úlohu při aktualizaci určitých souborů, make užitečnost se může hodit. make obslužný program vyžaduje soubor Makefile (nebo makefile ), který definuje sadu úloh, které mají být provedeny. Možná jste použili make zkompilovat program ze zdrojového kódu. Většina open source projektů používá make zkompilovat finální spustitelný binární soubor, který lze poté nainstalovat pomocí make install .
V tomto článku prozkoumáme make a Makefile pomocí základních a pokročilých příkladů. Než začnete, ujistěte se, že make je nainstalován ve vašem systému.
Základní příklady
Začněme vytištěním klasického „Hello World“ na terminálu. Vytvořte prázdný adresář myproject obsahující soubor Makefile s tímto obsahem:
say_hello:
echo "Ahoj světe"
Nyní spusťte soubor zadáním make v adresáři myproject . Výstup bude:
$ make
echo "Ahoj světe"
Ahoj světe
Ve výše uvedeném příkladu say_hello chová se jako název funkce, jako v každém programovacím jazyce. Tomu se říká cíl . Předpoklady nebo závislosti sledovat cíl. Pro zjednodušení jsme v tomto příkladu nedefinovali žádné předpoklady. Příkaz echo "Hello World" se nazývá recept . recept používá předpoklady vytvořit cíl . Cíl, předpoklady a recepty dohromady tvoří pravidlo .
Abychom to shrnuli, níže je syntaxe typického pravidla:
cíl:předpokladyrecept
Jako příklad může být cílem binární soubor, který závisí na předpokladech (zdrojové soubory). Na druhou stranu předpokladem může být také cíl, který závisí na dalších závislostech:
final_target:sub_target final_target.c
Recipe_to_create_final_target
sub_target:sub_target.c
Recipe_to_create_sub_target
Není nutné, aby cílem byl soubor; může to být jen název pro recept, jako v našem příkladu. Říkáme jim „falešné cíle.“
Vraťme se k výše uvedenému příkladu, když make byl proveden celý příkaz echo "Hello World" byl zobrazen, následovaný skutečným výstupem příkazu. To často nechceme. Abychom potlačili echo skutečného příkazu, musíme spustit echo s @ :
say_hello:
@echo "Ahoj světe"
Nyní zkuste spustit make znovu. Výstup by měl zobrazovat pouze toto:
$ make
Ahoj světe
Pojďme přidat několik dalších falešných cílů:generate a clean do Makefile :
say_hello:
@echo "Ahoj světe"
generovat:
@echo "Vytváření prázdných textových souborů..."
klepněte na soubor-{1. .10}.txt
vyčistit:
@echo "Uklízení..."
rm *.txt
Pokud se pokusíme spustit make po změnách pouze cíl say_hello bude popraven. Je to proto, že pouze první cíl v makefile je výchozím cílem. Často se nazývá výchozí cíl , to je důvod, proč uvidíte all jako první cíl ve většině projektů. Je to odpovědnost all zavolat další cíle. Toto chování můžeme přepsat pomocí speciálního falešného cíle nazvaného .DEFAULT_GOAL .
Zahrneme to na začátek našeho souboru makefile:
.DEFAULT_GOAL := generate
Tím se spustí cíl generate jako výchozí:
$ make
Vytváření prázdných textových souborů...
dotykový soubor-{1..10}.txt
Jak název napovídá, falešný cíl .DEFAULT_GOAL může spustit pouze jeden cíl najednou. To je důvod, proč většina makefiles obsahuje all jako cíl, který může volat tolik cílů, kolik je potřeba.
Pojďme zahrnout falešný cíl all a odstraňte .DEFAULT_GOAL :
all:say_hello generation
say_hello:
@echo "Ahoj světe"
generate:
@echo "Vytváření prázdných textových souborů.. ."
dotkněte se souboru-{1..10}.txt
vyčistit:
@echo "Probíhá úklid..."
rm *.txtPřed spuštěním
make, zahrneme další speciální falešný cíl,.PHONY, kde definujeme všechny cíle, které nejsou soubory.makespustí svůj recept bez ohledu na to, zda soubor s tímto názvem existuje nebo jaký je čas jeho poslední úpravy. Zde je úplný soubor makefile:.PHONY:all say_hello generovat čisté
all:say_hello generovat
say_hello:
@echo "Hello World"
vygenerovat:
@echo "Vytváření prázdných textových souborů..."
touch file-{1..10}.txt
clean:
@echo "Čištění nahoru..."
rm *.txt
makeby měl zavolatsay_helloagenerate:$ make
Hello World
Vytváření prázdných textových souborů...
dotykový soubor-{1..10}.txtJe dobrým zvykem nevolat
cleanveallnebo to dát jako první cíl.cleanby měl být volán ručně, když je potřeba čištění jako první argument promake:$ make clean
Čištění...
rm *.txtNyní, když máte představu o tom, jak funguje základní makefile a jak napsat jednoduchý makefile, pojďme se podívat na některé pokročilejší příklady.
Pokročilé příklady
Proměnné
Další zdroje pro Linux
- Cheat pro příkazy Linuxu
- Cheat sheet pro pokročilé příkazy systému Linux
- Bezplatný online kurz:Technický přehled RHEL
- Síťový cheat pro Linux
- Cheat sheet SELinux
- Cheat pro běžné příkazy pro Linux
- Co jsou kontejnery systému Linux?
- Naše nejnovější články o Linuxu
Ve výše uvedeném příkladu je většina cílových a nezbytných hodnot pevně zakódována, ale ve skutečných projektech jsou nahrazeny proměnnými a vzory.
Nejjednodušší způsob, jak definovat proměnnou v makefile, je použít = operátor. Chcete-li například přiřadit příkaz gcc do proměnné CC :
CC = gcc
Říká se tomu také rekurzivní rozšířená proměnná a používá se v pravidle, jak je uvedeno níže:
ahoj:hello.c
${CC} hello.c -o hello
Jak jste možná uhodli, recept se po předání do terminálu rozbalí následovně:
gcc hello.c -o hello
Oba ${CC} a $(CC) jsou platné odkazy na volání gcc . Ale pokud se někdo pokusí znovu přiřadit proměnnou k sobě, způsobí to nekonečnou smyčku. Pojďme si to ověřit:
CC =gcc
CC =${CC}
vše:
@echo ${CC}
Spuštění make výsledkem bude:
$ make
Makefile:8:*** Rekurzivní proměnná 'CC' odkazuje sama na sebe (nakonec). Zastavit.
Abychom se tomuto scénáři vyhnuli, můžeme použít := operátor (také se nazývá jednoduše rozšířená proměnná ). Neměli bychom mít problém se spuštěním souboru makefile níže:
CC :=gcc
CC :=${CC}
all:
@echo ${CC}
Vzory a funkce
Následující makefile dokáže zkompilovat všechny programy C pomocí proměnných, vzorů a funkcí. Pojďme to prozkoumat řádek po řádku:
# Použití:
# make # kompilovat všechny binární
# make clean # odstranit VŠECHNY binární soubory a objekty
.PHONY =all clean
CC =gcc # kompilátor k použití
LINKERFLAG =-lm
SRCS :=$(zástupný znak *.c)
BINS :=$(SRCS:%. c=%)
vše:${BINS}
%:%.o
@echo "Checking.."
${CC} ${LINKERFLAG} $<-o $@
%.o:%.c
@echo "Vytváření objektu.."
${CC} -c $<
vyčistit:
@echo "Uklízení..."
rm -rvf *.o ${BINS}
-
Řádky začínající
#jsou komentáře. -
Řádek
.PHONY = all cleandefinuje falešné cíleallaclean. -
Proměnná
LINKERFLAGdefinuje příznaky, které se mají použít sgccv receptu. -
SRCS := $(wildcard *.c):$(wildcard pattern)je jednou z funkcí pro názvy souborů . V tomto případě všechny soubory s příponou.crozšíření bude uloženo v proměnnéSRCS. -
BINS := $(SRCS:%.c=%):Toto se nazývá substituční reference . V tomto případě, pokudSRCSmá hodnoty'foo.c bar.c',BINSbude mít'foo bar'. -
Řádek
all: ${BINS}:Falešný cílallvolá hodnoty v${BINS}jako individuální cíle. -
Pravidlo:
%:%.o
@echo "Probíhá kontrola.."
${CC} ${LINKERFLAG} $< -o $@Pro pochopení tohoto pravidla se podívejme na příklad. Předpokládejme
fooje jednou z hodnot v${BINS}. Potom%bude odpovídatfoo(%může odpovídat libovolnému cílovému názvu). Níže je pravidlo v jeho rozšířené podobě:foo:foo.o
@echo "Probíhá kontrola.."
gcc -lm foo.o -o fooJak je uvedeno,
%je nahrazenofoo.$<je nahrazenofoo.o.$<je vzorováno tak, aby odpovídalo předpokladům a$@odpovídá cíli. Toto pravidlo bude voláno pro každou hodnotu v${BINS} -
Pravidlo:
%.o:%.c
@echo "Vytváření objektu.."
${CC} -c $<Každý předpoklad v předchozím pravidle je považován za cíl pro toto pravidlo. Níže je pravidlo v jeho rozšířené podobě:
foo.o:foo.c
@echo "Vytváření objektu.."
gcc -c foo.c -
Nakonec odstraníme všechny binární soubory a soubory objektů v cíli
clean.
Níže je přepsání výše uvedeného makefile, za předpokladu, že je umístěn v adresáři s jediným souborem foo.c:
# Použití:
# make # kompilovat všechny binární
# make clean # odstranit VŠECHNY binární soubory a objekty
.PHONY =all clean
CC =gcc # kompilátor k použití
LINKERFLAG =-lm
SRCS :=foo.c
BINS :=foo
vše :foo
foo:foo.o
@echo "Checking.."
gcc -lm foo.o -o foo
foo.o :foo.c
@echo "Vytváření objektu.."
gcc -c foo.c
clean:
@echo "Uklízení..."
rm -rvf foo.o foo
Další informace o souborech makefiles naleznete v příručce GNU Make, která nabízí kompletní reference a příklady.
Můžete si také přečíst náš Úvod do GNU Autotools, kde se dozvíte, jak automatizovat generování makefile pro váš projekt kódování.