| Tipus | utilitat UNIX,llenguatge script,llenguatge de regles fora de joc,sistema de construcció illenguatge de programació |
|---|---|
| Versió inicial | abril 1976 |
| Característiques tècniques | |
| Sistema operatiu | Unix |
| Escrit en | C |
| Format de fitxer d'escriptura | |
| Equip | |
| Desenvolupador(s) | Stuart Feldman |
| Dissenyador | Stuart Feldman |
| Més informació | |
| Stack Exchange | Etiqueta |
| Free Software Directory | Make |
Make és una programa informàtic que automatitza lacompilació de programes i biblioteques a partir del seucodi font.Make llegeix uns fitxers anomenatsmakefiles que especifiquen quins passos s'han de seguir per a compilar i en quin ordre s'han de compilar els fitxers. Tot i que es poden fer servir elsentorns integrats de desenvolupament per a manejar el procés de construcció de programari,make encara és molt utilitzat, especialment en entornsUnix.
Creat el 1977 perStuart Feldman en elsLaboratoris Bell, es va començar a distribuir en entorna Unix, juntament amb altres eines dedicades al desenvolupament de programari, amb la versió 1.0 dePWB/UNIX. A partir d'aleshores, make ha esdevingut una de les eines de compilació automàtica més utilitzades fins al punt que el2003 laACM va atorgar un premi al Dr. Felman per aquesta eina.[1]
Abans de la introducció de make, el sistema de compilació de programari més comú era el de distribuir unshell script per a cada sistema operatiu diferent a on s'hagués de compilar el programa. Make va fer un pas molt important cap a entorns de compilació moderns al poder combinar les ordres pels diferents sistemes operatius així com un mètode per poder seguir les dependències tot en un sol fitxer.
Per norma general, el make s'utilitza per acompilar programes i biblioteques binàries a partir del seu codi font. Tanmateix, make es pot fer servir per a qualsevol procés que necessiti convertir fitxers basats en dependències executant un nombre arbitrari d'ordres. Per exemple, es podria fer servir make per detectar qualsevol canvi en un fitxer imatge (la dependència) i les ordres a executar podrien convertir aquesta imatge en un altre format, copiar el resultat en unsistema de gestió de continguts i enviar un correu a un conjunt de destinataris que s'han realitzat totes aquestes operacions.
Amb el pas del temps, s'han reescrit diverses variants del make que utilitzen el mateix format pelsmakefiles i segueixen el mateixalgorisme bàsic, però que afegeixen un nombre de millores no estàndards pròpies. Algunes d'aquestes variants són:
name deMicrosoft, utilitzat en sistemesWindows. És una versió força bàsica i només conté unsubconjunt de les característiques de les versions explicades més amunt. No s'ha de confondre elnmake de Microsof amb el deAT&T i el de Laboratoris Bell per Unix.
L'estàndardPOSIX inclou una estandardització de les característiques i operacions bàsiques del make i la majoria de les implementacions per Unix el segueixen força completament. En general, la majoria del makefiles simples es poden fer servir sense diferències entre les diferents variants del make. El make de GNU i el del BSD es poden configurar de manera que primer busquin fitxers anomenatsGNUmakefile iBSDmakefile respectivament,[2][3] de manera que és possible fer servir makefiles que utilitzin detalls d'una implementació concreta en diferents llocs.
Make ordena la llista de dependències pels fitxers a compilar, com ara quines capçaleres contribueixen a la compilació d'un fitxer objecte. Això manté el make com una eina general i útil per a qualsevol tipus de fitxer, però també augmenta la possibilitat d'error humà. Una dependència de més o que s'hagi oblidat pot no ser òbvia a primera vista i donar com a resultat errades de programari difícils de trobar. És possible escriure makefiles que generin les dependències de manera automàtica utilitzant eines externes, i alguns generadors de makefiles, com araGNU Automake, per defecte ho fan així.
Un altre problema que make no maneja molt bé és la diferència de paràmetres que hi poden haver entre les eines de diversos sistemes. Per exemple, el compilador d'una plataforma pot no acceptar els paràmetres del compilador d'una altra. Aquest problema generalment es deixa en mans de processos que generen les instruccions necessàries per a cada plataforma. Eines comuns per a aquesta feina són elAutoconf i elCmake, que generen un shell script anomenatconfigure que l'usuari ha d'executar abans de començar el procés de compilació.
Make decideix si un fitxer de sortida s'ha de regenerar o no comparant l'hora de modificació del fitxer de sortida i les seves dependències. Tot i que aquesta solució és simple, no funciona quan un fitxer canvia però la seva hora de modificació no. Canvis d'aquest estil són freqüents quan s'utilitza programari decontrol de versions o quan el codi font es troba en un sistema d'arxius en xarxa els rellotges del sistemes no està sincronitzat. En aquests casos, l'usuari es veu forçat a recompilar-ho tot.
Les ordres dels makefiles s'executen dins d'unashell. Com que els diferentssistemes operatius utilitzen diferents shells això significa que alguns makefiles poden no ser portables. Per exemple, el make de GNU executa les ordres a través debash i pot executar eines d'Unix com elcp. En canvi, el nmake de Microsoft executa les ordre en a través del cmd.exe i, per tant, s'han de fer servir ordres debatch comCOPY.
La sintaxi utilitzada pel make utilitza de manera diferent el caràcter deltabulador i el d'espai de manera diferent. Això és problemàtic perquè per norma general no hi ha cap diferència visual entre els dos caràcters i sovint es critica la sintaxi del make per culpa d'això. Pels programadors que utilitzen generadors de makefiles o editors de text amb suport per a makefiles, aquest problema és menys greu.
El llenguatge de make s'assembla molt a laprogramació declarativa.[4][5] Aquest tipus de llenguatges, en què es declaren els objectius però l'ordre de les accions no és tan important, provoca a vegades confusió entre els programadors acostumats allenguatges imperatius.
Un makefile consisteix enlínies de dependències a on es defineix un objectiu (una regla) seguida per dos punts i de manera opcional els conjunt de fitxers del que depèn. Lalínia de dependències s'escriu de manera que a la part esquerra del caràcter: hi ha l'objectiu a compilar i a la dreta del: hi ha les seves dependències.
Després de cada línia de dependències poden haver-hi una sèrie de línies sagnades amb el caràctertab que indiquen quines ordres s'han d'executar per transformar les dependències a l'objectiu. Si qualsevol de les dependències s'ha modificat, s'executen totes les ordres aquí llistades. L'estructura bàsica és:
# Els comentaris comencen amb el caràcter de sostingut (#)objectiu[objectiu…]:[dependència…][<TAB>ordre1]...[<TAB>ordren]
Nota: Generalment els objectiu s'escriuen en línies separades i les línies d'ordres són opcionals. La llista de dependències pot consistir únicament en altres objectius que s'han de compilar com ara:
realclean:cleandisclean
Les ordres generalment s'escriuen de manera que generen l'objectiu. Per exemple, si el fitxer "fitxer.html" és més nou que el fitxer de text a convertir, es pot escriure el següent makefile:
fitxer.txt:fitxer.htmllynx-dumpfitxer.html>fitxer.txt
Aquesta regla s'executa invocant el make amb el nom de l'objectiu:
makefitxer.txt
Un makefile també pot contenir definicions de macros i algunes ordres poden incloure altres makefiles. Les macros definides en els makefiles es poden anul·lar en els arguments que es passen en executar el make. Això permet als usuaris especificar diferents comportaments a l'hora de compilar o executar determinats programes. Un exemple és la macro "CC" que s'utilitza molt sovint en makefiles per definir la ruta al compilador deC i l'usuari podria voler fer servir un compilador alternatiu sota alguns casos. Un exemple del make de GNU:
# Makefile pel make de GNU # Aquest fragment atura als make(1) que no siguin de GNU i que # no entendrien totes les ordres. ifneq (,)AquestmakefilenecessitaelmakedeGNU. endif include makefile/environment.mk include makefile/common.mk # Defineix macros. En aquest case són "variables simples que no s'expandeixen" # Es poden canviar per la línia d'ordresCC=gccCFLAGS=-Wall-pedantic-gall:echo"Res a fer"
all.makeOBJECTIU[OBJECTIU...]
make CC=gcc all, aleshores s'anomenen "variables". La sintaxi genèrica és:makeMACRO="valor"[MACRO="valor"...]OBJECTIU[OBJECTIU...]
Les variables de la shell que formen part de l'entorn també es troben disponibles com a macros (o "variables") i tradicionalment s'escriuen tot en majúscules:
MACRO=definició
Quan s'expandeixen les macros per obtenir-ne el seu valor, generalment s'escriuen entre(). Tot i que també és possible escriure-les entre{}, generalment no es fa.
NOVA_MACRO=$(MACRO)-$(MACRO2)
Els valor de les macros també pot ser el resultat d'executar una ordre ja sigui utilitzant operadors desubstitució d'ordres o l'accent greu``.
YYYYMMDD=`date`
Aquest valor es guarda tal com apareix a la sortida de la comanda i només s'expandeix quan s'utilitza la macro en una línia d'ordre d'un objectiu. Per exemple:
PACKAGE=packageVERSION=`date+"%Y.%m%d"`ARCHIVE=$(PACKAGE)-$(VERSION)dist: # Fixa't com només les macro s'expandeixen per a ser interpretades per la shell: # tar -cf package-`date +"%Y%m%d"`.tartar-zcf$(ARCHIVE).tar.
Cada ordre que segueix la línia de dependències han d'estar sagnades amb un caràcter de tabulació.
objectiu:dependència<TAB>ordre
Cada ordre s'executa en una shell independent i ha d'estar escrita en una única file. Es poden concatenar ordres indicant-t'ho amb una barra invertida\ al final de cada línia.
objectiu:dependència\dependència<TAB>ordre;\<TAB>ordre|\<TAB>ordre-enllaçada
Les ordres es poden prefixar amb els següents tres caràcters: un guió ("-") per indicar que s'ignoren els errors de la comanda, una arrova ("@") per no escriure l'ordre per pantalla abans d'executar-la, o un signe de suma ("+") per executar la comanda encar que make s'executi en mode "no executis". De manera alternativa, es poden ignorar errors i amagar les ordres a executar amb els objectius especials .IGNORE i .SILENT.[6]
El makefiles també poden accedr amacros internes.
objectiu:dependència1dependència2echo$?# conté les dependències modificades més recentment que objectiuecho$@# conté el nom del objectiu
Es poden escriure regles de sufix a l'estilFROM.TO i es poden fer servir per executar ordres basant-se en l'extensió dels fitxers. En les regles de sufix, la macro interna$< es refereix a la dependència i la macro$@ a l'objectiu. Com a exemple es podria crear una regla de sufix per a convertir tots els fitxers HTML a fitxers de text. Fixa't també en el caràcter de redirecció al mig de l'ordre:
.SUFFIXES:.txt.html # De .html a .txt.html.txt:lynx-dump$<>$@
Quan s'executa el make, l'exemple anterior s'expandeix a:
$make-nfitxer.txtlynx-dumpfitxer.html>fitxer.txt
Els makefiles s'utilitzen generalment per a compilar codi (*.c, *.cc, *.C, etc.), però també es poden fer servir per a automatitzar tasques comunes. Al cridar un d'aquests makefiles des de l'intèrpret d'ordres:
make# Sense cap paràmetre s'executa el primer objectiumakehelp# Mostra tots els objectiusmakedist# Crea un fitxer comprimit amb el contingut del directory
The makefile:
PACKAGE=packageVERSION=`date"+%Y.%m%d%"`RELEASE_DIR=..RELEASE_FILE=$(PACKAGE)-$(VERSION) # Fixa't que la variable LOGNAME prové de l'entorn # de les shells de POSIX. # # objectiu: all - Objectiu per defecte. No fa res.all:echo"Hola$(LOGNAME), per defecte no es fa res"echo"Prova amb 'make help'" # objectiu: help - Mostra els objectius.help:egrep"^# objectiu:"[Mm]akefile # objectiu: llistar - Llista el fitxers de codi fontllistar: # Això no funciona perquè cada ordre d'executa en un shell diferent.cdsrcls # Això sí perquè es continua l'ordre dins de la mateixa shell.cdsrc;\ls # objectiu: dist - Crear un fitxer comprimit amb el contingut del directori.dist:tar-cf$(RELEASE_DIR)/$(RELEASE_FILE)&&\gzip-9$(RELEASE_DIR)/$(RELEASE_FILE).tar
A sota hi ha un makefile molt simple que compila un codi font anomentar "holamon.c" utilitzant elgcc, un compilador, i també especifica un objectiu anomenat "clean" que esborra els fitxers generats. L'objectiu .PHONY és una manera d'inicar a make que un objectiu en particular no és el nom d'un fitxer a generar.
CC=gccCFLAGS=-gall:holamonholamon:holamon.o$(CC)$(LDFLAGS)-o$@$^holamon.o:holamon.c$(CC)$(CFLAGS)-c-o$@$<clean:rm-fholamonholamon.o # Aquesta és una extensió del make de GNU que significa que 'clean' no és un # nom de fitxer i, per tant, no ha de comprovar-ne cap hora de modificació..PHONY:clean