即使没有更改,Makefile 也会始终构建

Makefile always builds even when no changes

我在 tex 源文件上有以下 运行ning pdflatex 的 Makefile:

MAKEFLAGS += --warn-undefined-variables

deps := mydoc.tex mydoc.cls

mydoc.pdf: $(deps)

.PHONY: build
build:  $(deps) 
    pdflatex mydoc.tex mydoc.pdf

.PHONY: build
clean:  ## Delete misc
    rm -f mydoc.out mydoc.pdf mydoc.aux mydoc.log

当我 运行 make build 它总是 运行s pdflatex 即使 mydoc.tex 没有改变。

我的理解是make build应该说如果mydoc.tex没有改变就没什么可做的。我做错了什么?

首先,您已将目标 build 声明为 .PHONY。虚假目标的全部意义在于它总是被认为是过时的并且它的配方将被调用。所以,当然,食谱总是 运行.

即使您删除 .PHONY,食谱也将始终是 运行。你说 make 应该什么都不做是 mydoc.tex 没有改变......好吧,make 怎么知道 mydoc.tex 没有改变?与什么相比没有变化? Make 没有自己的数据库来告诉它上次 运行 的时间,以及文件上的所有时间戳在过去的某个时间是什么。它只是依赖于比较文件系统上文件的时间戳,因为它们现在存在。

当您编写规则时,它会告诉 make,如果任何先决条件的修改时间比目标更新,则目标已过时,配方应该 运行更新.

因此,如果您编写规则 build: mydoc.tex,make 将查看先决条件 mydoc.tex 是否比目标 build 更新。由于没有文件 build 并且从未创建过,因此 mydoc.tex 将始终被认为比 non-existent 文件更新,并且配方将始终为 运行.

您需要确保规则的目标是配方更新的文件。最佳做法是确保您编写的每个食谱(更新文件)都会更新 $@ 自动变量中包含的文件:

mydoc.pdf:  $(deps) 
        pdflatex mydoc.tex $@