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