make 无法识别 Makefile 中的目标

make does not recognize target in Makefile

我遇到了以下情况:

$ 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 tactics.tex 生成 tactics.pdf文件。

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

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

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

%.tex:  %.stex

不会告诉 make “去文件系统并找到所有匹配 %.stex 的文件,这些文件可以变成 .tex 文件并执行此操作”。它告诉 make,“嘿,如果你发现出于某种原因你想构建一个匹配模式 %.tex 的目标,那么这里有一种构建它的方法”。

另一方面:

tactics.pdf:    %.tex

根本不是模式规则。模式规则 必须 在目标名称中有一个 %。这是一个直接明确的规则,恰好依赖于一个名为 %.tex 的文件。 Make 不知道有什么方法可以构建名为 %.tex 的文件(因为没有按字面意思命名的文件 %.stex,因此您在上面定义的模式规则不适用)。

您可以这样做:

tactics.pdf: *.tex

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

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

STEX := $(wildcard *.stex)

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

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

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

tactics.pdf: $(TEX)

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