Utilitarul make este utilizat pentru a determina dependentele dintre modulele unui program si de a genera comenzi de recompilare. Spre exemplu, daca am compilat fisierele server.c, sock.c si handle.c si modificam fisierul handle.c, utilitarul isi va da seama de acest lucru si va recompila numai handle.c pentru obtinerea noului executabil.
Inca de la aparitia lui, make a devenit un standard de facto in lumea Unix; in ciuda mai multor deficiente, el este inca folosit pe scara larga, mai ales datorita altor tool-uri din proiectul GNU: autoconf, automake.
La baza utilitarului sta un fisier makefile care contine reguli de compilare. Desi sunt recunoscute implicit mai multe nume (Makefile, GNUMakefile si makefile - pentru GNU make, versiunea cea mai utilizata), se prefera folosirea Makefile, deoarece apare proeminent la listarea continutului unui director.
Un fisier Makefile este format din reguli si definiri; o regula este, la randul ei formata dintr-o linie de dependente si 0 sau mai multe actiuni (comenzi). Pentru o mai buna intelegere a acestora vom utiliza urmatorul exemplu:
# # exemplu Makefile # CC = gcc # compilatorul folosit CFLAGS = -Wall -pedantic -ansi # optiunile pentru compilare LDFLAGS = -lefence # optiunile pentru linking # creeaza executabilele client si server all: client server # leaga modulele client.o user.o sock.o in executabilul client client: client.o user.o sock.o log.o $(CC) $(LDFLAGS) -o $@ $^ # leaga modulele server.o cli_handler.o sock.o in executabilul server server: server.o cli_handler.o sock.o log.o $(CC) $(LDFLAGS) -o $@ $^ # compileaza fisierul client.c in modulul obiect client.o client.o: client.c sock.h user.h log.h $(CC) $(CFLAGS) -c $< # compileaza fisierul user.c in modulul obiect user.o user.o: user.c user.h $(CC) $(CFLAGS) -c $< # compileaza fisierul sock.c in modulul obiect sock.o sock.o: sock.c sock.h $(CC) $(CFLAGS) -c $< # compileaza fisierul server.c in modulul obiect server.o server.o: server.c cli_handler.h sock.h log.h $(CC) $(CFLAGS) -c $< # compileaza fisierul cli_handler.c in modulul obiect cli_handler.o cli_handler.o: cli_handler.c cli_handler.h $(CC) $(CFLAGS) -c $< # compileaza fisierul log.c in modulul obiect log.o log.o: log.c log.h $(CC) $(CFLAGS) -c $< clean: rm -fr *~ *.o server client
Pe acest exemplu, vom descrie in detaliu structura unui fisier Makefile.
Comentariile intr-un fisier Makefile incep de la caracterul # si dureaza pana la sfasitul liniei.
Dupa liniile cu comentariu urmeaza trei linii de definire; aici se specifica compilatorul (definit in variabila CC), optiunile pentru compilare (CFLAGS) si cele pentru linking (LDFLAGS). Compilatorul folosit este gcc, optiunile sunt -Wall -pedantic -ansi, iar pentru legare folosim biblioteca libefence. Electric Fence este un utilitar care ajuta la prevenirea erorilor de alocare sau eliberare a zonelor de memorie; intrucat este usor de folosit (trebuie doar legat la executabil), se recomanda folosirea lui.
Ceea ce urmeaza acum sunt regulile. Regulile au o sintaxa de forma:
TARGET: PREREQUISITES COMMANDS
TARGET este in general numele unui fisier (executabil, obiect) care se doreste obtinut. PREREQUISITES sunt fisiere care sunt necesare pentru obtinerea fisierului specificat de target. COMMAND este comanda (comenzile) executate de make pentru obtinerea fisierului indicat de TARGET. IMPORTANT: fiecare comanda incepe cu caracterul TAB.
In lipsa specificarii unei tinte la rularea make, se va considera prima regula intalnita. De aceea se obisnuieste folosirea unui ``phony target'' cu numele all ca prima regula; acesta va avea ca dependente executabilele ce se doresc obtinute. Obtinerea executabilului client necesita existenta modulelor obiect client.o, sock.o, user.o, log.o; actiunea necesara pentru obtinerea executabilului este legarea acestor module. Linia
Pentru obtinerea modulelor obiect, sintaxa este aceeasi: TARGET este numele fisierul obiect iar PREREQUISITES contine fisierul sursa care va fi compilat si fisierele header folosite. Comanda
Daca la un moment de timp, se va modifica fisierul user.c, atunci pasii urmati de make vor fi urmatorii (la rularea comenzii $ make):
Fisierul Makefile in forma simplificata va fi asadar:
# # exemplu Makefile - forma uzuala (simplificata) # CFLAGS = -Wall -pedantic -ansi LDFLAGS = -lefence all: client server client: client.o sock.o user.o log.o $(CC) $(LDFLAGS) -o $@ $^ server: server.o sock.o cli_handler.o log.o $(CC) $(LDFLAGS) -o $@ $^ client.o: sock.h user.h log.h user.o: user.h sock.o: sock.h log.o: log.h server.o: sock.h cli_handler.h log.h cli_handler.o: cli_handler.h clean: rm -fr *~ *.o client server
Informatii exhaustive despre utilitarul make gasiti accesand paginile de documentatie info