2017-08-14 77 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) 

內容:生成文件擴展變量內定義每個生成文件的

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

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

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

輸出是

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

它看起來像第一次NAME是空的。

回答

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)成爲a
      • ${NAME}什麼也不擴展
      • $(info ::::::: :::::::::::::::)什麼也不擴展
        • 作爲一個副作用::::::: :::::::::::::::出現在標準輸出
  • $(eval $(call func1,a))擴展到$(eval include HERE/test/a/component.mk),什麼也不擴展
    • 作爲副作用,所述包括處理使
    • 推測HERE/test/a/component.mk存在幷包含有效使語法, 和可變NAME獲取值。

1設置爲b。泡沫,沖洗,重複。

提示

爲了得到在這樣的代碼問題的提示,始終運行使--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. 

在這裏,我們看到$(info …)甚至在它已經到達eval之前已經消失。 天真的修復是非常可怕的。

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. 

這東西[]有效使語法之間。 收拾它看起來像:

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

工作完成。有更清潔的方式,但你需要先了解疼痛!

+0

非常感謝您的幫助。這個對我有用 :) – user2331977