Poiché la questione è circa la scrittura di codice riutilizzabile in Makefiles, ti darò un esempio di come utilizzare le regole del modello in GNU Make (sembra come quello che stai usando dato che menzioni la destinazione .PHONY
). Tuttavia, se non si sta usando qualsiasi controllo delle dipendenze di marca, può essere più semplice di fare questo con uno script di shell - qualcosa come:
#!/bin/sh
TASKS="task01 task02 task03"
for i in $TASKS; do
rm $i $i.ext $i.o -f;
compiler $i.ext -O2 --make;
./$i;
done
Ma, per espandere il principio di fare, abbiamo un altro problema affrontare. Linee di forma:
task01-all: task01-clean task01 task01-run
non dicono Fai in quale ordine di costruire i pre-requisiti - solo che tutti hanno bisogno di essere fatto prima di task01-all
ottiene costruito. Invece, ogni passo da eseguire dovrebbe dipendere dal passo precedente. Qualcosa di simile a questo:
TASKS=task01-run task02-run task03-run
.PHONY: all $(TASKS) $(TASKS:run=clean)
all: $(TASKS)
$(TASKS:run=clean): %-clean:
rm $* $*.ext $*.o -f
%: %.ext | %-clean
compiler $< -O2 --make
$(TASKS): %-run: %
./$<
Le regole con %
sono chiamate "regole" del modello, e sono un ottimo strumento per evitare di ri-scrivere la stessa regola più volte per diversi target. Un avvertimento è che Make normalmente non controlla le regole del modello per un target .PHONY
; diciamo Fai di fare questo esplicitamente prefiggendo quelle regole con l'elenco di obiettivi e un secondo due punti (ad esempio, $(TASKS):
).
Dal task01-run
esigenze task01
al fine di lavorare, facciamo %-run
obiettivi dipendono %
. Inoltre, il tuo Makefile mostra che vuoi eseguire la pulizia ogni volta, quindi facciamo %
dipendente da %-clean
. Dal momento che lo %-clean
in realtà non produce alcun output, creiamo una dipendenza "solo ordine" - Make non cercherà un time stamp o altro, verrà semplicemente eseguita la regola %-clean
per prima cosa ogni volta che è necessario eseguire lo %
regola. "Ordine solo" dipendenze sono posti dopo un |
:
%: %.ext | %-clean
vale la pena ricordare che uno dei più grandi punti di forza di fare è che si può risparmiare tempo evitando di ripetere il lavoro che non ha bisogno di essere ripetuto - cioè, esegue una regola solo se le dipendenze sono più recenti della destinazione.Quindi, si potrebbe lasciare fuori la dipendenza %-clean
, che causerebbe far correre solo compiler $< -O2 --make
se %.ext
è più recente rispetto %
:
%: %.ext
compiler $< -O2 --make
È quindi possibile aggiungere una regola solo per eseguire tutte le %-clean
obiettivi:
.PHONY: all $(TASKS) $(TASKS:run=clean) clean
clean: $(TASKS:run=clean)
Ultima cosa: utilizzo alcune variabili speciali nelle ricette. [email protected]
indica l'obiettivo in fase di costruzione. $<
indica la prima dipendenza. $*
indica la "radice" di una regola del modello (ad esempio, la parte corrispondente allo %
).
Belle spiegazioni. Grazie! –
Fornire un esempio per "|" è stato bello, grazie. –