2016-05-17 4 views
2

Ich versuche herauszufinden, ob das folgende Verhalten ein Fehler in Make ist, oder absichtlich Teil des Designs (wenn ja, kann ich nicht finde es überall dokumentiert). Es tritt sowohl mit alten als auch mit neuen Versionen von GNU Make auf, die ich ausprobiert habe.Wert der einfach erweiterten Variable über den berechneten Namen unterscheidet sich in Rezept vs außerhalb Rezept

Kurz gesagt besteht das Verhalten darin, dass die Auswertung von Variablen mit berechneten Namen in Rezepten beim Aufruf des Rezepts erfolgt und nicht an der Stelle in der Datei, an der das Rezept definiert ist, auch wenn die Variable einfach- expanded (": =", im Gegensatz zu rekursiv-expanded "=") (nicht, dass das von mir erwartet würde).

Repro-Code:


a_name := alpha 
b_name := beta 

AB := a 

target1 : $($(AB)_name) 
     echo $^ 
     echo $($(AB)_name) 

alpha : ; 

beta : ; 

AB := b 

target2 : target1 ; 

nach make target2

Ausgang Aufrufen erwarte ich:

alpha
alpha

tatsächliche Ausgabe:

alpha
beta

Antwort

1

Sie müssen lesen 3.7 How make Reads a Makefile zu verstehen, was Sie sehen.

es gelesen haben, werden Sie erkennen, dass der Schlüsselteil ist:

Rule Definition 

A rule is always expanded the same way, regardless of the form: 

immediate : immediate ; deferred 
     deferred 

In diesem Licht sehen Sie, dass:

target1 : $($(AB)_name) 

in Ihrem Make-Datei ist sofort erweitert, wenn es Einlesen in Phase 1. An diesem Punkt ist die Definition von ABa, also $($(AB)_name) erweitert zu $(a_name) und dann zu alpha.

Diese alpha ist dann ein für alle Mal, um die Voraussetzung, die $^ wird erweitern, Verschoben, in Phase 2, in dem Rezept, also:

echo $^ 

im Rezept wird alpha Echo.

Die nächste Zeile im Rezept:

echo $($(AB)_name) 

wird auch latente Expanded in Phase 2, nach dem die ganze Make-Datei gelesen wurde. An diesem Punkt AB besitzt seine endgültige Definition von Phase 1, die b war, so hier $($(AB)_name) expandiert nach $(b_name), und dann zu beta. Also diese Zeile des Rezepts echo beta.

+0

Danke! Also, wenn ich Sie richtig verstehe, war meine Hypothese falsch: Es ist * not *, dass berechnete Variablen in Rezepten erweitert werden am Punkt des Aufrufs des Rezepts berechnet. Was wirklich passiert ist: Alle Variablen in Rezepten nehmen den Wert, den sie am Ende des Makefiles haben, unabhängig davon, wo sich das Rezept befindet. Ich sehe Makefiles jetzt anders! –

Verwandte Themen