2014-10-15 39 views
14

Ho già visto How to manually call another target from a make target?, ma la mia domanda è un po 'diversa; considerare questo esempio (nota, stackoverflow.com cambia le tabulazioni in spazi in esposizione, ma le schede sono conservati in formato sorgente, se si tenta di modificare):Modificare una variabile make e chiamare un'altra regola da una ricetta nello stesso Makefile?

TEXENGINE=pdflatex 

pdflatex: 
    echo the engine is $(TEXENGINE) 

lualatex: 
    TEXENGINE=lualatex 
    echo Here I want to call the pdflatex rule, to check $(TEXENGINE) there! 

Qui, se corro il target di default (pdflatex), ottengo i risultati attesi:

$ make pdflatex 
echo the engine is pdflatex 
the engine is pdflatex 

Ma, con l'obiettivo lualatex, voglio:

  • cambiamento della variabile makeTEXENGINE a lualatex e quindi
  • chiama lo stesso codice di pdflatex (che lo utilizza).

Come potrei farlo?

Chiaramente, nel mio lualatex regola io non riesco nemmeno a modificare la variabile TEXENGINE, perché ottengo questo quando l'ho provato:

$ make lualatex 
TEXENGINE=lualatex 
echo Here I want to call the pdflatex rule, to check pdflatex there! 
Here I want to call the pdflatex rule, to check pdflatex there! 

... quindi mi piacerebbe davvero sapere se qualcosa come questo è possibile nei Makefile.

+1

Tanto per cominciare, non lo definirei tale obiettivo 'pdflatex', se lo si usa per controllare roba arbitraria. Suggerirei qualcosa come 'checkEngine', e renderlo' .PHONY'. –

+0

Grazie, @OliverCharlesworth - Penso che vada bene, però, perché "pdflatex" in questo caso d'uso è l'impostazione predefinita, quindi ottengo lo stesso risultato per "make" o "make pdflatex" (e il caso d'uso è quindi cambiare i motori specificandoli come obiettivi per 'make', come in' make lualatex'). Saluti! – sdaau

+1

Bene, dipende da te;) (Troverò che pratica piuttosto confusa e cattiva ...) Puoi semplicemente fare 'make TEXENGINE = whatever', e strutturare un insieme generico di target/regole che usano l'utente specificato Variabile 'TEXENGINE'? –

risposta

15

Utilizzare un target-specific variable

c'è una caratteristica più particolare di varia specifici target bles: quando si definisce una variabile specifica della destinazione, il valore della variabile è valido anche per tutti i prerequisiti di questa destinazione e tutti i relativi prerequisiti, ecc. (a meno che quei prerequisiti non sostituiscano quella variabile con il proprio valore di variabile specifico della destinazione).

TEXENGINE=pdflatex 

pdflatex: 
    echo the engine is $(TEXENGINE) 

lualatex: TEXENGINE=lualatex 
lualatex: pdflatex 
    echo Here I want to call the pdflatex rule, to check $(TEXENGINE) there! 

L'output è:

$ make pdflatex 
echo the engine is pdflatex 
the engine is pdflatex 
$ make lualatex 
echo the engine is lualatex 
the engine is lualatex 
echo Here I want to call the pdflatex rule, to check lualatex there! 
Here I want to call the pdflatex rule, to check lualatex there! 
+0

Grazie per questo @JonathanWakely - All'inizio ero confuso, perché un prerequisito avrebbe chiamato 'pdflatex' prima di' lualatex'; ma poi ho provato e realizzato la divisione del 'lualatex:' obiettivo in due evita questo trabocchetto - e la soluzione funziona anche senza chiamata 'make' ricorsiva, che è grandiosa. Grazie anche per la nota su "variabili specifiche del target". Saluti! – sdaau

+1

In particolare, se non c'è niente che devi fare in 'lualatex' che non è solo ciò che' pdflatex' fa, allora non hai bisogno di un corpo di una ricetta sull'obiettivo 'lualatex'. Solo le due linee 'lualatex:' sono sufficienti. –

1

Bene, sono riuscito a ottenere una soluzione alternativa, ma non lo capisco molto, quindi una risposta più apprezzabile sarà apprezzata. Per me qui, questi collegamenti aiutato:

Così qui è l'esempio modificato - a quanto pare, per chiamare una regola da una regola in seguito (non come prerequisito, piuttosto, come requisito post), posso chiamare ricorsivamente solo make, pur avendo il nuovo valore di variabile specificato sulla sua riga di comando:

TEXENGINE=pdflatex 

pdflatex: 
    echo the engine is $(TEXENGINE) 

lualatex: 
    echo Here I want to call the pdflatex rule, to check $(TEXENGINE) there! 
    $(MAKE) TEXENGINE=lualatex pdflatex 

L'uscita è in qualche modo più dettagliato di quanto mi piacerebbe, ma funziona:

$ make lualatex 
echo Here I want to call the pdflatex rule, to check pdflatex there! 
Here I want to call the pdflatex rule, to check pdflatex there! 
make TEXENGINE=lualatex pdflatex 
make[1]: Entering directory `/tmp' 
echo the engine is lualatex 
the engine is lualatex 
make[1]: Leaving directory `/tmp' 

... che è quello che ho voluto semplicemente della riga di comando di interazione-saggio, ma so che è non è la soluzione migliore (si veda il commento di @ JonathanWakely sotto)

+2

Ciò che la tua regola fa qui è eseguire un'altra istanza di 'make' e sovrascrivere esplicitamente la variabile' TEXENGINE'. Le variabili definite sulla riga di comando hanno la precedenza sulle variabili definite nell'ambiente o nel makefile, quindi quando il secondo 'make' esegue utilizza il valore sottoposto a override. Il rovescio della medaglia di questo approccio è che si esegue 'make' due volte, quindi se deve fare molto lavoro per verificare lo stato dei prerequisiti allora si fa tutto il lavoro due volte. –