强制使用更具体的规则

She*_*hep 5 makefile

我似乎无法强迫make使用更具体的规则.我正在使用版本3.81,它应该使用它所使用的第一个规则,但是当更具体的规则具有必须用另一个规则构造的依赖性时,这似乎不起作用.这是基本图片:

#rule for the dependency of the more specific rule
%.bbl: %.tex *.bib
    <build the .bbl file>

#more specific rule
some_prefix%.pdf: some_prefix%.tex some_prefix%.bbl
    <build the .pdf>

#general rule
%.pdf: %.tex
    <build the .pdf>
Run Code Online (Sandbox Code Playgroud)

所以基本上我想make.bbl文件构建pdf,如果它匹配some_prefix,否则使用更一般的规则.不幸的是,除非我删除对.bbl文件的依赖,否则永远不会调用第二条规则.

我似乎能够通过添加一般规则的黑客来使其工作:

%.pdf: %.tex %.hack
    <make the pdf with a more general rule>

%.hack: %.tex
    touch $@
Run Code Online (Sandbox Code Playgroud)

这似乎工作,.hack文件被自动删除,但顾名思义,这是一个可怕的黑客.似乎必须有一些更好的方法来强制使用特定规则.

如何强制make使用更具体的规则?把它放在第一位似乎没有帮助.

Mad*_*ist 4

您忘记了隐式规则搜索算法的一个非常重要的方面:make 总是更喜欢具有显式目标先决条件的隐式规则,而不是其中先决条件模式之一与已知目标不匹配并且必须通过规则链接构建的隐式规则。请参阅算法中的步骤 #5 与步骤 #6。这与正常的“makefile 中的第一个”模式规则排序不同。

如果您想执行此操作,则必须将bbl规则编写为静态模式规则,而不是真正的模式规则,以便文件bbl是显式目标而不是隐式目标。

  • 您需要“bbl”文件列表:“BBL_FILES = foo.bbl bar.bbl biz.bbl”,然后将模式规则介绍更改为“$(BBL_FILES) : %.bbl : %.tex *.bib”(以及规则的其余部分)。现在它是静态模式规则。 (3认同)
  • 我应该指出静态模式规则并不是解决这个问题的唯一方法。你只需要以某种方式让这些“bbl”文件“已知”即可。在 makefile 中将它们(明确地)列为目标或先决条件_任何地方_就足够了。例如,考虑到上面的变量分配,您只需编写一个新规则“make_bbls:$(BBL_FILES)”就足够了。你不需要任何东西来依赖`make_bbls`;只要有这条规则存在就足够了。 (3认同)