具有两个或多个依赖项的 Makefile 模式规则 %.sas7bdat: %.sas %.dat
Makefile pattern rule with two or more dependencies %.sas7bdat: %.sas %.dat
我似乎无法在网上找到任何这方面的例子,而且它似乎对我不起作用。能否在具有两个匹配依赖项的 make 文件中使用模式规则?
例如
%.sas7bdat: %.sas %.dat
# build %.sas7bdat using %.sas and %.dat
具体来说,如果我 运行 制作,它说明...
make: *** No rule to make target `sip84fp.sas7bdat', needed by `sipp84'. Stop.
尽管规则定义如上。
但是,将规则缩减为...
%.sas7bdat: %.sas
好像有用?
是的,静态模式规则和隐式模式规则都可以有多个先决条件,其中包含对模式主干的 %
引用。
隐式模式规则不同于静态模式规则或普通的非模式规则,因为它们仅在没有先决条件 ("unconditionally make this thing") 或存在先决条件时适用。
也就是说,如果需要构建一个target,比如sip84fp.sas7bdat
需要更新,那么模式规则%.sas7bdat: %.sas %.dat
确实是一个候选。但是进行了检查:sip84fp
词干被插入到先决条件模式中以生成 sip84fp.sas sip84fp.dat
。这两者都必须存在。如果它们不存在,则不考虑该规则,并继续搜索其他规则。
这就是为什么最后您会收到一条关于 "no rule" 的消息:这实际上意味着在忽略所有不适用的隐式规则后没有留下任何规则。
相比之下,在静态模式规则或普通规则下,如果目标匹配规则,并且先决条件不存在,则必须更新先决条件。例如,如果您有 foo.o: foo.c
而 foo.c
不存在,则不能丢弃该规则,因为它不是隐式的:该规则必须用于 foo.o
。然后 Make 将寻找构建 foo.c
的规则(并且可能找不到:错误将是没有规则可以构建 foo.c
,而不是 foo.o
)。
请参阅 GNU Make 手册中的主题 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
在其他地方表达。隐式规则仅匹配主要可交付成果:目标文件和翻译单元的 "root" 文件。
我似乎无法在网上找到任何这方面的例子,而且它似乎对我不起作用。能否在具有两个匹配依赖项的 make 文件中使用模式规则?
例如
%.sas7bdat: %.sas %.dat
# build %.sas7bdat using %.sas and %.dat
具体来说,如果我 运行 制作,它说明...
make: *** No rule to make target `sip84fp.sas7bdat', needed by `sipp84'. Stop.
尽管规则定义如上。
但是,将规则缩减为...
%.sas7bdat: %.sas
好像有用?
是的,静态模式规则和隐式模式规则都可以有多个先决条件,其中包含对模式主干的 %
引用。
隐式模式规则不同于静态模式规则或普通的非模式规则,因为它们仅在没有先决条件 ("unconditionally make this thing") 或存在先决条件时适用。
也就是说,如果需要构建一个target,比如sip84fp.sas7bdat
需要更新,那么模式规则%.sas7bdat: %.sas %.dat
确实是一个候选。但是进行了检查:sip84fp
词干被插入到先决条件模式中以生成 sip84fp.sas sip84fp.dat
。这两者都必须存在。如果它们不存在,则不考虑该规则,并继续搜索其他规则。
这就是为什么最后您会收到一条关于 "no rule" 的消息:这实际上意味着在忽略所有不适用的隐式规则后没有留下任何规则。
相比之下,在静态模式规则或普通规则下,如果目标匹配规则,并且先决条件不存在,则必须更新先决条件。例如,如果您有 foo.o: foo.c
而 foo.c
不存在,则不能丢弃该规则,因为它不是隐式的:该规则必须用于 foo.o
。然后 Make 将寻找构建 foo.c
的规则(并且可能找不到:错误将是没有规则可以构建 foo.c
,而不是 foo.o
)。
请参阅 GNU Make 手册中的主题 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
在其他地方表达。隐式规则仅匹配主要可交付成果:目标文件和翻译单元的 "root" 文件。