GNU Make è un'utilità di sviluppo che determina le parti di una particolare base di codice che devono essere ricompilate e può inviare comandi per eseguire tali operazioni sulla base di codice. Questo particolare fare utility può essere utilizzata con qualsiasi linguaggio di programmazione a condizione che la loro compilazione possa essere effettuata dalla shell mediante l'emissione di comandi.
Per utilizzare GNU Make, abbiamo bisogno di un insieme di regole che definiscano la relazione tra i diversi file nel nostro programma e i comandi per aggiornare ogni file. Questi sono scritti su un file speciale chiamato 'makefile‘. Il 'fare' comando usa il 'makefile' database e gli orari di ultima modifica dei file per decidere quali file devono essere ricompilati di nuovo.
In genere 'makefile'contengono 5 tipi di cose vale a dire: regole implicite, regole esplicite, definizioni variabili, direttive, e Commenti.
Le informazioni che raccontano fare come ricompilare un sistema deriva dalla lettura di un database chiamato makefile. Un semplice makefile will consiste di regole della seguente sintassi:
obbiettivo...: prerequisiti... ricetta... ...
UN obbiettivo è definito come il file di output generato dal programma. Può essere anche obiettivi fasulli, che verrà spiegato di seguito. Esempi di file di destinazione includono eseguibili, file oggetto o obiettivi fasulli Piace pulire, installare, disinstallare eccetera.
UN prerequisito è un file utilizzato come input per creare i file di destinazione.
UN ricetta è l'azione che fare esegue per creare il file di destinazione in base ai prerequisiti. È necessario inserire il carattere di tabulazione prima di ogni ricetta all'interno del makefile a meno che non specifichiamo il '.RICETTA PREFISSO‘ variabile per definire qualche altro carattere come prefisso alla ricetta.
final: main.o end.o inter.o start.o gcc -o final main.o end.o inter.o start.o. main.o: main.c global.h gcc -c main.c. end.o: end.c local.h global.h gcc -c end.c. inter.o: inter.c global.h gcc -c inter.c. start.o: start.c global.h gcc -c start.c. clean: rm -f main.o end.o inter.o start.o
Nell'esempio sopra abbiamo usato 4 Do file sorgente e due file di intestazione per creare l'eseguibile finale. Qui ogni '.o' è sia un obiettivo che un prerequisito all'interno del makefile. Ora dai un'occhiata al nome dell'ultimo obiettivo pulire. È solo un'azione piuttosto che un file di destinazione.
Poiché normalmente non ne abbiamo bisogno durante la compilazione, non è scritto come prerequisito in nessun'altra regola. Vengono chiamati i target che non si riferiscono a file ma sono solo azioni obiettivi fasulli. Non avranno alcun prerequisito come altri file di destinazione.
Per impostazione predefinita fare inizia con il primo obiettivo nel 'makefile' ed è chiamato come 'obiettivo predefinito’. Considerando il nostro esempio, abbiamo finale come nostro primo obiettivo. Poiché i suoi prerequisiti includono altri file oggetto, questi devono essere aggiornati prima della creazione finale. Ciascuno di questi prerequisiti viene elaborato secondo le proprie regole.
La ricompilazione si verifica se vengono apportate modifiche a file sorgenti o file di intestazione o se il file oggetto non esiste affatto. Dopo aver ricompilato i file oggetto necessari, fare decide se ricollegare finaleo no. Questo deve essere fatto se il file finale non esiste o se uno dei file oggetto è più recente di esso.
Quindi se cambiamo il file inter.c, poi in esecuzione fare ricompilerà il file sorgente per aggiornare il file oggetto inter.o e poi link finale.
Nel nostro esempio, abbiamo dovuto elencare tutti i file oggetto due volte nella regola per finale come mostrato di seguito.
final: main.o end.o inter.o start.o gcc -o final main.o end.o inter.o start.o
Per evitare tali duplicazioni, possiamo introdurre variabili per memorizzare l'elenco dei file oggetto che vengono utilizzati all'interno del makefile. Usando la variabile OBJ possiamo riscrivere il campione makefile a uno simile mostrato di seguito.
OBJ = main.o end.o inter.o start.o. finale: $(OBJ) gcc -o finale $(OBJ) main.o: main.c global.h gcc -c main.c. end.o: end.c local.h global.h gcc -c end.c. inter.o: inter.c global.h gcc -c inter.c. start.o: start.c global.h gcc -c start.c. pulito: rm -f $(OBJ)
Come abbiamo visto nell'esempio makefile, possiamo definire regole per ripulire la directory di origine rimuovendo i file oggetto indesiderati dopo la compilazione. Supponiamo di avere un file di destinazione chiamato pulire. come si può fare differenziare le due situazioni precedenti? Ecco che nasce il concetto di obiettivi fasulli.
UN bersaglio fasullo è uno che non è proprio il nome di un file, ma è solo un nome per una ricetta da eseguire ogni volta che viene fatta una richiesta esplicita dal makefile. Uno dei motivi principali per usarlo bersaglio fasullo è quello di evitare un conflitto con un file con lo stesso nome. Un altro motivo è migliorare le prestazioni.
Per spiegare questa cosa, svelerò una svolta inaspettata. La ricetta per pulire non verrà eseguito per impostazione predefinita durante l'esecuzione fare. Occorre invece invocare lo stesso impartendo il comando rendere pulito.
.FALSO: pulito. pulito: rm -f $(OBJ)
Ora prova a creare makefile per la tua base di codice. Sentiti libero di commentare qui con i tuoi dubbi.