Comment pourrais-je abandonner une exécution make / makefile basée sur la variable d'un makefile qui n'est pas définie / valorisée?
Je suis venu avec cela, mais ne fonctionne que si l'appelant n'exécute pas explicitement une cible (c'est-à-dire make
ne fonctionne que).
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)
Je pense que quelque chose comme ça serait une bonne idée, mais je n'ai rien trouvé dans le manuel de make:
ifndef MY_FLAG
.ABORT
endif
Réponses:
TL; DR : utilisez la
error
fonction :Notez que les lignes ne doivent pas être indentées. Plus précisément, aucun onglet ne doit précéder ces lignes.
Solution générique
Dans le cas où vous allez tester de nombreuses variables, il vaut la peine de définir une fonction auxiliaire pour cela:
Et voici comment l'utiliser:
Cela produirait une erreur comme celle-ci:
Remarques:
Le vrai contrôle se fait ici:
Cela reflète le comportement du
ifndef
conditionnel, de sorte qu'une variable définie à une valeur vide est également considérée comme "non définie". Mais cela n'est vrai que pour les variables simples et les variables récursives explicitement vides:Comme suggéré par @VictorSergienko dans les commentaires, un comportement légèrement différent peut être souhaité:
Et:
Vérification spécifique à la cible
Il est également possible d'étendre la solution afin que l'on puisse exiger une variable uniquement si une certaine cible est invoquée.
$(call check_defined, ...)
de l'intérieur de la recetteDéplacez simplement le chèque dans la recette:
Le
@
signe principal désactive l'écho de commande et:
est la commande réelle, un stub no-op du shell .Affichage du nom de la cible
La
check_defined
fonction peut être améliorée pour afficher également le nom de la cible (fourni via la$@
variable):Donc, maintenant, une vérification échouée produit une sortie bien formatée:
check-defined-MY_FLAG
cible spécialePersonnellement, j'utiliserais la solution simple et directe ci-dessus. Cependant, par exemple, cette réponse suggère d'utiliser une cible spéciale pour effectuer le contrôle réel. On pourrait essayer de généraliser cela et de définir la cible comme une règle de modèle implicite:
Usage:
Notez que le
check-defined-BAR
est répertorié comme condition préalable à la commande uniquement (|...
).Avantages:
Les inconvénients:
make -t
(voir au lieu d'exécuter des recettes ) polluera votre répertoire racine avec beaucoup decheck-defined-...
fichiers. C'est un triste inconvénient du fait que les règles de modèle ne peuvent pas être déclarées.PHONY
.Je crois que ces limitations peuvent être surmontées en utilisant des hacks d' expansion
eval
magiques et secondaires , même si je ne suis pas sûr que cela en vaille la peine.la source
make --version
dans un premier temps.Utilisez la fonction shell
test
:Usage:
la source
checkforsomething
cible qui ne contenait que letest
et qui enfoo
dépendait, et 2) j'ai changé le chèque à la@if test -z "$(something)"; then echo "helpful error here"; exit 1; fi
place. Cela m'a donné la possibilité d'ajouter une erreur utile et m'a permis de rendre le nom de la nouvelle cible un peu plus indicatif de ce qui n'allait pas.Makefile:5: *** missing separator. Stop.
test -n "$(something) || (echo "message" ; exit 1)
j'évitais l'expliciteif
.Vous pouvez utiliser un IF pour tester:
Résultat:
la source
[
est un alias pour la commandetest
, c'est donc la même réponse que @Messa ci-dessus. Ceci est cependant plus compact et inclut la génération de message d'erreur.Utilisez la gestion des erreurs du shell pour les variables non définies (notez le double
$
):Si vous avez besoin d'un message d'erreur personnalisé, ajoutez-le après le
?
:la source
Pour plus de simplicité et de brièveté:
Avec sorties:
la source