GNU/Linux >> Znalost Linux >  >> Linux

Co je Makefile a jak funguje?

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ředpoklady
recept

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 *.txt

Př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 zavolat say_hello a generate :

$ make
Hello World
Vytváření prázdných textových souborů...
dotykový soubor-{1..10}.txt

Je dobrým zvykem nevolat clean ve all 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 pro make :

$ make clean
Čištění...
rm *.txt

Nyní, 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íle all a clean .

  • Proměnná LINKERFLAG definuje příznaky, které se mají použít s gcc 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ě, pokud SRCS má hodnoty 'foo.c bar.c' , BINS bude mít 'foo bar' .

  • Řádek all: ${BINS} :Falešný cíl all 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ídat foo (% 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 foo

    Jak je uvedeno, % je nahrazeno foo . $< je nahrazeno foo.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í.


Linux
  1. Co je NGINX? Jak to funguje?

  2. Co je webový server a jak webový server funguje?

  3. Co je DNS a jak funguje?

  1. Jak Awk ‚!a[$0]++‘ funguje?

  2. Jak rm funguje? Co dělá rm?

  3. Jak vlastně sig_atomic_t funguje?

  1. Jak Sticky Bit funguje?

  2. Účel .bashrc a jak to funguje?

  3. Ssh – Jak funguje Tcp-keepalive v Ssh?