具有正则表达式模式匹配的自动化制作系统

时间:2013-12-04 18:39:50

标签: regex makefile build-automation

我使用GNU make来构建报告(LaTeX for source,python for figures等)。对于目标,我使用广泛的模式匹配,例如:

 all : sample1_test1.png sample2_test1.png sample2_test.png

 sample%_test1.png : sample%.dat
    python gen_figure.py $< $@ --test 1

 sample%_test2.png : sample%.dat
    python gen_figure.py $< $@ --test 2

现在,为了简化规则,我想使用多个模式组(如正则表达式组)并在构建规则中单独使用匹配项,例如:

 all : sample1_test1.png sample2_test1.png sample2_test.png

 sample(?P<Sample>[0-9]+)_test(?P<Test>[0-9]+).png : sample$(<Sample>).dat
     python gen_figure.py $< $@ --test $(<Test>)

(语法是任意的,但重点是我可以定义两个名为SampleTest的不同匹配组,并将它们用作我脚本的参数。)

我如何在make或其他构建系统(waf,scons等)中实现这一目标?

1 个答案:

答案 0 :(得分:1)

要在GNU make中执行此操作,您可以使用GNU make支持的两种不同“元编程”模型之一:

  1. 自动生成的包含文件。在主makefile中,添加-include generated.mk,然后编写一个包含目标generated.mk的makefile规则(可能列出Makefile作为先决条件),其中配方根据目标列表生成适当的目标。您可以使用shell的全部功能来构建您想要的目标列表。每次修改makefile时,都会重建包含的文件,然后GNU make会自动重新执行,这样你就不需要做任何额外的事情了。

  2. 使用GNU make的$(eval ...)函数(可能与$(call ...)$(foreach ...)结合使用)来自动评估规则。要执行此操作,请使用define ... enddef为规则定义“模板”,并在要提供参数的位置安装变量,然后使用$(call ...)实例化它们,对结果使用$(eval ...) call,并在每个目标的循环中执行。例如:$(foreach T,$(TARGETS),$(eval $(call DEFINERULE,$(T))))

  3. 以下是方法1的示例。假设您在makefile中有此预定义内容:

    TESTS := sample1_test1.png sample2_test1.png sample2_test.png
    

    然后你可以使用这个makefile来获得类似上面的内容:

    all: $(TESTS)
    
    -include generated.mk
    
    generated.mk : Makefile
            @rm -f '$@'
            @for t in $(TESTS); do \
                eval `echo "$$t" | sed 's/^sample\([0-9]*\)_test\([0-9]*\).*/sample=\1 test=\2/'`; \
                echo "$$t : sample$$sample.dat ; python gen_figure.py \$$< \$$@ --test $$test" >> '$@'; \
             done
    

    注意我刚刚写下了这篇文章,但我认为它会起作用。