2011-06-29 164 views
14

以下示例代碼中的dep2函數有什麼問題?定義自定義GNU make函數

dep1 = $(eval makefile_list_$1 := $(MAKEFILE_LIST))$(eval -include $1.mk)$(eval MAKEFILE_LIST := $(makefile_list_$1)) 

define dep2 
$(eval makefile_list_$1 := $(MAKEFILE_LIST)) 
$(eval -include $1.mk) 
$(eval MAKEFILE_LIST := $(makefile_list_$1)) 
endef 

$(call dep1,test) 
$(call dep2,test) 

.DEFAULT_TARGET: all 
.PHONY: all 
all: 
    @echo [email protected] 

GNU使3.81和3.82產生Makefile:10: *** missing separator. Stop.,它指向DEP2通話,DEP1無錯運行。兩個變體之間的唯一區別是dep2中的換行符(以及爲什麼我想使用define的全部觀點)。

回答

6

你忘了 =
限定DEP2 =

編輯:
將分號在每一行的末尾。我已經測試過它,它可以工作(在GNUMake 3.81中)。

define dep2 
$(eval makefile_list_$1 := $(MAKEFILE_LIST)); 
$(eval -include $1.mk); 
$(eval MAKEFILE_LIST := $(makefile_list_$1)); 
endef 

爲什麼這些分號是必要的,我不知道,但文檔define中似乎是用於多行「變量」僅定義外殼的序列時,命令在配方中使用,不制定命令,所以也許規則有點不同。

+0

不,「=」是可選的(並且僅在GNU make 3.82中引入)。添加它並沒有什麼區別。 –

+0

@ g.b .:你真的嘗試過嗎?我做了(使用GNU make 3.81),它確實有所作爲。它符合我的預期,如果我添加'='。 – eriktous

+4

@eriktous:是的,我用3.82試過。如果後面跟着一個'=',那麼舊版本會完全忽略定義語句,這就是爲什麼你沒有收到錯誤信息的原因。 –

-1

你在做什麼可以改進很多。一方面,你真的想把eval調用分配給頂部的一個調用。

但是,您的特殊問題源於不理解多行遞歸字符串make's define命令使用永遠不會包含女士新行。寫evalable功能最自然的約定是

定義美孚1號線 2號線

endef

你可以看一下串EVAL是看到,看到通過信息命令這是什麼一樣,例如 $(info $(call Foo,x)$(call Foo,y))。

1

我會移動dep2以外的$(eval ...)調用。通過這樣做,在dep2中不需要分號。這意味着一些擴張的跡象加倍,以避免擴張過早完成。所以:

define dep2 
makefile_list_$1 := $$(MAKEFILE_LIST) 
-include $1.mk 
MAKEFILE_LIST := $$(makefile_list_$1) 
endef 

$(eval $(call dep2,test)) 

# Quick checks for testing, to be removed from the final code... 
$(info $(makefile_list_test)) 
$(info $(MAKEFILE_LIST)) 

.DEFAULT_TARGET: all 
.PHONY: all 
all: 
    @echo [email protected] 

我已經測試了上面的代碼,它與Gnu Make 4.0一起使用。我希望它能回到Gnu Make 3.8x。 $(eval $(call ...))模式是我總是用來執行我的自定義函數,並且我已經使用了它很長一段時間了。