2012-11-29 22 views
7

Vorrei eseguire un'attività in più directory, ma fino ad ora non ho trovato una soluzione "simile al makefile". So che questa è una domanda frequente e so come risolverlo per i sub-makfile e così via, ma sto cercando qualcosa di più semplice.Iterazione di un elenco di directory in un Makefile

Invece di fare

copy: 
    cd module1 && mkdir foo 
    cd module2 && mkdir foo 
    cd module3 && mkdir foo 

Mi piacerebbe avere qualcosa di simile

directories = module1 module2 module3 

copy: $(directories) 
    cd $< && mkdir foo 

ma che non funziona, dal momento che la ricetta viene chiamato una sola volta con il primo elenco. Sono venuto con questa soluzione che funziona, ma probabilmente non è nello stile di Makefile:

directories = module1 module2 module3 

copy: 
    for d in $(directories); do cd $$d && mkdir foo && cd ..; done 

Come posso fare questo più bene?

risposta

6

Ci sono molti modi di fare questo.

È possibile fare ciò che Andrew suggerisce senza codificare un prefisso:

directories = module1 module2 module2 

%/foo: ; mkdir -p -- "[email protected]" 

copy: $(addsuffix /foo,$(directories)) 

che dà

$ make -n copy 
mkdir -p -- "module1/foo" 
mkdir -p -- "module2/foo" 
mkdir -p -- "module3/foo" 

Si può anche generare il target copy dal makefile:

directories = module1 module2 module2 

define copy-target 
    copy:: ; cd $1 && mkdir foo 
endef 

$(foreach dir,$(directories),$(eval $(call copy-target,$(dir)))) 

Questo dà:

$ make -n copy 
cd module1 && mkdir foo 
cd module2 && mkdir foo 
cd module3 && mkdir foo 

Si potrebbe anche generare i comandi, non il bersaglio:

directories = module1 module2 module2 

copy: ; $(foreach dir,$(directories),(cd $(dir) && mkdir foo) &&) : 

che si traduce in

$ make -n copy 
(cd module1 && mkdir foo) && (cd module2 && mkdir foo) && (cd module3 && mkdir foo) && : 
+0

Grazie, funziona. Ho scelto la soluzione 2 (generare il target 'copy' dal makefile) perché non è legato al caso' mkdir'. Sfortunatamente, non è molto diverso dall'usare una shell-per-loop, ma non importa. – Robert

2

In Makefile, ogni volta che si desidera creare un file, creare una regola con il nome del file come destinazione e fornire il comando per creare il file di destinazione.

copy: module1/foo module2/foo module3/foo 

module%/foo: 
     mkdir [email protected] 

Se vuoi parametrizzare che un po 'per evitare doppioni, si potrebbe anche scrivere qualcosa di simile

MODULE_NUMBERS = 1 2 3 

copy: ${MODULE_NUMBERS:%=module%/foo} 

module%/foo: 
     mkdir [email protected] 
+0

Grazie. Sfortunatamente, non posso applicare la tua soluzione perché non posso indirizzare le directory rilevanti usando un carattere jolly ("modulo%" nel tuo esempio) poiché ho molte directory con lo stesso prefisso e voglio usare una variabile ("directory" nel mio esempio) per selezionare solo alcuni di essi. BTW: Ho usato "mkdir" come un comando di esempio (in realtà, non voglio creare directory ma caricare file da ogni directory su un server), quindi la soluzione dovrebbe funzionare indipendentemente dall'attività in corso. – Robert

Problemi correlati