在 GNU Make 模式规则中使用通配符

在 GNU Make 模式规则中使用通配符

假设doc.pdf是目标。

以下规则在更新doc.pdf时触发重新生成,但在根本不存在doc.refer时也很高兴:doc.refer

doc.pdf: doc.mom $(wildcard doc.refer)
    pdfmom -e -k < $< > $@

然而,以下模式规则并不能完成相同的任务(正确生成 PDF,但更改时不会触发重建doc.refer):

%.pdf: %.mom Makefile $(wildcard %.refer)
    pdfmom -e -k < $< > $@

我怀疑该wildcard命令是在%字符展开之前执行的。我该如何解决这个问题?

答案1

GNU Make 函数wildcard采用 shell 通配模式并将其扩展为与该模式匹配的文件。该模式%.refer不包含任何 shell 通配模式。

你可能想要类似的东西

%.pdf: %.mom %.refer
        pdfmom -e -k < $< > $@

%.pdf: %.mom
        pdfmom -e -k < $< > $@

当有一个时,第一个目标将被调用来制作 PDF 文件.mom .refer可用于文档基本名称的文件。当没有.refer可用文件时,将调用第二个目标。

这些目标的顺序很重要。

答案2

你也许可以使用二次扩张:

.SECONDEXPANSION:
%.pdf: %.mom Makefile $$(wildcard %.refer)
    pdfmom -e -k < $< > $@

答案3

GNU Make 评估所有函数以生成模式规则的内部表示。

因此,$(wildcard %.refer)您的规则被评估为空字符串。

实现目标的唯一方法是利用规则排序,例如 善行难陀的解决方案建议(info "(make)Pattern Match")

10.5.4 How Patterns Match

   It is possible that more than one pattern rule will meet these
criteria.  In that case, 'make' will choose the rule with the shortest
stem (that is, the pattern that matches most specifically).  If more
than one pattern rule has the shortest stem, 'make' will choose the
first one found in the makefile.

相关内容