Reputation: 153
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)
Contents of each makefile:
cat test/a/component.mk
NAME := AA
cat test/b/component.mk
NAME := BB
cat test/c/component.mk
NAME := CC
Output is
::::::: :::::::::::::::
:::::::AA :::::::::::::::
:::::::BB :::::::::::::::
It looks like first time NAME is empty.
Upvotes: 2
Views: 415
Reputation: 15483
Let's look at the expansion of $(foreach dir, ${INCLUDES}, $(eval $(call func1, ${dir}) ))
in painful detail.
${INCLUDES}
is expanded, giving $(foreach dir,a b c,$(eval $(call func1,${dir})))
dir
is set to a
$(call func1,a)
is expanded
1
is set to a
func1
is expanded:include $(shell pwd)/test/$(strip $1)/component.mk
$(info :::::::${NAME} ::::::::::::::: )
$(shell pwd)
becomes HERE
, say (N.B. Use ${CURDIR}
instead)$(strip $1)
becomes $(strip a)
becomes a
${NAME}
expands to nothing$(info ::::::: ::::::::::::::: )
expands to nothing
::::::: :::::::::::::::
appears on stdout$(eval $(call func1,a))
expands to $(eval include HERE/test/a/component.mk)
, expands to nothing
HERE/test/a/component.mk
exists and contains valid make syntax,
and the variable NAME
gets a value.1
is set to b
. Lather, rinse, repeat.
To get a hint of problems in code like this, always run make with --warn
:
$ make --warn -Rr
Makefile:8: warning: undefined variable 'NAME'
::::::: :::::::::::::::
⋮
To get some insight, replace the $(eval stuff)
with $(error [stuff])
$ make
::::::: :::::::::::::::
Makefile:8: *** [ include /cygdrive/c/Users/somewhere/a/component.mk
]. Stop.
Here we see the $(info …)
has disappeared even before it has got to the eval.
The naive fix is pretty horrible.
define func1
include $(shell pwd)/test/$(strip $1)/component.mk
$$(info :::::::$${NAME} ::::::::::::::: )
endef
Running this with the $(error …)
in place gives
$ make
Makefile:8: *** [ include /cygdrive/c/Users/somewhere/a/component.mk
$(info :::::::${NAME} ::::::::::::::: )]. Stop.
That stuff between the [
and ]
is valid make syntax.
Tidied up it looks like:
include /cygdrive/c/Users/somewhere/a/component.mk
$(info :::::::${NAME} ::::::::::::::: )
Job done. There are cleaner ways, but you need to understand the pain first!
Upvotes: 4