Makefile在define中扩展变量

时间:2017-08-14 13:36:47

标签: makefile gnu-make

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)

每个makefile的内容:

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

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

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

输出

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

看起来第一次NAME是空的。

1 个答案:

答案 0 :(得分:2)

让我们看一下$(foreach dir, ${INCLUDES}, $(eval $(call func1, ${dir}) ))在痛苦细节中的扩展。

  • ${INCLUDES}已展开,提供$(foreach dir,a b c,$(eval $(call func1,${dir})))
  • 下一个dir设置为a
  • $(call func1,a)已展开
    • 1设置为a
    • func1展开:
      include $(shell pwd)/test/$(strip $1)/component.mk
      $(info :::::::${NAME} ::::::::::::::: )
      • $(shell pwd)变为HERE,说(N.B.使用${CURDIR}代替)
      • $(strip $1)变为$(strip a) <{1}}
      • a扩展为空缺
      • ${NAME}扩展为空
        • 由于副作用$(info ::::::: ::::::::::::::: )出现在 stdout
  • ::::::: :::::::::::::::扩展为$(eval $(call func1,a)),展开为空
    • 作为副作用,包含 make
    • 处理
    • 据推测$(eval include HERE/test/a/component.mk)存在且包含有效的 make 语法, 变量HERE/test/a/component.mk得到一个值。

NAME设置为1。泡沫,冲洗,重复。

提示

要在此类代码中获得一些问题,请始终使用b运行 make

--warn

修复

要获得一些见解,请将$ make --warn -Rr Makefile:8: warning: undefined variable 'NAME' ::::::: ::::::::::::::: ⋮ 替换为$(eval stuff)

$(error [stuff])

在这里,我们看到$ make ::::::: ::::::::::::::: Makefile:8: *** [ include /cygdrive/c/Users/somewhere/a/component.mk ]. Stop. 已经消失,甚至在它到达eval之前。 天真的修复非常可怕。

$(info …)

define func1 include $(shell pwd)/test/$(strip $1)/component.mk $$(info :::::::$${NAME} ::::::::::::::: ) endef 到位的情况下运行

$(error …)

$ make Makefile:8: *** [ include /cygdrive/c/Users/somewhere/a/component.mk $(info :::::::${NAME} ::::::::::::::: )]. Stop. [之间的内容是有效的 make 语法。 整理它看起来像:

]

完成工作。有更简洁的方法,但你需要先了解疼痛!