代码生成和规则扩展

时间:2012-04-15 18:43:22

标签: makefile code-generation

假设我有一个制定规则:

.PHONY:gen
gen: auto.template
        generate-sources auto.template

创建了一堆文件,例如auto1.srcauto2.srcauto3.src等等。

如果我现在有从*.src文件构建目标的规则,请执行以下操作:

$(patsubst %.src,%.target,$(wildcard *.src)): %.target: %.src
        build $< > $@

如何告诉make首先执行gen规则,然后展开第二个规则模板的前提条件?欢迎GNU扩展。

注意:我想将其保留在一个 make调用中;一个简单的解决方案是将第二条规则放在辅助Makefile.secondrun中,并在$(MAKE) -f Makefile.secondrun处理后调用gen。但我想知道是否有更好的选择。

2 个答案:

答案 0 :(得分:4)

建立Beta的答案,这里是你如何使用GNU make中的 makefile remaking 来做到这一点,这与递归make不同。相反,它使用主makefile中的规则更新包含的makefile,然后重新启动原始make实例。这就是通常生成和使用*.d依赖文件的方式。

# Get the list of auto-generated sources.  If this file doesn't exist, or if it is older 
# than auto.template, it will get built using the rule defined below, according to the 
# standard behavior of GNU make.  If autosrcs.mk is rebuilt, GNU make will automatically 
# restart itself after autosrcs.mk is updated.

include autosrcs.mk

# Once we have the list of auto-generated sources, getting the list of targets to build 
# from them is a simple pattern substitution.

TARGETS=$(patsubst %.src,%.target,$(AUTO_SRCS))

all: $(TARGETS)

# Rule describing how to build autosrcs.mk.  This generates the sources, then computes 
# the list of autogenerated sources and writes that to autosrcs.mk in the form of a 
# make variable.  Note that we use *shell* constructs to get the list of sources, not
# make constructs like $(wildcard), which could be expanded at the wrong time relative
# to when the source files are actually created.

autosrcs.mk: auto.template
        ./generate-sources auto.template
        echo "AUTO_SRCS=`echo *.src`" > autosrcs.mk

# How to build *.target files from *.src files.

%.target: %.src
        @echo 'build $< > $@'

答案 1 :(得分:1)

简短的回答:你做不到。 Make确定在执行任何规则之前必须执行的所有规则。

更长的回答:也许你可以。正如你所说,你可以使用recursive Make明确地,或者秘密地通过构建一个你的makefile将include的文件(我正在看着你,Jack Kelly)。或者如果你能以某种方式获得gen将构建的文件列表,你可以围绕它编写规则。或者你可以采取这样的信念:

%.target: %.src
        build $< > $@

%.src: gen;