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 make nem tudja kezelni a helyközt tartalmazó fájlneveket, és linuxban szimbolikus link esetén az eredeti (helyközös) néven dolgozza fel a fájlokat. Hard linkkel lehet áthidalni a problémát. 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.GNU make implicit változóinak listája (GNU operating system) automatikus változó:Automatikus változók (GNU operating system) 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.Az all nem fenntartott szó; szokás így nevezni az összes célt előállító szabályt. 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ésesDefining and Redefining Pattern Rules (GNU operating system) 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,Pl. általánosan elterjedt a clean cél használata a make által létrehozott fájlok törlésére, ami után a paraméter nélküli make újrafordítja a teljes programot. 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)
Kategória:Programozási nyelvek