2015-01-08 17 views
7

Voglio rendere un target dipendente dalla lingua. In particolare: ho un file sorgente e voglio creare oggetti diversi da aggiungere alla cartella della lingua corrispondente. Quel singolo file sorgente sarà diverso nei C-Flags, il compilatore otterrà. Finché l'ho usato in modo statico, funziona abbastanza bene.Makefile GNU - La regola di pattern con più destinazioni con una dipendenza ignora tutti i target ma il primo

de/info.o en/info.o es/info.o : info.c 
    $(ECHO)  (DEP) $< for [email protected] 

Ora ho pensato, sarebbe bello se si è un po 'più dinamico, nel caso in cui io aggiungo un file di lingua seconda nuova. Così ho usato un jolly come segue:

de/%.o en/%.o es/%.o : %.c 
    $(ECHO)  (DEP) $< for [email protected] 

Ma ora è solo fare il primo obiettivo e ignora il resto. Il Make-debug stampa il seguente cosa:

Successfully remade target file `de/info.o'. 
Considering target file `en/info.o'. 
File `en/info.o' was considered already. 

Solo nel caso: No, non esistono gli oggetti. Quindi non esiste un obiettivo, ma una dipendenza esistente, quindi make dovrebbe eseguire le regole.

MODIFICA: ha trovato una soluzione per questo problema.

define FOO 

$(1)/%.o : %.c 
    $(ECHO)  $$< for $(1) 

endef 

$(foreach lang,$(LANGUAGE_LIST), $(eval $(call FOO,$(lang)))) 

Ispirato da: http://www.gnu.org/software/make/manual/make.html#Eval-Function

risposta

6

regole modello di lavoro diverso rispetto regole implicite. Mentre una regola implicita come

a b c: d 
     command 

è equivalente alla notazione più

a: d 
     command 
b: d 
     command 
c: d 
     command 

questo non vale per le regole del modello. Le regole del modello con più target sono esplicitamente richieste per creare tutte le delle loro destinazioni in una singola chiamata di command. Così si dovrebbe scrivere

$ cat GNUmakefile 
all: de/x.o en/x.o es/x.o 

de/%.o: %.c 
     @echo [email protected] from $< 
en/%.o: %.c 
     @echo [email protected] from $< 
es/%.o: %.c 
     @echo [email protected] from $< 
$ gmake 
de/x.o from x.c 
en/x.o from x.c 
es/x.o from x.c 

la documentazione richiesta sia trovato in 10.5.1 Introduzione al modello Regole del manuale GNU make:

regole modello può avere più di un bersaglio. A differenza delle normali regole, ciò non comporta tante regole diverse con gli stessi prerequisiti e la stessa ricetta. Se una regola del modello ha bersagli multipli, fai sapere che la ricetta della regola è responsabile della realizzazione di tutti i bersagli. La ricetta viene eseguita solo una volta per rendere tutti gli obiettivi. Quando si cerca una regola del modello per abbinare un bersaglio, i modelli di destinazione di una regola diversa da quella che corrisponde al bersaglio che necessita di una regola sono incidentali: preoccuparsi solo di dare una ricetta e i prerequisiti al file attualmente in questione. Tuttavia, quando viene eseguita la ricetta di questo file, gli altri target vengono contrassegnati come se fossero stati aggiornati.

+0

Ah ok, sì, ho letto questo ... ma ho pensato che ci sarebbe stata una soluzione affidabile per questo problema. Perché così devi aggiungere un bersaglio ogni volta che aggiungi una lingua. – Mario

+2

Bene, se i tuoi comandi sono multi-linea, prendi in considerazione la definizione di una macro multilinea chiamata 'commands' e usandola con' @ $ (call commands) '. Quindi ogni nuova lingua richiede solo l'aggiunta di due righe. La macro – Jens

+1

era un buon suggerimento! una combinazione di '$ (foreach,,)', '$ (eval)' e '$ (call)' ha risolto il problema! Modifico il mio primo post. – Mario