2015-08-13 1 views
2

Je suis en train de mettre en œuvre include guards dans Gnu faire. Dans ce Makefile, la première inclusion est OK, tandis que la seconde échoue avec une erreur.ifndef incluent garde Gnu Faire des pauses sur imbriquée conditionnelle

ifndef INCLUDED 
INCLUDED = 1 
$(info Including) 

define macro 
ifneq ($(1),) 
define inner_macro 
macro content... 
endef 
else 
define inner_macro 
endef 
endif 
endef 

endif 

Le même effet peut être simulé en donnant explicitement INCLUDED = 1 avant l'inclusion, par exemple sur la ligne de commande. Gnu Make 4.1 sous Gentoo dit Makefile:14: *** missing separator. Stop., tandis que Gnu Make 3.81 sous Debian Wheezy dit Makefile:14: *** extraneous `endef'. Stop.. Sur la première inscription, ils disent tous les deux:

Including 
make: *** No targets. Stop. 

Si je tente $(eval $(call macro,whatever)) après la première inscription, il définit inner_macro comme prévu.

J'ai utilisé les commandes make INCLUDED=1 et make respectivement pour obtenir le comportement décrit.

La même chose se produit lorsque je clair l'environnement et de désactiver les règles et les variables intégrées: env -i make -rR INCLUDE=1. Lorsque j'utilise -p pour vider la base de données, sans INCLUDED=1, le macro est défini comme il se doit, mais avec INCLUDED=1, vide inner_macro est défini. Ceci est cohérent dans les deux versions de Make. Cela me laisse deviner que lorsque la condition est fausse, Faites en sorte parse le Makefile différemment et pense que la else dans la définition de l « macro appartient au ifndef. D'autres types de conditions se comportent tout de même.

Si je supprime à la fois les définitions de inner_macro, le problème disparaît. Je lis les pages de manuel info make conditional\ syntax et info make multi-line (anciennement defining), mais je n'ai trouvé aucune mise en garde et je pense toujours que je ne fais rien de mal.

  1. Suis-je correct avec mes conclusions?
  2. Est-ce un bug dans Make, ou est-ce que j'appelle un comportement indéfini?
  3. Comment est-ce que je devrais implémenter des protections incluses dans Gnu Make?
+0

En tant que travail autour, je me suis déplacé la définition de macro' 'dans un autre fichier et l'a remplacé avec' inclure ce fichier. mk'. – Palec

Répondre

1

C'est un bug. Rapportez-le sur Savannah.

Il y a quelque chose de mal avec le suivi des imbriqué définir/ENDEF l'intérieur d'une non-prise ifdef/ifndef condition. Si vous n'utilisez pas imbriqué define/endef alors cela fonctionne; par exemple (évidemment, vous ne pouvez pas être en mesure de le faire dans votre environnement):

ifndef INCLUDED 
INCLUDED = 1 
$(info Including) 

define macro 
ifneq ($(1),) 
inner_macro = macro content... 
else 
inner_macro = 
endif 
endef 

endif 
+0

J'ai utilisé votre solution de contournement, même si cela nécessitait quelques manipulations de caractères spéciaux. J'ai d'abord stocké les caractères dans des macros et utilisé les extensions de ces macros. Je vais voir si le bug a déjà été signalé et le déposer, si ce n'est pas le cas. Mais il faut attendre une semaine, je suis très occupé maintenant. – Palec

+0

Il ne devrait pas être nécessaire de manipuler les caractères spéciaux en raison de ifdef/ifndef. Je ne sais pas quels caractères spéciaux vous voulez dire ou quel genre de bidouillage vous avez fait, donc je ne peux pas en dire plus ... – MadScientist

+0

J'ai utilisé des macros pour les nouvelles lignes et les onglets pour pouvoir remplacer define avec affectation. Sans cela, je ne suis pas sûr si newline peut devenir une partie de la valeur de la variable grâce à l'affectation. – Palec