我似乎无法在网上找到任何这个例子,它似乎对我不起作用.你能在make文件中有一个模式规则,它有两个匹配的依赖项吗?
例如
%.sas7bdat: %.sas %.dat
# build %.sas7bdat using %.sas and %.dat
Run Code Online (Sandbox Code Playgroud)
具体来说,如果我运行make,它说明......
make: *** No rule to make target `sip84fp.sas7bdat', needed by `sipp84'. Stop.
Run Code Online (Sandbox Code Playgroud)
即使规则明确如上所述.
但是,减少规则到这个......
%.sas7bdat: %.sas
Run Code Online (Sandbox Code Playgroud)
似乎工作?
是的,静态模式规则和隐式模式规则都可以有多个先决条件,其中包含%对模式主干的引用.
隐式模式规则与静态模式规则或普通非模式规则的不同之处在于它们只有在没有先决条件("无条件地使这个东西")或者存在先决条件时才适用.
也就是说,如果需要构建的目标,比如sip84fp.sas7bdat需要更新,那么模式规则确实%.sas7bdat: %.sas %.dat是候选者.但是要进行检查:将sip84fp茎插入先决条件模式中以生成sip84fp.sas sip84fp.dat.这两者都必须存在.如果它们不存在,则不再考虑该规则,并继续搜索其他规则.
这就是为什么最后你得到一条关于"无规则"的消息:它实际上意味着在忽略所有不适用的隐含规则之后没有留下任何规则.
相反,在静态模式规则或普通规则下,如果目标与规则匹配,并且先决条件不存在,则必须更新先决条件.例如,如果你有foo.o: foo.c和foo.c该规则必须用于:不存在,该规则不能因为它不是隐含扔掉foo.o.然后,Make将查找构建的规则foo.c(并且可能找不到一个:错误将是没有规则要做foo.c,而不是foo.o).
请参阅GNU Make Manual中的隐式规则搜索算法主题.
如果.dat文件可能不存在的预期行为,则必须以其他方式表达.例如,一种方法是使用一些外部依赖关系生成来制作表单的许多具体规则:
foo.sas7bdat: foo.dat
Run Code Online (Sandbox Code Playgroud)
把它放入一个foo.d文件,然后include放入Makefile.如果你有一个名为TARGETS包含所有.sas7bdat文件名称的变量,你可以包含它们的所有.d依赖文件,如下所示:
-include $(patsubst %.sas7bdat,%.d,$(TARGETS))
Run Code Online (Sandbox Code Playgroud)
这与编译C相同.我们不会为C程序编写这样的模式规则:
%.o: %.c %.h
# ... build steps
Run Code Online (Sandbox Code Playgroud)
这是因为并非所有人foo.c都有foo.h,因此该规则不适用于此类情况.相反,我们有:
%.o: %.c
Run Code Online (Sandbox Code Playgroud)
然后任何其他依赖关系,如foo.o取决于在foo.h别处表达.隐式规则仅匹配主要可交付物:目标文件和翻译单元的"根"文件.