具有两个或多个依赖项的Makefile模式规则%.sas7bdat:%。sas%.dat

时间:2015-02-05 23:14:24

标签: makefile

我似乎无法在网上找到任何这样的例子,它似乎对我不起作用。你能在make文件中有一个模式规则,它有两个匹配的依赖项吗?

例如

%.sas7bdat: %.sas %.dat
  # build %.sas7bdat using %.sas and %.dat

具体来说,如果我运行make,则说明......

make: *** No rule to make target `sip84fp.sas7bdat', needed by `sipp84'.  Stop.

即使规则明确定义如上。

但是,将规则缩减到这个......

%.sas7bdat: %.sas

似乎有用吗?

1 个答案:

答案 0 :(得分:5)

是的,静态模式规则和隐式模式规则都可以有多个先决条件,其中包含对模式词干的%引用。

隐式模式规则与静态模式规则或普通非模式规则的不同之处在于,它们仅在没有先决条件(“无条件地生成此事物”)或者存在先决条件时才适用。

也就是说,如果需要构建的目标(如sip84fp.sas7bdat)需要更新,那么模式规则%.sas7bdat: %.sas %.dat确实是候选者。但是进行了检查:将sip84fp词干插入先决条件模式以生成sip84fp.sas sip84fp.dat。这两者都必须存在。如果它们不存在,则不再考虑该规则,并继续搜索其他规则。

这就是为什么最后你得到一条关于“无规则”的消息:它实际上意味着在忽略所有不适用的隐含规则后没有留下任何规则。

相反,在静态模式规则或普通规则下,如果目标与规则匹配,并且先决条件不存在,则必须更新先决条件。例如,如果您不存在foo.o: foo.cfoo.c,则不能删除该规则,因为它不是隐含的:该规则必须用于foo.o。然后,Make会查找构建foo.c的规则(可能找不到一个:错误将是没有规则来制作foo.c,而不是foo.o)。

请参阅GNU Make Manual中的主题Implicit Rule Search Algorithm

如果.dat文件可能不存在的预期行为,则必须以其他方式表达。例如,一种方法是使用一些外部依赖关系生成来制作形式的许多具体规则:

foo.sas7bdat: foo.dat

将其放入foo.d文件,include放入Makefile。如果您有一个名为TARGETS的变量,其中包含所有.sas7bdat个文件的名称,则可以包含所有.d依赖项文件,如下所示:

-include $(patsubst %.sas7bdat,%.d,$(TARGETS))

这与编译C相同。我们不会为C程序编写这样的模式规则:

%.o: %.c %.h
        # ... build steps

这是因为并非每个foo.c都有foo.h,因此该规则不适用于此类情况。相反,我们有:

%.o: %.c

然后任何其他依赖项,例如foo.o,取决于foo.h在其他地方表达。隐式规则仅匹配主要可交付成果:目标文件和翻译单元的“根”文件。