自定义依赖项筛选器用于makefile中的目标

时间:2017-08-08 11:07:12

标签: makefile gnu-make

我正在使用一个遗留库,并试图通过一些单元测试来帮助我进行开发。在使用它时,我发现如果我可以在我的依赖项上创建目标特定的过滤器,那将使他们的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.txtinput2.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))但不在依赖列表中。

1 个答案:

答案 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类似的问题。

编辑:该功能应该过滤掉