make 无法识别 Makefile 中的目标

时间:2021-03-10 16:33:21

标签: makefile gnu-make makefile-errors

我经历了以下情况:

$ cat Makefile
POLYSCRIPTER=${HOLDIR}/Manual/Tools/polyscripter
UMAP=${HOLDIR}/Manual/Tools/umap

all:    tactics.pdf

%.tex:  %.stex
        ${POLYSCRIPTER} ${UMAP} <%.stex >%.tex

tactics.pdf:    %.tex
        pdflatex tactics.tex
        bibtex tactics
        pdflatex tactics.tex
        pdflatex tactics.tex


clean:
        rm tactics.{aux,bbl,blg,log,pdf,tex,ui,uo}
$ make
make: *** No rule to make target '%.tex', needed by 'tactics.pdf'.  Stop.

有一个 %.tex 目标。我做错了什么?

这是 GNU Make 4.3。

更新:我想表达的是:从相应的 %.stex 文件中创建任何 %.tex 文件,然后从包含所有 %.tex 文件的 latexing strategy.tex 生成tactic.pdf。

UPDATE2:我编辑了一行,学习如何引用依赖项和目标:

${POLYSCRIPTER} ${UMAP} <$< >$@                   

1 个答案:

答案 0 :(得分:1)

模式规则是告诉 make 如何构建目标的模板。它不为 make 提供要构建的目标列表:它只是构建目标的方法。所以这个模式规则:

%.tex:  %.stex

不告诉 make “去文件系统并找到所有与 %.stex 匹配的文件,这些文件可以转换为 .tex 文件并执行此操作”。它告诉 make,“嘿,如果您发现出于某种原因想要构建一个与模式 %.tex 匹配的目标,那么您可以通过以下方式构建它”。

另一方面:

tactics.pdf:    %.tex

根本不是模式规则。模式规则必须在目标名称中包含 %。这是一个直截了当的显式规则,恰好依赖于名为 %.tex 的文件。 Make 不知道以任何方式构建名为 %.tex 的文件(因为没有按字面命名的文件 %.stex,因此您上面定义的模式规则不适用)。

你可以这样做:

tactics.pdf: *.tex

使用shell globbing。这更接近,因为它告诉 make 一组 .tex 文件要构建。但这也不起作用,因为当您第一次运行 make 时,没有 .tex 文件存在!因此,此表达式将不匹配任何文件,并且您将拥有一组空的先决条件。

您需要做的是 (1) 找到您要构建的所有源文件:

STEX := $(wildcard *.stex)

然后 (2) 将其转换为您要构建的目标集:

TEX := $(patsubst %.stex,%.tex,$(STEX))

然后 (3) 将这些目标列为 PDF 文件的先决条件:

tactics.pdf: $(TEX)

现在,make 将使用您的模式规则来确定如何构建这些 .tex 文件。