Vous pouvez imprimer des variables pendant la lecture du makefile (en supposant que GNU make comme vous avez correctement tagué cette question) en utilisant cette méthode (avec une variable nommée "var"):
$(info $$var is [${var}])
Vous pouvez ajouter cette construction à n'importe quelle recette pour voir quelle marque passera au shell:
.PHONY: all
all: ; $(info $$var is [${var}])echo Hello world
Maintenant, ce qui se passe ici, c'est que make stocke l'intégralité de la recette ( $(info $$var is [${var}])echo Hello world
) comme une seule variable développée récursivement. Lorsque make décide d'exécuter la recette (par exemple lorsque vous lui dites de construire all
), il développe la variable, puis passe chaque ligne résultante séparément au shell.
Donc, dans les moindres détails:
- Il se dilate
$(info $$var is [${var}])echo Hello world
- Pour ce faire, il se développe d'abord
$(info $$var is [${var}])
$$
devient littéral $
${var}
devient :-)
(disons)
- L'effet secondaire est qu'il
$var is [:-)]
apparaît sur la sortie standard
- L'expansion du
$(info...)
bien est vide
- Faire est laissé avec
echo Hello world
- Faites d'abord des impressions
echo Hello world
sur stdout pour vous faire savoir ce que cela va demander au shell
- La coquille imprime
Hello world
sur stdout.
Selon le manuel GNU Make et également indiqué par «bobbogo» dans la réponse ci-dessous, vous pouvez utiliser info / warning / error pour afficher du texte.
Pour imprimer des variables,
'error' arrêterait l' exécution de make , après avoir montré la chaîne d'erreur
la source
à partir d'un "Mr. Make post" https://www.cmcrossroads.com/article/printing-value-makefile-variable
Ajoutez la règle suivante à votre Makefile:
Ensuite, si vous souhaitez connaître la valeur d'une variable makefile, il suffit:
et il renverra:
la source
Si vous voulez simplement une sortie, vous voulez l'utiliser
$(info)
seule. Vous pouvez le faire n'importe où dans un Makefile, et cela s'affichera lorsque cette ligne sera évaluée:Sortira
VAR="<value of VAR>"
chaque fois que les processus seront traités sur cette ligne. Ce comportement est très dépendant de la position, vous devez donc vous assurer que l'$(info)
expansion se produit APRÈS tout ce qui pourrait être modifié$(VAR)
s'est déjà produit!Une option plus générique consiste à créer une règle spéciale pour imprimer la valeur d'une variable. De manière générale, les règles sont exécutées après que les variables sont affectées, cela vous montrera donc la valeur réellement utilisée. (Cependant, il est possible qu'une règle modifie une variable .) Un bon formatage aidera à clarifier à quoi une variable est définie, et la
$(flavor)
fonction vous dira de quel type de variable il s'agit. Donc dans cette règle:$*
se développe jusqu'à la tige à laquelle le%
modèle correspond dans la règle.$($*)
se développe à la valeur de la variable dont le nom est donné par$*
.[
et]
délimiter clairement l'expansion variable. Vous pouvez également utiliser"
et"
ou similaire.$(flavor $*)
vous indique de quel type de variable il s'agit. REMARQUE:$(flavor)
prend un nom de variable et non son expansion. Donc, si vous ditesmake print-LDFLAGS
, vous obtenez$(flavor LDFLAGS)
, c'est ce que vous voulez.$(info text)
fournit une sortie. Faites des impressionstext
sur sa sortie standard comme effet secondaire de l'expansion. L'expansion de$(info)
bien est vide. Vous pouvez y penser comme@echo
, mais surtout, il n'utilise pas le shell, vous n'avez donc pas à vous soucier des règles de citation du shell.@true
est là juste pour fournir une commande pour la règle. Sans cela, make sortira égalementprint-blah is up to date
. Je pense@true
qu'il est plus clair que c'est censé être un non-op.En l'exécutant, vous obtenez
la source
@echo $ (NDK_PROJECT_PATH) est le bon moyen de le faire. Je ne pense pas que l'erreur vient de là. Généralement, cette erreur apparaît lorsque vous avez mal saisi l'intention: je pense que vous avez des espaces où vous devriez avoir une tabulation.
la source
Toutes les versions de
make
nécessitent que les lignes de commande soient mises en retrait avec un TAB (pas d'espace) comme premier caractère de la ligne. Si vous nous montriez la règle entière au lieu des deux lignes en question, nous pourrions donner une réponse plus claire, mais cela devrait être quelque chose comme:où le premier caractère de la deuxième ligne doit être TAB.
la source
Run
make -n
; il vous montre la valeur de la variable ..Makefile ...
Commander:
Production:
la source
--just-print
le même dans Au lieu de l'exécutionCela
makefile
générera le message d'erreur «séparateur manquant»:Il y a un onglet avant le
@echo "All done"
(bien que ladone:
règle et l'action soient largement superflues), mais pas avant le@echo PATH=$(PATH)
.Le problème est que la ligne commençant
all
doit avoir deux points:
ou un égal=
pour indiquer qu'il s'agit d'une ligne cible ou d'une macro, et qu'elle n'a ni l'une ni l'autre, de sorte que le séparateur est manquant.L'action qui fait écho à la valeur d'une variable doit être associée à une cible, éventuellement une cible factice ou PHONEY. Et cette ligne cible doit avoir un deux-points dessus. Si vous ajoutez un
:
aprèsall
dans l'exemplemakefile
et remplacez les blancs en tête de la ligne suivante par un onglet, cela fonctionnera correctement.Vous avez probablement un problème analogue près de la ligne 102 dans l'original
makefile
. Si vous montriez 5 lignes non vides et sans commentaire avant les opérations d'écho qui échouent, il serait probablement possible de terminer le diagnostic. Cependant, puisque la question a été posée en mai 2013, il est peu probable que le cassémakefile
soit toujours disponible maintenant (août 2014), donc cette réponse ne peut pas être validée formellement. Il ne peut être utilisé que pour illustrer une manière plausible dont le problème s'est produit.la source
Pas besoin de modifier le Makefile.
la source
Le problème est que l'écho ne fonctionne que sous un bloc d'exécution. c'est-à-dire quoi que ce soit après "xx:"
Donc, tout ce qui se trouve au-dessus du premier bloc d'exécution n'est qu'une initialisation, donc aucune commande d'exécution ne peut être utilisée.
Alors créez un bloc d'exécution
la source
Cela peut être fait de manière générique et peut être très utile lors du débogage d'un makefile complexe. En suivant la même technique que celle décrite dans une autre réponse , vous pouvez insérer ce qui suit dans n'importe quel makefile:
Ensuite, vous pouvez simplement faire "make print" pour vider la valeur de n'importe quelle variable:
la source
Vous pouvez créer une règle vars dans votre fichier make, comme ceci:
Il existe des moyens plus robustes de sauvegarder toutes les variables ici: gnu make: liste les valeurs de toutes les variables (ou "macros") dans une exécution particulière .
la source
Si vous ne souhaitez pas modifier le Makefile lui-même, vous pouvez utiliser
--eval
pour ajouter une nouvelle cible, puis exécuter la nouvelle cible, par exemplemake --eval='print-tests: @echo TESTS $(TESTS) ' print-tests
Vous pouvez insérer le caractère TAB requis dans la ligne de commande à l'aide de
CTRL-V, TAB
exemple Makefile d'en haut:
la source
make: *** missing separator. Stop.
make --eval='print-tests: ; @echo TESTS $(TESTS)' print-tests
si vous utilisez Android make (mka)
@echo $(NDK_PROJECT_PATH)
ne fonctionnera pas et vous donne une erreur,*** missing separator. Stop."
utilisez cette réponse si vous essayez d'imprimer des variables dans Android makequi a fonctionné pour moi
la source
J'ai généralement un écho avec une erreur si je voulais voir la valeur de la variable (uniquement si vous vouliez voir la valeur. Cela arrêtera l'exécution).
la source