Wie kann ich eine make / makefile-Ausführung abbrechen, wenn die Variable eines makefiles nicht festgelegt / bewertet wird?
Ich habe mir das ausgedacht, aber es funktioniert nur, wenn der Anrufer ein Ziel nicht explizit ausführt (dh make
nur ausführt ).
ifeq ($(MY_FLAG),)
abort: ## This MUST be the first target :( ugly
@echo Variable MY_FLAG not set && false
endif
all:
@echo MY_FLAG=$(MY_FLAG)
Ich denke, so etwas wäre eine gute Idee, habe aber nichts im Handbuch von make gefunden:
ifndef MY_FLAG
.ABORT
endif
Antworten:
TL; DR : Verwenden Sie die
error
Funktion :Beachten Sie, dass die Zeilen nicht eingerückt werden dürfen. Genauer gesagt dürfen vor diesen Zeilen keine Tabulatoren stehen.
Generische Lösung
Wenn Sie viele Variablen testen möchten, lohnt es sich, eine Hilfsfunktion dafür zu definieren:
Und so geht's:
Dies würde einen Fehler wie folgt ausgeben:
Anmerkungen:
Die eigentliche Prüfung erfolgt hier:
Dies spiegelt das Verhalten der
ifndef
Bedingung wider , sodass eine für einen leeren Wert definierte Variable ebenfalls als "undefiniert" betrachtet wird. Dies gilt jedoch nur für einfache Variablen und explizit leere rekursive Variablen:Wie von @VictorSergienko in den Kommentaren vorgeschlagen, kann ein etwas anderes Verhalten erwünscht sein:
Und:
Zielspezifische Prüfung
Es ist auch möglich, die Lösung so zu erweitern, dass nur dann eine Variable erforderlich ist, wenn ein bestimmtes Ziel aufgerufen wird.
$(call check_defined, ...)
aus dem Rezept herausVerschieben Sie einfach den Scheck in das Rezept:
Das führende
@
Zeichen schaltet das Echo des Befehls aus und:
ist der eigentliche Befehl, ein Shell- No-Op-Stub .Zielnamen anzeigen
Die
check_defined
Funktion kann verbessert werden, um auch den Zielnamen auszugeben (bereitgestellt durch die$@
Variable):Damit führt eine fehlgeschlagene Prüfung zu einer gut formatierten Ausgabe:
check-defined-MY_FLAG
spezielles ZielPersönlich würde ich die oben beschriebene einfache und unkomplizierte Lösung verwenden. In dieser Antwort wird jedoch beispielsweise vorgeschlagen, ein spezielles Ziel zu verwenden, um die eigentliche Prüfung durchzuführen. Man könnte versuchen, das zu verallgemeinern und das Ziel als implizite Musterregel zu definieren:
Verwendung:
Beachten Sie, dass dies
check-defined-BAR
als Voraussetzung nur für die Bestellung (|...
) aufgeführt ist.Vorteile:
Nachteile:
make -t
(siehe Anstatt Rezepte auszuführen ), wird Ihr Stammverzeichnis mit vielencheck-defined-...
Dateien verschmutzt . Dies ist ein trauriger Nachteil der Tatsache, dass Musterregeln nicht deklariert werden können.PHONY
.Ich glaube, diese Einschränkungen können mit einigen
eval
magischen und sekundären Erweiterungs- Hacks überwunden werden , obwohl ich nicht sicher bin, ob es sich lohnt.quelle
make --version
als ersten Schritt überprüfen .Verwenden Sie die Shell-Funktion
test
:Verwendung:
quelle
checkforsomething
Ziel erstellt, das nur das enthälttest
und davonfoo
abhängig gemacht hat, und 2) ich habe@if test -z "$(something)"; then echo "helpful error here"; exit 1; fi
stattdessen die Prüfung in geändert . Das gab mir die Möglichkeit, einen nützlichen Fehler hinzuzufügen, und erlaubte mir, den Namen des neuen Ziels ein wenig deutlicher zu machen, was ebenfalls schief gelaufen ist.Makefile:5: *** missing separator. Stop.
test -n "$(something) || (echo "message" ; exit 1)
das Explizite vermiedenif
.Sie können eine IF verwenden, um Folgendes zu testen:
Ergebnis:
quelle
[
ist ein Alias für den Befehltest
, daher ist dies die gleiche Antwort wie oben bei @Messa. Dies ist jedoch kompakter und umfasst die Generierung von Fehlermeldungen.Verwenden Sie die Shell-Fehlerbehandlung für nicht gesetzte Variablen (beachten Sie das Double
$
):Wenn Sie eine benutzerdefinierte Fehlermeldung benötigen, fügen Sie diese nach
?
:quelle
Der Einfachheit und Kürze halber:
Mit Ausgängen:
quelle