2012-01-10 15 views
9

Catturo l'intento del Makefile in pseudo codice, quindi indico i problemi che ho. Sto cercando un Makefile che sia più user-friendly in un ambiente di test. L'uso corretto del Makefile è uno dei seguenti.Uso di regole condizionali in un makefile

make CATEGORY=parser TEST=basic. 
    make ALL 

Se un utente dà "solo" i comandi, come indicato qui di seguito, si deve stampare un messaggio che dice "categoria di prova non definito definito" e viceversa

make CATEGORY=parser 
    make TEST=basic 

ho provato a scrivere il Makefile in seguito modi, ma errori fuori:

help: 
     echo"Usage: make CATEGORY=<advanced|basic> TEST=<test-case> 
     echo"  make ALL 

    ifdef CATEGORY 
     ifdef TEST 
      CATEGORY_TEST_DEFINED = 1 
     else 
      echo "TEST not defined" 
    else 
     echo "CATEGORY not defined" 
    endif 



    ifeq ($(CATEGORY_TEST_DEFINED), 1) 
    $(CATEGORY): 
     cd $(PROJ)/$(CATEGORY) 
     make -f test.mk $(TEST) 
    endif 

    ifdef ALL 
    $(ALL): 
     for i in `ls` 
     cd $$(i) 
     make all 
    endif 

domande che ho sono:

  1. Se le regole in un Makefile possono essere selettive (utilizzando ifdef per selezionare le regole e le destinazioni).

  2. echo non funziona. echo dovrebbe aiutare l'utente con l'uso corretto.

+0

Seguendo il punto di @ Beta, dovresti guardare le [FAQ] (http://stackoverflow.com/faq) e soprattutto la sezione [Come faccio a porre domande qui?] (Http://stackoverflow.com/faq # howtoask). –

risposta

15

Il problema è che echo appartiene alla shell; Make può passarlo alla shell in un comando, ma Make non può eseguirlo. Utilizzare info invece:

ifdef CATEGORY 
$(info CATEGORY defined) 
else 
$(info CATEGORY undefined) 
endif 

Se si desidera che le regole siano condizionale:

ifdef CATEGORY 
ifdef TEST 
$(CATEGORY): 
    whatever 
else 
$(info TEST not defined) 
else 
$(info CATEGORY not defined) 
endif 
+0

Grazie per l'input. Se Make non può eseguire il comando di shell, allora ho visto che Makefile ha (il rientro è difficile qui) per esempio, ciao: @echo "Hello There". rendi output hello -> Hello There – Mike

+0

@Mike: sì, in tal caso, "echo" è in un comando nella regola "ciao". Quando "fai buongiorno", invia Invia quel comando alla shell. Se vuoi farlo in questo modo, devi associare i messaggi "non definiti" con alcuni target, il che sembra disordinato. – Beta

3

Queste linee sono dubbi:

help: 
    echo"Usage: make CATEGORY=<advanced|basic> TEST=<test-case> 
    echo"  make ALL 

È necessario uno spazio tra echo e la stringa, e la stringa deve essere terminata:

help: 
    echo "Usage: make CATEGORY=<advanced|basic> TEST=<test-case>" 
    echo "  make ALL" 

Queste linee sono dubbi:

ifdef CATEGORY 
    ifdef TEST 
     CATEGORY_TEST_DEFINED = 1 
    else 
     echo "TEST not defined" 
else 
    echo "CATEGORY not defined" 
endif 

Sicuramente bisogno di un endif prima del secondo else? (Anche se non è sintatticamente obbligatoria, lo consiglierei.)

ifdef CATEGORY 
    ifdef TEST 
     CATEGORY_TEST_DEFINED = 1 
    else 
     echo "TEST not defined" 
    endif 
else 
    echo "CATEGORY not defined" 
endif 

Inoltre, make esegue solo comandi come echo si suppone che sia durante l'elaborazione di un bersaglio (regola). Lì non eseguirà echo; semplicemente obietterà che non puoi definire comandi senza che siano azioni per un bersaglio. Nonostante tutto ciò che GNU Make aggiunge a un makefile, la lingua in un makefile è un linguaggio dichiarativo e non un linguaggio procedurale.


Un altro modo di gestire questo è quello di definire i valori di default per le macro:

CATEGORY = advanced 
TEST  = all 

definiscono i valori predefiniti che fanno qualcosa di semi-ragionevole; lasciare che l'utente sovrascriva il valore predefinito se lo desidera.Si può avere una norma come:

${CATEGORY}/${TEST}: ...dependencies... 
    ...actions... 

Puoi lasciare help come la prima regola. Ho alcune directory in cui la prima regola è:

null: 
    @echo "You must specify a target with this makefile!" 

Questo è equivalente a quello che si ha (salvo che make non eco il comando prima di eseguirlo, così vedo solo il messaggio al posto della linea di comando echo e il messaggio, questo è il @ al lavoro). Il makefile da cui proviene ha anche una regola all che di solito è la prima regola (predefinita) più sensata.