我有一个更复杂的Makefile,它具有动态生成的目标,例如:
COMPONENTS = foo bar lipsum
define TEST_template =
.PHONY: test-$(1)
test-$(1):
@echo test
endef
$(foreach cmpnt,$(COMPONENTS),$(eval $(call TEST_template,$(cmpnt))))
但是现在我想向该目标添加特定于目标的变量。对于非动态目标,效果很好:
test: VAR_ONE=1
test:
@echo "VAR_ONE=$(VAR_ONE)"
但是将这两者结合不起作用
COMPONENTS = foo bar lipsum
define TEST_template =
.PHONY: test2-$(1)
test2-$(1): VAR_ONE=1
test2-$(1):
@echo "test - VAR_ONE=$(VAR_ONE)"
endef
$(foreach cmpnt,$(COMPONENTS),$(eval $(call TEST_template,$(cmpnt))))
现在运行make test2-foo
将返回test - VAR_ONE=
,因此似乎未设置该变量。
这甚至可能吗?我已经尝试了几天,但是我什么也找不到。
您必须对define
内不希望由call
解释的任何变量引用进行转义。就是这样:
define TEST_template =
.PHONY: test2-$(1)
test2-$(1): VAR_ONE=1
test2-$(1):
@echo "test - VAR_ONE=$$(VAR_ONE)"
endef
一个好的经验法则(尽管与其他方法一样,都有例外)是,当定义要与call
/ eval
对一起使用的变量时,call
的参数(例如$1
, $2
等)应直接引用,所有其他变量都应转义。
您必须写
@echo "test - VAR_ONE=$$(VAR_ONE)"
(注意双倍$$
)。参见info make
重要的是要意识到'eval'参数已经扩展两次;首先通过'eval'函数,然后将扩展结果解析为makefile语法时再次扩展。这意味着您可能需要为“ $”]提供额外的转义级别