2014-10-15 13 views
14

Ich habe bereits gesehen How to manually call another target from a make target?, aber meine Frage ist ein bisschen anders; betrachten Sie dieses Beispiel (beachten Sie, stackoverflow.com ändert die Tabs zu Leerzeichen in der Anzeige, aber Registerkarten Quelle erhalten sind, wenn Sie zu bearbeiten versuchen):Eine make-Variable ändern und eine andere Regel aus einem Rezept im selben Makefile aufrufen?

TEXENGINE=pdflatex 

pdflatex: 
    echo the engine is $(TEXENGINE) 

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

Hier wird, wenn ich die Standard-Ziel ausgeführt (pdflatex), ich erhalte die erwartete Ausgabe:

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

Aber mit dem Ziel lualatex, ich will:

  • Änderung der make Variable TEXENGINE zu lualatex und dann
  • rufen Sie den gleichen Code wie in pdflatex (die es verwendet).

Wie könnte ich das tun?

ist klar, die ich in meinem lualatex Regel nicht gelingt, auch die TEXENGINE Variablen zu ändern, weil ich das, wenn ich versuche, es:

$ 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! 

... so würde ich wirklich gerne wissen, ob etwas So ist das in Makefiles möglich.

+1

Für einen Start, ich würde dieses Ziel 'pdflatex' nicht nennen, wenn Sie es verwenden willkürliche Sachen zu überprüfen. Ich würde etwas wie "checkEngine" vorschlagen und es zu ".PHONY" machen. –

+0

Danke, @OliverCharlesworth - Ich denke, das ist in Ordnung, aber, weil 'pdflatex' in diesem Anwendungsfall der Standard ist, und so bekomme ich das gleiche Ergebnis für nur' make' oder 'make pdflatex' (und der Anwendungsfall ist dann um Motoren zu ändern, indem man sie als Ziele für 'make' spezifiziert, wie in' make lualatex'. Prost! – sdaau

+1

Nun, es liegt an dir;) (Ich würde das eher verwirrend und schlechte Praxis finden ...) Kannst du einfach "TEXENGINE = was auch immer" machen, und einen generischen Satz von Zielen/Regeln strukturieren, die den vom Benutzer angegebenen verwenden 'TEXENGINE' Variable? –

Antwort

15

ein Verwenden target-specific variable

eine weitere Besonderheit von zielspezifischen varia Es gibt bles: Wenn Sie eine zielspezifische Variable definieren, gilt dieser Variablenwert auch für alle Voraussetzungen dieses Ziels und alle deren Voraussetzungen usw. (außer diese Voraussetzungen überschreiben diese Variable mit ihrem eigenen zielspezifischen Variablenwert).

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! 

Die Ausgabe lautet:

$ 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

Danke dafür @JonathanWakely - Ich war zuerst verwirrt, denn eine Voraussetzung würde 'pdflatex' vor' lualatex' heißen; Aber dann habe ich getestet und realisiert, dass das 'lualatex:' Target in zwei Teile geteilt wird, um diese Fallstricke zu vermeiden - und die Lösung funktioniert auch ohne rekursives 'make' Call, was großartig ist. Danke auch für den Hinweis zu "zielspezifischen Variablen". Prost! – sdaau

+1

Genauer gesagt, wenn Sie in 'lualatex' nichts tun müssen, was nicht' pdflatex' ist, dann brauchen Sie überhaupt keinen Rezeptkörper auf dem 'lualatex' Ziel. Nur die zwei 'lualatex:' Zeilen sind genug. –

1

Nun, ich habe es geschafft, zu einer Art Workaround zu kommen, aber ich verstehe es nicht genau - also wird eine mehr gelernte Antwort geschätzt werden. Für mich hier half diese Links:

So, hier ist das Beispiel geändert - offenbar eine Regel aus der Regel zu rufen danach (nicht als Voraussetzung, sondern als Post Requisite), kann ich nur make rekursiv aufrufen, während die neue Variable Wert in der Befehlszeile angegeben:

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 

Die Ausgabe ist etwas ausführlicher als ich es möchte, aber es funktioniert:

$ 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' 

... das, was ich rein Kommandozeilen-Interaktion weisen wollte, aber ich weiß, ist, nicht die beste Lösung (siehe @ unter JonathanWakely Kommentar)

+2

Was Ihre Regel hier tut, wird eine andere Instanz von 'make' ausgeführt und überschreibt explizit die' TEXENGINE'-Variable. Variablen, die in der Befehlszeile definiert sind, haben Vorrang vor Variablen, die in der Umgebung oder im Makefile definiert sind. Wenn die zweite 'make' ausgeführt wird, verwendet sie den überschriebenen Wert. Der Nachteil dieses Ansatzes ist, dass Sie "make" zweimal ausführen. Wenn Sie also eine Menge Arbeit aufwenden müssen, um den Status der Voraussetzungen zu überprüfen, dann machen Sie das alles doppelt. –