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

发布于 2025-01-16 19:03:56 字数 484 浏览 4 评论 0原文

我有以下 Makefile 用于在 tex 源文件上运行 pdflatex:

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 时,它总是运行 pdflatex,即使 mydoc.tex 没有更改。

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

I have the following Makefile for running pdflatex on tex source files:

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

When I run make build it always runs pdflatex even though mydoc.tex has not changed.

My understanding is make build should say there is nothing to do if mydoc.tex has not changed. What am I doing wrong?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

乖乖公主 2025-01-23 19:03:56

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

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

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

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

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

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

First, you've declared the target build to be .PHONY. The entire point of a phony target is that it will always be considered out of date and its recipe will be invoked. So, of course the recipe is always run.

Even if you remove the .PHONY though, the recipe will always be run. You say make should do nothing is mydoc.tex has not changed... well, how can make know that mydoc.tex has not changed? Not changed compared to what? Make doesn't have its own database that tells it the last time it ran, and what all the timestamps on the files were at some time in the past. It simply relies on comparing timestamps of files on the filesystem as they exist now.

When you write a rule it tells make, if any of the prerequisites have a newer modification time than the target, then the target is out of date and the recipe should be run to bring it up to date.

So if you write a rule build: mydoc.tex make will look to see if the prerequisite mydoc.tex is newer than the target build. Since there is no file build and one is never created, mydoc.tex will always be considered newer than a non-existent file, and the recipe will always be run.

You need to be sure that the target of the rule is the file that is updated by the recipe. Best practice is to ensure that every recipe you write (that updates a file) updates the file contained in the $@ automatic variable:

mydoc.pdf:  $(deps) 
        pdflatex mydoc.tex $@
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文