下面的示例代码中的dep2函数有什么问题?
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 $@
GNU make 3.81和3.82生成Makefile:10: *** missing separator. Stop.
指向dep2调用,dep1运行时没有错误。这两个变体之间的唯一区别是dep2中的换行符(以及为什么我要使用define的全部内容)。
答案 0 :(得分:8)
你忘记了=
:
定义dep2 =
击>
修改:
在每行末尾加一个分号。我已经对此进行了测试,并且它有效(在GNUMake 3.81中)。
define dep2
$(eval makefile_list_$1 := $(MAKEFILE_LIST));
$(eval -include $1.mk);
$(eval MAKEFILE_LIST := $(makefile_list_$1));
endef
为什么这些分号是必要的我不知道,但在文档中define
似乎用于多行"变量"只有在定义要在配方中使用的shell命令序列时,才能生成命令,所以规则可能会有所不同。
答案 1 :(得分:2)
我会将$(eval ...)
来电移到dep2
之外。通过这种方式,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 $@
我已经测试了上面的代码,它适用于Gnu Make 4.0。我希望它可以回到Gnu Make 3.8x。 $(eval $(call ...))
模式是我经常执行自定义函数的模式,现在已经使用了很长时间了。
答案 2 :(得分:0)
您可以执行以下行来消除错误:
FOO := $(call dep2, test)
我猜原因是gcc(3.8.1 / 2)的早期版本只能接受任何表达式的返回。
例如$(info string)
不返回任何内容,但$(call dep2, test)
会返回2个换行符。
答案 3 :(得分:-1)
您正在做的事情可以改善很多。首先,您确实希望将eval调用分配到顶部的单个调用。
然而,你的特殊问题源于不理解make的定义命令使用的多行递归字符串从不包括lady新行。编写可证实函数的最自然的惯例是
定义Foo 1号线 LINE2
endef
您可以查看eval正在查看的字符串,并通过info命令查看此操作,例如 $(info $(call Foo,x)$(call Foo,y))。