2017-08-14 1 views
2
define func1 
    include $(shell pwd)/test/$(strip $1)/component.mk 
    $(info :::::::${NAME} :::::::::::::::) 
endef 

INCLUDES := a b c 

$(foreach dir, $(INCLUDES), $(eval $(call func1, $(dir)))) 

all : $(objs) 

Contenu de chaque makefile:Makefile variables en expansion définissent l'intérieur

cat test/a/component.mk 
    NAME := AA 

cat test/b/component.mk 
    NAME := BB 

cat test/c/component.mk 
    NAME := CC 

sortie est

::::::: ::::::::::::::: 
:::::::AA ::::::::::::::: 
:::::::BB ::::::::::::::: 

Il ressemble première fois NOM est vide.

Répondre

2

Regardons l'expansion de $(foreach dir, ${INCLUDES}, $(eval $(call func1, ${dir}))) en détail douloureux.

  • ${INCLUDES} est élargi, donnant $(foreach dir,a b c,$(eval $(call func1,${dir})))
  • suivant dir est réglé sur a
  • $(call func1,a) est dilatée
    • 1 est réglé sur a
    • func1 est élargi:
      include $(shell pwd)/test/$(strip $1)/component.mk
      $(info :::::::${NAME} :::::::::::::::)
      • $(shell pwd) devient HERE, disons (N.B. Utilisez ${CURDIR} à la place)
      • $(strip $1) devient $(strip a) devient a
      • ${NAME} par rien
      • $(info ::::::: :::::::::::::::) par rien
        • Comme un effet secondaire ::::::: ::::::::::::::: apparaît sur stdout
  • $(eval $(call func1,a)) étend à $(eval include HERE/test/a/component.mk), par rien
    • Comme un effet secondaire, la comprennent est traité par faire
    • On peut supposer que HERE/test/a/component.mk existe et contient valide faire syntaxe, et la variable NAME obtient une valeur.

1 est réglé sur b. Mousser, rincer, répéter.

Conseil

Pour avoir une idée des problèmes dans le code comme celui-ci, exécutez toujours faire avec --warn:

$ make --warn -Rr 
Makefile:8: warning: undefined variable 'NAME' 
::::::: ::::::::::::::: 
⋮ 

Fix

Pour obtenir un aperçu, remplacer le $(eval stuff) avec $(error [stuff])

$ make 
::::::: ::::::::::::::: 
Makefile:8: *** [ include /cygdrive/c/Users/somewhere/a/component.mk 
    ]. Stop. 

Ici, nous voyons que le $(info …) a disparu avant même d'avoir atteint l'eval. La solution naïve est assez horrible.

define func1 
    include $(shell pwd)/test/$(strip $1)/component.mk 
    $$(info :::::::$${NAME} :::::::::::::::) 
endef 

L'exécution de ce avec le $(error …) en place donne

$ make 
Makefile:8: *** [ include /cygdrive/c/Users/somewhere/a/component.mk 
    $(info :::::::${NAME} :::::::::::::::)]. Stop. 

Ce truc entre le [ et ] est valide faire syntaxe. rangea il ressemble:

include /cygdrive/c/Users/somewhere/a/component.mk 
$(info :::::::${NAME} :::::::::::::::) 

fait Job. Il y a des manières plus propres, mais vous devez d'abord comprendre la douleur!

+0

Merci beaucoup pour votre aide. Ça marche pour moi :) – user2331977