A Make egy olyan szoftver, amely automatikusan felépíti a fájlt , gyakran futtatható vagy könyvtárakat olyan alapvető elemekből, mint a forráskód . A makefiles nevű fájlokat használja, amelyek meghatározzák a célfájlok felépítésének módját. Egy egyszerű shell parancsfájltól eltérően a make csak akkor hajt végre parancsokat, ha szükség van rájuk. A cél az eredmény elérése (szoftver összeállítása vagy telepítése, dokumentáció készítése stb.) Anélkül, hogy szükségszerűen elvégezné az összes lépést. A make különösen a UNIX platformokon használható .
Az 1970-es években a programok összeállítása egyre hosszabbá és összetettebbé vált, sok egymással összefüggő lépésre volt szükség. Az akkor használt rendszerek többsége shell szkripteken alapul , amelyek megkövetelik az összes lépést a legkisebb korrekció érdekében. Ez ebben az összefüggésben, hogy gyártmánya fejlesztették doktor Stuart Feldman (in) , a 1977 , míg ő dolgozik Bell Labs . A forrásfájlok és a lefordított fájlok közötti függőségek kezelésével a Make lehetővé teszi, hogy csak azt állítsa össze, ami a forrásfájl módosítását követően szükséges.
Az eredeti fejlesztés óta a program számos változatot látott. A legismertebbek a BSD és a GNU Projektek - alapértelmezés szerint Linux rendszereken . Ezek a variánsok új funkciókat kínálnak, és általában nem kompatibilisek egymással. Például a GNU Make számára szkriptek nem működnek a BSD Make alatt.
Ezt követően megjelentek más eszközök, amelyek lehetővé tették a make által használt konfigurációs fájlok (Makefile) automatikus előállítását. Ezek az eszközök lehetővé teszik a függőségek ( automake ) vagy a rendszer konfigurációjának ( autoconf ) elemzését komplex Makefiles létrehozásához, és kifejezetten ahhoz a környezethez igazítva, amelyben a fordítási műveleteket végrehajtják.
A Make azóta számos különféle összeállítás-kezelő szoftvert inspirált, amelyek bizonyos platformokra jellemzőek ( rake , hangya ), vagy olyan generalista, mint a Ninja a 2010-es években.
2003-ban a D r Feldman megkapta az ACM árát a márka fejlesztéséért.
A fordítási folyamat elemi szabályokra van bontva, például: "Az A cél B-től és C-től függ. Az A gyártásához egy adott parancssorozatot kell végrehajtania" . Ezeket a szabályokat egy Makefile nevű fájlba helyezzük. A parancsok a fordítás , a linkek szerkesztése , a kód létrehozása elemi műveleteiből állnak .
A függőségek megegyeznek a fájlokkal, ezek lehetnek forrásfájlok , vagy az összeállítási folyamat közbenső eredményei. A cél általában fájl, de lehet absztrakt is.
Az A felépítését a parancs hajtja végre:
make AEzután a Make ellenőrzi, hogy a B és C fájlok rendelkezésre állnak-e és naprakészek-e, vagyis a létrehozásuk után nincsenek megváltoztatva a függőségeik, és a Másképpen készítés a B és C rekurzív felépítésével indul. A létrehozási parancsai, amint nem létezik ilyen nevű fájl, vagy az A fájl régebbi, mint B vagy C.
Szokás egy egész célt használni, amely összefoglalja a teljes projektet, ennek az elvont célnak függősége van az összes építendő fájlra. Más célok általános használatban vannak: telepítés a projekt telepítési parancsainak futtatásához, tiszta az összes előállított fájl törléséhez.
A Make lehetővé teszi a fájlnévnek megfelelő vagy implicit, a fájlmintáknak megfelelő függőségi szabályok használatát; Például bármely .o kiterjesztésű fájlt össze lehet állítani egy .c kiterjesztésű azonos nevű fájlból egy fordítási parancs segítségével.
A Make függőségfaként reprezentálja a projektet , és a program egyes változatai lehetővé teszik több célpont párhuzamos felépítését , ha nincsenek függőségek közöttük.
Tegye a kereséseket a használni kívánt makefile aktuális könyvtárába . Például a GNU kereséseket végez egy GNUmakefile , makefile , Makefile érdekében , majd végrehajtja a megadott (vagy alapértelmezett) célokat csak az adott fájlhoz.
A makefile-ben használt nyelv deklaratív programozás . Az imperatív programozástól eltérően ez azt jelenti, hogy az utasítások végrehajtásának sorrendje nem számít.
A makefile szabályokból áll . A szabály legegyszerűbb formája:
cible [cible ...]: [composant ...] [tabulation] commande 1 . . . [tabulation] commande nA „cél” leggyakrabban felépítendő fájl, de meghatározhat egy műveletet is (törlés, fordítás stb.). A „komponensek” a szabály által meghatározott művelet végrehajtásához szükséges előfeltételek. Más szavakkal, az "összetevők" azoknak a szabályoknak a célpontjai, amelyeket teljesíteni kell, mielőtt ez a szabály teljesülhetne. A szabály egy műveletet "parancsok" sorozatával határoz meg. Ezek a parancsok meghatározzák, hogyan kell használni az összetevőket a cél előállításához. Minden parancsot tabulátorral kell megelőzni.
A parancsokat külön héj vagy parancssori tolmács hajtja végre .
Íme egy példa egy makefile-re:
all: cible1 cible2 echo ''all : ok'' cible1: echo ''cible1 : ok'' cible2: echo ''cible2 : ok''Amikor ezt a makefile- t a make all paranccsal vagy a make paranccsal hajtják végre, az 'all' szabály végrehajtásra kerül. Megköveteli a „target1” és a „target2” komponensek létrehozását, amelyek a „target1” és a „target2” szabályokkal társulnak. Ezek a szabályok tehát automatikusan végrehajtásra kerül , mielőtt a „minden” szabályt. Másrészt a make target1 parancs csak a 'target1' szabályt hajtja végre.
A szabályok végrehajtásának sorrendjének feloldása érdekében használjon topológiai rendezést .
Vegye figyelembe, hogy egy szabály nem feltétlenül tartalmaz parancsot.
Az összetevők nem mindig célpontjai más szabályoknak, a célfájl összeállításához szükséges fájlok is lehetnek:
sortie.txt: fichier1.txt fichier2.txt cat fichier1.txt fichier2.txt > sortie.txtA fenti példa-szabály az output.txt fájlt a fájl1.txt és a fájl2.txt fájlok felhasználásával állítja össze. A makefile futtatásakor ellenőrizze, hogy létezik-e az output.txt fájl, és ha nem, akkor a szabályban megadott paranccsal felépíti.
A parancssorok a következő három előtag közül egyet vagy többet tartalmazhatnak:
Ha több célhoz ugyanazok az összetevők szükségesek, és ugyanazok a parancsok építik őket, akkor több szabály is meghatározható. Például :
all: cible1 cible2 cible1: texte1.txt echo texte1.txt cible2: texte1.txt echo texte1.txthelyébe a következő léphet:
all: cible1 cible2 cible1 cible2: texte1.txt echo texte1.txtVegye figyelembe, hogy az összes cél kötelező, különben csak a target1 cél kerül végrehajtásra.
Az érintett cél megismeréséhez használhatja például a $ @ változót :
all: cible1.txt cible2.txt cible1.txt cible2.txt: texte1.txt cat texte1.txt > $@két fájlt hoz létre, a target1.txt és a target2.txt fájlokat, ugyanazzal a tartalommal, mint a text1.txt .
A makefile makródefiníciókat tartalmazhat . A makrókat hagyományosan nagybetűvel határozzák meg:
MACRO = definitionA makrókat leggyakrabban akkor hívják változónak, amikor csak egyszerű karakterlánc- definíciókat tartalmaznak , például CC = gcc . A környezeti változók makróként is elérhetők. A makefájl makrói felülírhatók az elkészített argumentumokkal. A parancs ekkor:
make MACRO="valeur" [MACRO="valeur" ...] CIBLE [CIBLE ...]A makrók shell parancsokból állhatnak a grave akcentussal ( `):
DATE = ` date `Készítenek „belső makrókat” is:
A makrók lehetővé teszik a felhasználók számára, hogy megadják, mely programokat használják, vagy bizonyos egyéni beállításokat a készítés során. Például a CC makrót gyakran használják a makefile-ekben, hogy megadják a használni kívánt C fordítót .
A makró használatához ki kell bővítenie, ha $ () -ba foglalja . Például a CC makró használatához be kell írnia a $ (CC) szót . Vegye figyelembe, hogy a $ {} is használható . Például :
NOUVELLE_MACRO = $(MACRO)-${MACRO2}Ez a sor létrehoz egy új makrót: NOUVELLE_MACRO , kivonva a MACRO2 tartalmát a MACRO tartalmából .
A megbízás típusaiA makró meghatározásának számos módja van:
Ezek a szabályok lehetővé teszik makefájlok létrehozását egy fájltípushoz. Kétféle utótag-szabály létezik: páros és egyes.
A kettős utótag szabályt két utótag határozza meg: egy cél és egy forrás utótag . Ez a szabály minden „cél” típusú fájlt felismer. Például, ha a cél utótag „.txt”, a forrás utótag pedig „.html”, a szabály megegyezik a „% .txt:% .html” kifejezéssel (ahol a% bármilyen fájlnevet jelent). Egy egyszerű utótagszabályhoz csak forrás utótagra van szükség.
A kettős utótag szabály meghatározásának szintaxisa :
.suffixe_source.suffixe_cible :Felhívjuk figyelmét, hogy az utótagszabály nem tartalmazhat további összetevőket.
Az utótaglista meghatározásának szintaxisa:
.SUFFIXES: .suffixe_source .suffixe_ciblePélda az utótag szabályok használatára:
.SUFFIXES: .txt .html # transforme .html en .txt .html.txt: lynx -dump $< > $@A következő parancs fogja átalakítani a file.html fájlt be file.txt :
make -n fichier.txtAz utótag szabályok használatát elavultnak tekintik, mert túl korlátozó.
Íme egy példa a Makefile-re:
# Indiquer quel compilateur est à utiliser CC ?= gcc # Spécifier les options du compilateur CFLAGS ?= -g LDFLAGS ?= -L/usr/openwin/lib LDLIBS ?= -lX11 -lXext # Reconnaître les extensions de nom de fichier *.c et *.o comme suffixes SUFFIXES ?= .c .o .SUFFIXES: $(SUFFIXES) . # Nom de l'exécutable PROG = life # Liste de fichiers objets nécessaires pour le programme final OBJS = main.o window.o Board.o Life.o BoundedBoard.o all: $(PROG) # Étape de compilation et d'éditions de liens # ATTENTION, les lignes suivantes contenant "$(CC)" commencent par un caractère TABULATION et non pas des espaces $(PROG): $(OBJS) $(CC) $(CFLAGS) $(LDFLAGS) $(LDLIBS) -o $(PROG) $(OBJS) .c.o: $(CC) $(CFLAGS) -c $*.cEbben a példában .c.oegy implicit szabály. Alapértelmezés szerint a célállományok fájlok, de amikor két utótag áll egymás mellé, akkor ez egy olyan szabály, amely a második utótaggal végződő fájlokat egy azonos nevű, de az első utótaggal végződő fájlból vezeti le.
A cél eléréséhez végre kell hajtania a műveletet, a parancsot $(CC) $(CFLAGS) -c $*.c, ahol $*a fájl neve utótag nélkül szerepel.
Másrészt allegy cél, amely függ $(PROG)(és ezért lifeami egy fájl).
$(PROG)- vagyis life- egy cél, amely függ $(OBJS)(és ezért fájloktól main.o window.o Board.o Life.oés BoundedBoard.o). Ennek eléréséhez makefuttassa a parancsot $(CC) $(CFLAGS) $(LDFLAGS) $(LDLIBS) -o $(PROG) $(OBJS).
A szintaxis CC ?= gcc, vagy általánosabban <variable> ?= <valeur>, csak akkor hat <valeur>, <variable>ha <variable>még nincs inicializálva. Ha <variable>már tartalmaz értéket, akkor ennek az utasításnak nincs hatása.
A gyártás korlátai közvetlenül az azt népszerűsítő fogalmak egyszerűségéből fakadnak: fájlok és dátumok. Ezek a kritériumok valójában nem elégségesek a hatékonyság és a megbízhatóság garantálásához.
A fájlokkal társított dátumfeltétel önmagában egyesíti a két hibát. Hacsak a fájl nem egyszer írható adathordozón található, nincs biztosíték arra, hogy a fájl dátuma valóban az utolsó módosítás dátuma.
Ha egy nem privilegizált felhasználó esetében biztosak vagyunk abban, hogy az adatok nem lehetnek későbbiek, mint a feltüntetett dátum, akkor nem garantálható az elõzmények pontos dátuma.
Így a fájl dátumának legkisebb változásánál egy teljes produkció szükségesnek tekinthető, ha forrás, de még rosszabbnak tekinthető haszontalannak, ha éppen ellenkezőleg, célpont.
Ha a dátum és az akták továbbra is alapvetően szükségesek bármelyik megbízható és optimális gyártási motorhoz, akkor sem elegendőek, és néhány konkrét példa elegendő ennek szemléltetésére:
A gyártás másik korlátja, hogy nem generálja a függőségek listáját, és nem tudja ellenőrizni, hogy a mellékelt lista helyes-e. Így az előző, szabályon alapuló egyszerű példa .c.otéves: az objektumfájlok nem csak a .ctársított forrásfájloktól függenek , hanem a projekt összes fájljától is, amelyet a fájl tartalmaz .c. A függőségek reálisabb felsorolása a következő lenne:
$(PROG): $(OBJS) $(CC) $(CFLAGS) $(LDFLAGS) $(LDLIBS) -o $(PROG) $(OBJS) main.o: main.c Board.h BoundedBoard.h Life.h global.h $(CC) $(CFLAGS) -c main.c window.o: window.c window.h global.h $(CC) $(CFLAGS) -c window.c Board.o: Board.c Board.h window.h global.h $(CC) $(CFLAGS) -c Board.c Life.o: Life.c Life.h global.h $(CC) $(CFLAGS) -c Life.c BoundedBoard.o: BoundedBoard.c BoundedBoard.h Board.h global.h $(CC) $(CFLAGS) -c BoundedBoard.cIndokolt feltételezni, hogy a mellékelt rendszerfájlok (as stdio.h) nem változnak, és nem függőségként kell felsorolni őket. A függőségek dinamikus listáinak előállítására képes elemzők megírása árán a verzió egyes verziói megoldják ezt a problémát.
Ezen okok miatt specializálódnak az új generációs gyártói motorok bizonyos nyelvek feldolgozására (a fájlok tartalmának szemantikája), vagy olyan adatbázishoz is kapcsolódnak, amelyben az összes tényleges gyártási jellemzőt rögzítik ( a gyártás ellenőrzése ). célok (nyomon követhetőség).
Számos alternatíva létezik: