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.make
spustí 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
make
by měl zavolatsay_hello
agenerate
:$ make
Hello World
Vytváření prázdných textových souborů...
dotykový soubor-{1..10}.txtJe dobrým zvykem nevolat
clean
veall
nebo to dát jako první cíl.clean
by 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 clean
definuje falešné cíleall
aclean
. -
Proměnná
LINKERFLAG
definuje příznaky, které se mají použít sgcc
v receptu. -
SRCS := $(wildcard *.c)
:$(wildcard pattern)
je jednou z funkcí pro názvy souborů . V tomto případě všechny soubory s příponou.c
rozšíření bude uloženo v proměnnéSRCS
. -
BINS := $(SRCS:%.c=%)
:Toto se nazývá substituční reference . V tomto případě, pokudSRCS
má hodnoty'foo.c bar.c'
,BINS
bude mít'foo bar'
. -
Řádek
all: ${BINS}
:Falešný cílall
volá 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
foo
je 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í.