A volte, i file sorgente da compilare sono tanti ed è sconveniente, per chi compila da terminale, scrivere ogni volta il comando g++ seguito da tutti i nomi delle sorgenti...
I makefile servono proprio a questo, sono dei file speciali che consentono, tramite la sola chiamata al comando (make appunto) di compilare tutti i file sorgenti che vogliamo. Ma com'è composto un makefile? Un makefile semplice in genere contiene 3 parti:- Commenti
- Macro
- Dipendenze e comandi
Le Macro sono dei contenitori aventi un nome e servono a dare più leggibilità e modularità al makefile.Le Macro vanno assegnate, un pò come le variabili, indicando il nome (in genere si usa scriverlo in maiuscolo) il segno d'uguaglianza e le istruzioni che deve contenere.
Per poter richiamare le Macro dichiarate in precedenza, bisogna usare il simbolo $ seguito da (NomeMacro) o anche ${NomeMacro}, in questo modo viene chiamato il contenuto assegnato precedentemente alla macro (tutto ciò che abbiamo messo dopo il segno di uguaglianza).
Esempio:
#Macro
CC=gcc #indica che la macro CC contiene il nome del compilatore #usato, nel nostro caso gcc per c++.
Vi sono alcuni nomi di Macro usati per convenzione, tra di essi ricordiamo:
CC-contiene il nome del compilatore che usiamo
CFLAGS-contiene i parametri di compilazione
OBJ-contiene i file oggetto (.o)
La fase delle dipendenze e dei comandi è formata così:
target: dipendenze
(TAB)comando
Esempio di un MakeFile:
Abbiamo un gestore di una Banca avente i file:
main Banca.cpp Cliente.cpp ContoCorrente.cpp ContoCorrenteGold.cpp ContoCorrentePlatinum.cpp ContoCorrenteSilver.cpp ContoCorrenteStandard.cpp (e ovviamente tutti i .h relativi ai cpp).
In ogni file abbiamo scritto cosa importiamo, per esempio nel file ContoCorrenteGold avrà la sua dipendenza verso ContoCorrente. Ora creiamo il nostro makefile
- #Makefile per Banca
- #Macro
- BIN=banca
- CC=g++ #compilatore gcc per c++
- # File oggetto
- OBJS=main.o Banca.o Cliente.o ContoCorrente.o ContoCorrenteGold.o ContoCorrentePlatinum.o ContoCorrenteSilver.o ContoCorrenteStandard.o
- #Dipendenze e comandi
- #banca dipende da main.o Banca.o Cliente.o ContoCorrente.o #ContoCorrenteGold.o ContoCorrentePlatinum.o ContoCorrenteSilver.o #ContoCorrenteStandard.o
- $(BIN): $(OBJS)
- $(CC) -o $(BIN) $(OBJS)
- main.o: main.cpp ContoCorrenteStandard.h ContoCorrenteGold.h Cliente.h Banca.h
- $(CC) -c main.cpp
- Banca.o: Banca.h Banca.cpp ContoCorrenteStandard.h ContoCorrenteGold.h
- $(CC) -c Banca.cpp
- Cliente.o: Cliente.cpp Cliente.h
- $(CC) -c Cliente.cpp
- ContoCorrente.o: ContoCorrente.cpp ContoCorrente.h
- $(CC) -c ContoCorrente.cpp
- ContoCorrenteGold.o: ContoCorrenteGold.cpp ContoCorrenteGold.h ContoCorrente.h
- $(CC) -c ContoCorrenteGold.cpp
- ContoCorrenteSilver.o: ContoCorrenteSilver.cpp ContoCorrenteSilver.h ContoCorrente.h
- $(CC) -c ContoCorrenteSilver.cpp
- ContoCorrenteStandard.o: ContoCorrenteStandard.cpp ContoCorrenteStandard.h ContoCorrente.h
- $(CC) -c ContoCorrenteStandard.cpp
- ContoCorrentePlatinum.o: ContoCorrentePlatinum.cpp ContoCorrentePlatinum.h ContoCorrente.h
- $(CC) -c ContoCorrentePlatinum.cpp
Ora un pò di commenti:
In riga 7 dichiariamo la macro chiamata OBJS che conterrà i nostri file oggetto. In riga 13 diciamo che il file che vogliamo creare dipende da tutti i file oggetto ed eseguiamo nella riga successiva il comando classico per compilare (usando le macro stavolta). Le righe che seguono sono le altre dipendenze, necessarie se vogliamo che il nostro makefile sia ottimale anche per eventuali modifiche sui file .h e .cpp. La regola è semplice, ogni file oggetto dipende dal suo .h e dal suo .cpp ed eventualmente da altri file headers inclusi nel codice. Dopo ogni dichiarazione di dipendenza, va compilato (è sufficiente il cpp) tramite g++ -c nomeFile.cpp. I makefile consentono anche tante altre semplificazioni e peculiarità, che verranno discussi in seguito su altri post.
Foto post: DRUPAL
Questo è davvero una mano santa come articolo :D
RispondiEliminaGrazie! Con la scusa l'ho imparato pure io ahah xD
RispondiEliminafinalmente qualcosa di chiaro sull'argomento
RispondiElimina