Mit dieser Methode (mit einer Variablen namens "var") können Sie Variablen ausdrucken, während das Makefile gelesen wird (vorausgesetzt, GNU make, da Sie diese Frage entsprechend markiert haben):
$(info $$var is [${var}])
Sie können dieses Konstrukt zu jedem Rezept hinzufügen, um zu sehen, welche Marke an die Shell übergeben wird:
.PHONY: all
all: ; $(info $$var is [${var}])echo Hello world
Was hier passiert, ist, dass make das gesamte Rezept ( $(info $$var is [${var}])echo Hello world
) als einzelne rekursiv erweiterte Variable speichert . Wenn make beschließt, das Rezept auszuführen (z. B. wenn Sie es zum Erstellen anweisen all
), erweitert es die Variable und übergibt dann jede resultierende Zeile separat an die Shell.
Also, in schmerzhaften Details:
- Es dehnt sich aus
$(info $$var is [${var}])echo Hello world
- Dazu wird es zuerst erweitert
$(info $$var is [${var}])
$$
wird wörtlich $
${var}
wird :-)
(sagen)
- Der Nebeneffekt ist, dass
$var is [:-)]
auf Standard out erscheint
- Die Erweiterung des
$(info...)
Obwohl ist leer
- Make bleibt mit
echo Hello world
- Machen Sie zuerst Drucke
echo Hello world
auf stdout, um Sie wissen zu lassen, wozu die Shell aufgefordert wird
- Die Shell wird
Hello world
auf Standard gedruckt .
Gemäß dem GNU Make-Handbuch und in der folgenden Antwort auch mit 'bobbogo' angegeben, können Sie mit info / warning / error Text anzeigen.
Um Variablen zu drucken,
'error' würde die Ausführung von make stoppen , nachdem die Fehlerzeichenfolge angezeigt wurde
quelle
aus einem "Mr. Make Post" https://www.cmcrossroads.com/article/printing-value-makefile-variable
Fügen Sie Ihrem Makefile die folgende Regel hinzu:
Wenn Sie dann den Wert einer Makefile-Variablen herausfinden möchten, gehen Sie einfach wie folgt vor:
und es wird zurückkehren:
quelle
Wenn Sie nur eine Ausgabe wünschen, möchten Sie diese
$(info)
selbst verwenden. Sie können dies überall in einem Makefile tun und es wird angezeigt, wann diese Zeile ausgewertet wird:Wird ausgegeben,
VAR="<value of VAR>"
wenn Prozesse in dieser Zeile ausgeführt werden. Dieses Verhalten ist sehr positionsabhängig, daher müssen Sie sicherstellen, dass die$(info)
Erweiterung NACH allem erfolgt, was geändert werden könnte$(VAR)
bereits erfolgt ist!Eine allgemeinere Option besteht darin, eine spezielle Regel zum Drucken des Werts einer Variablen zu erstellen. Im Allgemeinen werden Regeln ausgeführt, nachdem Variablen zugewiesen wurden. Dies zeigt Ihnen also den Wert, der tatsächlich verwendet wird. (Es ist jedoch möglich, dass eine Regel eine Variable ändert .) Durch eine gute Formatierung wird klarer, auf was eine Variable eingestellt ist, und die
$(flavor)
Funktion zeigt an, um welche Art von Variable es sich handelt. Also in dieser Regel:$*
erweitert sich zu dem Stamm, dass das%
Muster in der Regel übereinstimmt.$($*)
wird auf den Wert der Variablen erweitert, deren Name durch gegeben ist$*
.[
und definieren]
die variable Expansion klar. Sie könnten auch"
und verwenden"
oder ähnliches verwenden.$(flavor $*)
sagt Ihnen, um welche Art von Variable es sich handelt. HINWEIS:$(flavor)
nimmt einen variablen Namen , und nicht seine Expansion. Wenn Sie also sagenmake print-LDFLAGS
, bekommen Sie$(flavor LDFLAGS)
, was Sie wollen.$(info text)
liefert Ausgabe. Machen Sie Drucketext
auf dem Standard als Nebeneffekt der Erweiterung. Die Erweiterung von$(info)
obwohl ist leer. Sie können sich das so vorstellen@echo
, aber vor allem wird die Shell nicht verwendet, sodass Sie sich keine Gedanken über Regeln für das Zitieren von Shell machen müssen.@true
ist nur da, um einen Befehl für die Regel bereitzustellen. Ohne das wird auch make ausgegebenprint-blah is up to date
. Ich denke, es@true
macht klarer, dass es ein No-Op sein soll.Wenn Sie es ausführen, bekommen Sie
quelle
@echo $ (NDK_PROJECT_PATH) ist der gute Weg, dies zu tun. Ich glaube nicht, dass der Fehler von dort kommt. Im Allgemeinen tritt dieser Fehler auf, wenn Sie die Absicht falsch eingegeben haben: Ich denke, Sie haben Leerzeichen, in denen Sie eine Registerkarte haben sollten.
quelle
In allen Versionen von
make
müssen Befehlszeilen mit einem TAB (kein Leerzeichen) als erstem Zeichen in der Zeile eingerückt werden. Wenn Sie uns die gesamte Regel anstelle nur der beiden fraglichen Zeilen zeigen würden, könnten wir eine klarere Antwort geben, aber es sollte ungefähr so aussehen:Dabei muss das erste Zeichen in der zweiten Zeile TAB sein.
quelle
Lauf
make -n
; Es zeigt Ihnen den Wert der Variablen.Makefile ...
Befehl:
Ausgabe:
quelle
--just-print
das gleiche in Statt AusführungDadurch
makefile
wird die Fehlermeldung "Fehlendes Trennzeichen" generiert:Es gibt eine Registerkarte vor dem
@echo "All done"
(obwohl diedone:
Regel und Aktion weitgehend überflüssig sind), aber nicht vor dem@echo PATH=$(PATH)
.Das Problem ist, dass der Zeilenanfang
all
entweder einen Doppelpunkt:
oder ein Gleichheitszeichen haben sollte=
um anzuzeigen, dass es sich um eine Zielzeile oder eine Makrozeile handelt, und keine, sodass das Trennzeichen fehlt.Die Aktion, die den Wert einer Variablen wiedergibt, muss einem Ziel zugeordnet sein, möglicherweise einem Dummy- oder PHONEY-Ziel. Und diese Ziellinie muss einen Doppelpunkt haben. Wenn Sie im Beispiel ein
:
Nach hinzufügenall
makefile
und die führenden Leerzeichen in der nächsten Zeile durch eine Registerkarte ersetzen, wird es sanely arbeiten.Sie haben wahrscheinlich ein analoges Problem in der Nähe von Zeile 102 im Original
makefile
. Wenn Sie vor den fehlgeschlagenen Echooperationen 5 nicht leere Zeilen ohne Kommentar angezeigt haben, ist es wahrscheinlich möglich, die Diagnose abzuschließen. Da die Frage jedoch im Mai 2013 gestellt wurde, ist es unwahrscheinlich, dass der Fehlermakefile
jetzt (August 2014) noch verfügbar ist, sodass diese Antwort nicht offiziell validiert werden kann. Es kann nur verwendet werden, um eine plausible Art und Weise zu veranschaulichen, in der das Problem aufgetreten ist.quelle
Das Makefile muss nicht geändert werden.
quelle
Das Problem ist, dass Echo nur unter einem Ausführungsblock funktioniert. dh irgendetwas nach "xx:"
Alles über dem ersten Ausführungsblock ist also nur eine Initialisierung, sodass kein Ausführungsbefehl verwendet werden kann.
Erstellen Sie also einen Ausführungsblock
quelle
Dies kann generisch erfolgen und beim Debuggen eines komplexen Makefiles sehr nützlich sein. Nach der gleichen Technik wie in einer anderen Antwort beschrieben , können Sie Folgendes in jedes Makefile einfügen:
Dann können Sie einfach "make print" ausführen, um den Wert einer Variablen zu sichern:
quelle
Sie können eine vars-Regel in Ihrer make-Datei wie folgt erstellen:
Hier gibt es einige robustere Möglichkeiten, alle Variablen zu sichern : gnu make: Listet die Werte aller Variablen (oder "Makros") in einem bestimmten Lauf auf .
quelle
Wenn Sie das Makefile selbst nicht ändern möchten, können
--eval
Sie ein neues Ziel hinzufügen und dann das neue Ziel ausführen, zmake --eval='print-tests: @echo TESTS $(TESTS) ' print-tests
Sie können das gewünschte TAB-Zeichen mit in die Befehlszeile einfügen
CTRL-V, TAB
Beispiel Makefile von oben:
quelle
make: *** missing separator. Stop.
make --eval='print-tests: ; @echo TESTS $(TESTS)' print-tests
Wenn Sie Android Make (mka) verwenden, funktioniert dies
@echo $(NDK_PROJECT_PATH)
nicht und gibt Ihnen einen Fehler.*** missing separator. Stop."
Verwenden Sie diese Antwort, wenn Sie versuchen, Variablen in Android Make zu druckendas hat bei mir funktioniert
quelle
Normalerweise erhalte ich ein Echo mit einem Fehler, wenn ich den Variablenwert sehen wollte. (Nur wenn Sie den Wert sehen wollten. Die Ausführung wird gestoppt.)
quelle