Je capture l'intention du Makefile en pseudo-code, puis j'indique les problèmes que j'ai. Je recherche un Makefile plus convivial dans un environnement de test. L'utilisation correcte du Makefile est l'une des suivantes.
make CATEGORY=parser TEST=basic.
make ALL
Si un utilisateur donne à "JUST" les commandes comme indiqué ci-dessous, il doit imprimer un message disant "TEST défini par CATÉGORIE non défini" et vice-versa
make CATEGORY=parser
make TEST=basic
J'ai essayé d'écrire le Makefile de la manière suivante, mais il contient des erreurs:
help:
echo"Usage: make CATEGORY=<advanced|basic> TEST=<test-case>
echo" make ALL
ifdef CATEGORY
ifdef TEST
CATEGORY_TEST_DEFINED = 1
else
echo "TEST not defined"
else
echo "CATEGORY not defined"
endif
ifeq ($(CATEGORY_TEST_DEFINED), 1)
$(CATEGORY):
cd $(PROJ)/$(CATEGORY)
make -f test.mk $(TEST)
endif
ifdef ALL
$(ALL):
for i in `ls`
cd $$(i)
make all
endif
Les questions que j'ai sont:
Indique si les règles d'un Makefile peuvent être sélectives (en utilisant ifdef pour sélectionner les règles et les cibles).
l'écho ne fonctionne pas. l'écho devrait aider l'utilisateur à utiliser correctement.
Le problème est que echo
appartient au Shell; Make peut le passer au Shell dans une commande, mais Make ne peut pas l'exécuter. Utilisez à la place info
:
ifdef CATEGORY
$(info CATEGORY defined)
else
$(info CATEGORY undefined)
endif
Si vous souhaitez que les règles soient conditionnelles:
ifdef CATEGORY
ifdef TEST
$(CATEGORY):
whatever
else
$(info TEST not defined)
else
$(info CATEGORY not defined)
endif
Ces lignes sont douteuses:
help:
echo"Usage: make CATEGORY=<advanced|basic> TEST=<test-case>
echo" make ALL
Vous avez besoin d'un espace entre echo
et la chaîne, et la chaîne doit être terminée:
help:
echo "Usage: make CATEGORY=<advanced|basic> TEST=<test-case>"
echo " make ALL"
Ces lignes sont douteuses:
ifdef CATEGORY
ifdef TEST
CATEGORY_TEST_DEFINED = 1
else
echo "TEST not defined"
else
echo "CATEGORY not defined"
endif
Vous avez sûrement besoin d'un endif
avant le deuxième else
? (Même si ce n'est pas syntaxiquement obligatoire, je le recommanderais.)
ifdef CATEGORY
ifdef TEST
CATEGORY_TEST_DEFINED = 1
else
echo "TEST not defined"
endif
else
echo "CATEGORY not defined"
endif
De plus, make
exécute uniquement des commandes telles que echo
est censée être lors du traitement d'une cible (règle). Il n'y exécutera pas echo
; il objectera simplement que vous ne pouvez pas définir de commandes sans qu'elles soient des actions pour une cible. Malgré tout ce que GNU Make ajoute à un makefile, le langage dans un makefile est un langage déclaratif et non un langage procédural.
Une autre façon de gérer cela est de définir des valeurs par défaut pour les macros:
CATEGORY = advanced
TEST = all
Définissez des valeurs par défaut qui font quelque chose de semi-raisonnable; laissez l'utilisateur remplacer la valeur par défaut s'il le souhaite. Vous pouvez avoir une règle telle que:
${CATEGORY}/${TEST}: ...dependencies...
...actions...
Vous pouvez laisser help
comme première règle. J'ai quelques répertoires où la première règle est:
null:
@echo "You must specify a target with this makefile!"
C'est équivalent à ce que vous avez (sauf que make
ne fait pas écho à la commande avant de l'exécuter, donc je ne vois que le message au lieu de la ligne de commande echo et le message; c'est le @
au travail). Le makefile dont il provient a également une règle all
qui est généralement la première règle (par défaut) la plus sensée.