Make
A make egy programfordításra kifejlesztett segédprogram: a forrásprogramokból előállítja a végrehajtható programo(ka)t. Csak a szükséges műveleteket végzi el: azokat a forrásprogramokat fordítja le, melyeket még nem fordított le, vagy melyek az utolsó fordítás óta változtak.

A make nemcsak programfordításra használható, hanem minden olyan feladatra, ahol fájlokból más fájlokat kell előállítani. Unix operációs rendszerre fejlesztették ki, de azóta más rendszerekben is megtalálható.

A make a fájlok dátumából állapítja meg, hogy szükséges-e a fordítás. Tartalmaz beépített szabályokat az ismert programnyelvek számára, de saját szabályok is megadhatók, ill. a beépítettek helyettesíthetők saját szabályokkal.

A make programot rendszerint paraméter nélkül hívjuk. A fordításhoz szükséges tennivalók az aktuális könyvtárban, a Makefile nevű fájlban vannak.

Formai szabályok 
Makefile-ban
 a #-sel kezdődő sorok megjegyzések
 a sor végi \ folytatósort jelöl
 a szabály utasításainak első karaktere kötelezően tabulátor. Nem helyettesíthető egy vagy több helyközzel.
 a $ lefoglalt karakter a make változói számára. Ha a $ nem a make-nek szól (hanem pl. a shellnek), meg kell kettőzni: $$.

A make működése 
Példa Makefile-ra:
proba	: proba.c
	gcc -o proba proba.c

A fenti példa egyetlen szabályt tartalmaz. A szabály első sorában a kettősponttól balra álló szó a cél, a jobbra álló az előfeltétel. Több cél és több előfeltétel adható meg helyközzel elválasztva. A szabály következő sora(i) a célt előállító utasítás(ok). Fontos, hogy az utasítások tabulátorral (és nem helyközökkel) kezdődnek: a make innen tudja, mely sorok tartoznak a szabályhoz.

Az utasítások elmaradhatnak, ha van olyan implicit szabály, mely a célt elő tudja állítani (pl. a kiterjesztése alapján). Az előfeltételek is elmaradhatnak: ilyenkor az utasítások mindenképpen végrehajtódnak.

A make hívósorában cél(ok) adható(k) meg paraméterként. Ha nincs paraméter, az első szabály hajtódik végre, ami tipikus esetben az összes célt előállítja.

A célok fájlok (hacsak mást nem adunk meg: lásd a .PHONY utasítást). Az előfeltételek más szabályok célfájljai, ill. ha nem létezik ilyen szabály, akkor normál fájlok.

Az előfeltétel ellenőrzéséhez a make végrehajtja az előfeltétel-fájlt létrehozó szabályt (hogy ellenőrizze, nem kell-e újra létrehozni), ill. ha nincs ilyen szabály, de normál fájl igen, akkor összehasonlítja a célfájl és az előfeltétel-fájl dátumát. Ha a cél régebbi, mint a fájl, akkor a célt újra létre kell hozni, azaz végre kell hajtani az utasításait, ellenkező esetben nincs tennivaló: a cél az adott előfeltétel szempontjából naprakész. Ha sem szabálya, sem normál fájlja nincs az előfeltételnek, akkor a szabály befejeződik, és hibával visszatér az őt hívó szabályhoz.

A make a fenti módon egymás után ellenőrzi a szabály összes előfeltételét.

Egy szabálynak háromféle végeredménye lehet:
 a szabály sikeresen végrehajtódott: a szabály utasításait végre kellett hajtani, mert valamelyik előfeltétele nem volt naprakész, és a végrehajtás sikeres volt
 a szabály utasításait nem kellett végrehajtani, mert a cél naprakész valamennyi előfeltétel szempontjából
 a szabály végrehajtása sikertelen, ha legalább egy előfeltétele vagy utasítása sikertelen.

Utasítások 
Fontos, hogy a make a szabály utasításait soronként külön-külön shellben hajtja végre. Pl. a külön sorba írt cd könyvtár utasítás hatástalan, mivel a shellből való kilépés után megszűnik a hatása, így a következő sorban levő make-utasítást sem befolyásolja. Pontosvesszővel elválasztva viszont lehet több utasítást adni ugyanannak a shellnek.

A make minden utasítássor után ellenőrzi a shelltől visszakapott értéket, és ha az nem 0, vagyis a sor végrehajtása sikertelen, félbeszakítja az utasítások végrehajtását, és hibával visszatér a hívó szabályhoz, ami ugyancsak hibával visszatér az őt hívóhoz, stb., végül a make is hibával tér vissza a shellbe.

Változók 
A make-ben háromféle típusú változó van:
 implicit változó: a make beépített változói. Pl. a CC nevű változó tartalmazza az adott rendszerben a C-fordító nevét.
 automatikus változó: a szabály végrehajtásakor jön létre. A két legfontosabb automatikus változó:
 $@ a cél neve
 $^ az előfeltételek helyközzel elválasztott listája.
 a Makefile-ban a programozó által definiált saját változó.

A változó értékére a $(változónév) kifejezéssel lehet hivatkozni (az automatikus változók kivételével, ahol nem kell zárójel).

Saját változó a változónév = érték alakban definiálható. Az érték bármilyen szöveg lehet.

Az implicit és automatikus változó az utasításokban használható, a saját változó bárhol a szabályban.

 Példa:
MIND = proba proba.gz

all	: $(MIND)

proba	: proba.c proba1.c
	$(CC) -o $@ $^

proba.gz : proba.1
	gzip -c <$^ >$@

A MIND saját változó, mely a célok nevét (a végrehajtható programét és a tömörített manuálét) tartalmazza helyközzel elválasztva.

Az all a Makefile első szabálya, ez hajtódik végre, ha paraméter nélkül hívjuk a make parancsot. Miután utasítása nincs, csak az előfeltételeket ellenőrzi, de ezzel le is fordítja a programot ill. újratömöríti a manuált, ha valamelyik megváltozott. Az automatikus változók lehetővé teszik, hogy minden fájlnevet csak egyszer kelljen leírni, a CC implicit változó pedig azt, hogy Makefile-lal ne csak linuxban lehessen a programot lefordítani.

Implicit szabályok 
A fenti példában mindkét C-program lefordul, ha bármelyik forrásfájl megváltozik. Ez nem előnyös, különösen sok forrásprogramból álló programok esetén. Az alábbi Makefile-részlet megoldja a problémát:

...
proba	: proba.o proba1.o
	$(CC) -o $@ $^

proba.o : proba.c
	$(CC) -c $^

proba1.o : proba1.c
	$(CC) -c $^
...

Ebben az a kényelmetlen, hogy kétszer kell felsorolni a forrásfájlokat, és kétszer kell leírni a .c → .o fordítás utasítását is. Ezt lehet elkerülni implicit szabállyal:

...
.c.o:
	$(CC) -Wall -c $^
...

A fenti implicit szabály azt adja meg, hogyan kell .c kiterjesztésű fájlból .o-t előállítani. Ez helyettesíti a két .o kiterjesztésű cél szabályát. Amikor a proba cél előfeltételeiben a make találkozik proba.o-val, és nem talál ezt előállító szabályt, megpróbál olyan implicit szabályt keresni, mely előállít ilyen kiterjesztésű fájlt.

Háromféle implicit szabály létezik:
 mintaillesztéses
 kiterjesztéses, más néven hagyományos (fenti példa)
 beépített.
A mintaillesztéses implicit szabály a hagyományos kiterjesztése.

A make-nek vannak beépített implicit szabályai, pl. a .c → .o átalakításra is. Ezek törölhetők, de a törlés hátránya, hogy a Makefile nem lesz hordozható különböző operációs rendszerek között.
.SUFFIXES:
.SUFFIXES: .c .o .1 .gz

Az első sor törli az összes beépített szabályt, de a törléssel a beépített kiterjesztések táblázata is törlődik. A második sor pótolja azt a négy kiterjesztést, melyre a példában szükség van.

Hamis célok 
A fenti példában az all célú szabállyal probléma lehet, ha az aktuális könyvtárban véletlenül létezik all nevű fájl. Miután nem ritka az ehhez hasonló cél, a probléma elkerülésére külön utasítás szolgál:
.PHONY: all
A .PHONY után írt szavakat céloknak tekinti a make, és előfeltétel ellenőrzésekor végrehajtja a szabályaikat, de nem ellenőrzi, léteznek-e ilyen nevű fájlok.

Példa Makefile-ra 
.SUFFIXES:
.SUFFIXES: .c .o .1 .gz
.PHONY: all clean
 
.c.o:
	$(CC) -c -Wall $^
 
.1.gz:
	gzip -c <$^ >$@
 
MIND = proba proba.gz
 
all	: $(MIND)
 
proba	: proba.o proba1.o
	$(CC) -o $@ $^
 
clean:
	rm -f $(MIND) *.o
A -WaLL a C-fordító kapcsolója: bekapcsolja az összes figyelmeztetést.

Az rm parancsban fontos a -f: az rm – következésképp a make is – hibát jelez, ha nem létezik valamelyik törlendő fájl. A hibajelzést szünteti meg a kapcsoló.

Jegyzetek

Források 
 GNU Make Manual (GNU operating system)

Kapcsolódó szócikkek 
 Fordítóprogram
 C (programozási nyelv)
 Unix rendszerhéj (shell)

Programozási nyelvek
A make egy programfordításra kifejlesztett segédprogram : a forrásprogramokból előállítja a végrehajtható programo( ka) t . Csak a szükséges műveleteket végzi el : azokat a forrásprogramokat fordítja le , melyeket még nem fordított le , vagy melyek az utolsó fordítás óta változtak . A make nemcsak programfordításra használható , hanem minden olyan feladatra , ahol fájlokból más fájlokat kell előállítani . Unix operációs rendszerre fejlesztették ki , de azóta más rendszerekben is megtalálható . A make a fájlok dátumából állapítja meg , hogy szükséges-e a fordítás . Tartalmaz beépített szabályokat az ismert programnyelvek számára , de saját szabályok is megadhatók , ill . a beépítettek helyettesíthetők saját szabályokkal . A make programot rendszerint paraméter nélkül hívjuk . A fordításhoz szükséges tennivalók az aktuális könyvtárban , a Makefile nevű fájlban vannak . Formai szabályok Makefile-ban a #-sel kezdődő sorok megjegyzések a sor végi \ folytatósort jelöl a szabály utasításainak első karaktere kötelezően tabulátor . Nem helyettesíthető egy vagy több helyközzel. a $ lefoglalt karakter a make változói számára . Ha a $ nem a make-nek szól ( hanem pl. a shellnek ) , meg kell kettőzni : $$ . A make működése Példa Makefile-ra : proba : proba.c gcc -o proba proba.c A fenti példa egyetlen szabályt tartalmaz . A szabály első sorában a kettősponttól balra álló szó a cél , a jobbra álló az előfeltétel . Több cél és több előfeltétel adható meg helyközzel elválasztva . A szabály következő sora ( i ) a célt előállító utasítás( ok ) . Fontos , hogy az utasítások tabulátorral ( és nem helyközökkel ) kezdődnek : a make innen tudja , mely sorok tartoznak a szabályhoz . Az utasítások elmaradhatnak , ha van olyan implicit szabály , mely a célt elő tudja állítani ( pl. a kiterjesztése alapján ) . Az előfeltételek is elmaradhatnak : ilyenkor az utasítások mindenképpen végrehajtódnak . A make hívósorában cél( ok ) adható ( k ) meg paraméterként . Ha nincs paraméter , az első szabály hajtódik végre , ami tipikus esetben az összes célt előállítja . A célok fájlok ( hacsak mást nem adunk meg : lásd a\.PHONY utasítást ) . Az előfeltételek más szabályok célfájljai , ill . ha nem létezik ilyen szabály , akkor normál fájlok . Az előfeltétel ellenőrzéséhez a make végrehajtja az előfeltétel-fájlt létrehozó szabályt ( hogy ellenőrizze , nem kell-e újra létrehozni ) , ill . ha nincs ilyen szabály , de normál fájl igen , akkor összehasonlítja a célfájl és az előfeltétel-fájl dátumát . Ha a cél régebbi , mint a fájl , akkor a célt újra létre kell hozni , azaz végre kell hajtani az utasításait , ellenkező esetben nincs tennivaló : a cél az adott előfeltétel szempontjából naprakész . Ha sem szabálya , sem normál fájlja nincs az előfeltételnek , akkor a szabály befejeződik , és hibával visszatér az őt hívó szabályhoz . A make a fenti módon egymás után ellenőrzi a szabály összes előfeltételét . Egy szabálynak háromféle végeredménye lehet : a szabály sikeresen végrehajtódott : a szabály utasításait végre kellett hajtani , mert valamelyik előfeltétele nem volt naprakész , és a végrehajtás sikeres volt a szabály utasításait nem kellett végrehajtani , mert a cél naprakész valamennyi előfeltétel szempontjából a szabály végrehajtása sikertelen , ha legalább egy előfeltétele vagy utasítása sikertelen . Utasítások Fontos , hogy a make a szabály utasításait soronként külön-külön shellben hajtja végre . Pl. a külön sorba írt cd könyvtár utasítás hatástalan , mivel a shellből való kilépés után megszűnik a hatása , így a következő sorban levő make-utasítást sem befolyásolja . Pontosvesszővel elválasztva viszont lehet több utasítást adni ugyanannak a shellnek . A make minden utasítássor után ellenőrzi a shelltől visszakapott értéket , és ha az nem vagyis a sor végrehajtása sikertelen , félbeszakítja az utasítások végrehajtását , és hibával visszatér a hívó szabályhoz , ami ugyancsak hibával visszatér az őt hívóhoz , stb. , végül a make is hibával tér vissza a shellbe . Változók A make-ben háromféle típusú változó van : implicit változó : a make beépített változói . Pl. a CC nevű változó tartalmazza az adott rendszerben a C-fordító nevét. automatikus változó : a szabály végrehajtásakor jön létre . A két legfontosabb automatikus változó : $ @ a cél neve $^ az előfeltételek helyközzel elválasztott listája. a Makefile-ban a programozó által definiált saját változó . A változó értékére a $( változónév ) kifejezéssel lehet hivatkozni ( az automatikus változók kivételével , ahol nem kell zárójel ) . Saját változó a változónév = érték alakban definiálható . Az érték bármilyen szöveg lehet . Az implicit és automatikus változó az utasításokban használható , a saját változó bárhol a szabályban . Példa : MIND = proba proba.gz all : $( MIND ) proba : proba.c proba1.c $( CC ) -o $ @ $^ proba.gz \ : proba.1 gzip -c <$^ >$ @ A MIND saját változó , mely a célok nevét ( a végrehajtható programét és a tömörített manuálét ) tartalmazza helyközzel elválasztva . Az all a Makefile első szabálya , ez hajtódik végre , ha paraméter nélkül hívjuk a make parancsot . Miután utasítása nincs , csak az előfeltételeket ellenőrzi , de ezzel le is fordítja a programot ill . újratömöríti a manuált , ha valamelyik megváltozott . Az automatikus változók lehetővé teszik , hogy minden fájlnevet csak egyszer kelljen leírni , a CC implicit változó pedig azt , hogy Makefile-lal ne csak linuxban lehessen a programot lefordítani . Implicit szabályok A fenti példában mindkét C-program lefordul , ha bármelyik forrásfájl megváltozik . Ez nem előnyös , különösen sok forrásprogramból álló programok esetén . Az alábbi Makefile-részlet megoldja a problémát : ... proba : proba.o proba1.o $( CC ) -o $ @ $^ proba.o \ : proba.c $( CC ) -c $^ proba1.o \ : proba1.c $( CC ) -c $^ ... Ebben az a kényelmetlen , hogy kétszer kell felsorolni a forrásfájlokat , és kétszer kell leírni a\.c →\.o fordítás utasítását is . Ezt lehet elkerülni implicit szabállyal : ... .c.o : $( CC ) -Wall -c $^ ... A fenti implicit szabály azt adja meg , hogyan kell\.c kiterjesztésű fájlból \.o-t előállítani . Ez helyettesíti a két\.o kiterjesztésű cél szabályát . Amikor a proba cél előfeltételeiben a make találkozik proba.o-val , és nem talál ezt előállító szabályt , megpróbál olyan implicit szabályt keresni , mely előállít ilyen kiterjesztésű fájlt . Háromféle implicit szabály létezik : mintaillesztéses kiterjesztéses , más néven hagyományos ( fenti példa ) beépített . A mintaillesztéses implicit szabály a hagyományos kiterjesztése . A make-nek vannak beépített implicit szabályai , pl . a\.c →\.o átalakításra is . Ezek törölhetők , de a törlés hátránya , hogy a Makefile nem lesz hordozható különböző operációs rendszerek között . .SUFFIXES : .SUFFIXES : \.c\.o\.1\.gz Az első sor törli az összes beépített szabályt , de a törléssel a beépített kiterjesztések táblázata is törlődik . A második sor pótolja azt a négy kiterjesztést , melyre a példában szükség van . Hamis célok A fenti példában az all célú szabállyal probléma lehet , ha az aktuális könyvtárban véletlenül létezik all nevű fájl . Miután nem ritka az ehhez hasonló cél , a probléma elkerülésére külön utasítás szolgál : .PHONY : all A\.PHONY után írt szavakat céloknak tekinti a make , és előfeltétel ellenőrzésekor végrehajtja a szabályaikat , de nem ellenőrzi , léteznek-e ilyen nevű fájlok . Példa Makefile-ra .SUFFIXES : .SUFFIXES : \.c \.o\.1\.gz .PHONY : all clean .c.o : $( CC ) -c -Wall $^ .1.gz : gzip -c <$^ >$ @ MIND = proba proba.gz all : $( MIND ) proba : proba.o proba1.o $( CC ) -o $ @ $^ clean : rm -f $( MIND ) *.o A -WaLL a C-fordító kapcsolója : bekapcsolja az összes figyelmeztetést . Az rm parancsban fontos a -f : az rm – következésképp a make is – hibát jelez , ha nem létezik valamelyik törlendő fájl . A hibajelzést szünteti meg a kapcsoló . Jegyzetek Források GNU Make Manual ( GNU operating system ) Kapcsolódó szócikkek Fordítóprogram C ( programozási nyelv ) Unix rendszerhéj ( shell ) Programozási nyelvek