我正在使用一个遗留库,并试图通过一些单元测试来帮助我进行开发。在使用它时,我发现如果我可以在我的依赖项上创建目标特定的过滤器,那将使他们的makefile更适合我的单元测试。目前我会做这样的事情
var_list = input1 input2
out_list = $(var_list:%=%.txt)
all_deps = dep1 dep2 dep3
input1_filter = dep2
input2_filter = dep1 dep3
all: $(out_list)
input1.txt: %.txt: % $(filter-out $(input1_filter),$(all_deps))
@echo "reqs = $?"
@echo "$< > $@"
@echo $< > $@
input2.txt: %.txt: % $(filter-out $(input2_filter),$(all_deps))
@echo "reqs = $?"
@echo "$< > $@"
@echo $< > $@
clean:
@rm $(out_list)
显然,input1.txt
和input2.txt
的规则几乎完全相同,所以如果可以编写
var_list = input1 input2
out_list = $(var_list:%=%.txt)
all_deps = dep1 dep2 dep3
input1_filter = dep2
input2_filter = dep1 dep3
all: $(out_list)
$(out_list): %.txt: % $(filter-out $(%_filter),$(all_deps))
@echo "reqs = $?"
@echo "$< > $@"
@echo $< > $@
clean:
@rm $(out_list)
这意味着对于我创建的每个目标,我只需要指定一个相应的_filter
变量,makefile将处理其余的。但是我仍然无法让它发挥作用。我发现可以在规则体中引用这些变量,例如:一个人可以在正文中写$(filter-out $($<_filter),$(all_deps))
但不在依赖列表中。
答案 0 :(得分:1)
foreach-eval-call
(仅限GNU make)是一个选项:
var_list = input1 input2
out_list = $(var_list:%=%.txt)
all_deps = dep1 dep2 dep3
input1_filter = dep2
input2_filter = dep1 dep3
all: $(out_list)
define MY_rule
$(1).txt: $(1) $$(filter-out $$($(1)_filter),$$(all_deps))
@echo "reqs = $$?"
@echo "$$< > $$@"
@echo $$< > $$@
endef
$(foreach v,$(var_list),$(eval $(call MY_rule,$(v))))
clean:
@rm $(out_list)
注意双$$
,它们很重要。有关此结构的详细说明,请参阅this other answer类似的问题。
编辑:该功能应该过滤掉