我注意到 makefile 有时能完成它们的工作(它们编译文档),有时却不能(然后它们声称什么都没有改变)。在后一种情况下,根据 makefile 的外观,根本没有输出,或者会提示一条消息,说明没有什么可做的。在我的一个示例中,它告诉““example.pdf” ist bereits aktuell。”(翻译为:““example.pdf”已经是最新的。”)
我认为后者是特征(不是错误)以节省时间,以防源代码没有改变时调用 make(因为那时,当然,实际上没有什么可做的)。然而,有时这种行为是错误的,因为 LaTeX 源代码做过改变。
我一直在想(并调查了一段时间)为什么 make 脚本在代码更改后仍无法重新编译。我之所以想知道这个问题的主要原因当然是我想强制脚本重新编译。在写这个问题的过程中,我终于搞清楚了(!),但仍有一些问题没有解决。
首先,是我的观察和回答,然后是未解决的问题。
考虑以下 MWE:
\documentclass{beamer}
\begin{document}
\begin{frame}
frame 1
\end{frame}
\end{document}
现在,考虑两种 makefile 变体,它们都名为“makefile”。注意:标签后面的行必须以制表符开头,而不是以空格开头。
变体 1:
example.pdf:
pdflatex example.tex
pdflatex example.tex
变体 2:
example:
pdflatex example.tex
pdflatex example.tex
为了验证我的观察,您需要运行两个 makefile 变体。为了方便起见(即为了防止一直重命名文件),您可以只调用第一个变体 makefile1,第二个变体 makefile2,然后运行make -f makefile1
或make -f makefile2
。
显然,makefile 中使用的标签(即“example.pdf:”与“example:”)决定了它们是否可能不起作用。也就是说,makefile 的变体 2(不使用标签中的“.pdf”结尾)将总是无论如何都要重新编译(这可以通过多次调用脚本而不接触任何 tex 文件来轻松验证)。只有变体 1 有时(或总是(?),见下文)声称什么都不做。
这已经回答了我关于如何强制重新编译的问题(即仅使用不带 .pdf 结尾的 makecript 标签)。不过,我仍然有以下问题问题:
(A)为什么会这样?标签结尾为“.pdf”的语义是什么?更重要的是,我该如何找到它?我尽了最大努力寻找 LaTeX makefile 手册或相关的 stackoverlow 问题,但真的找不到任何事物! 似乎没有人遇到我的问题,尽管 LaTeX 源代码确实发生了变化,但脚本却无法运行。
(二)我尽力找到了一个 MWE 示例,证明了 makescript 变体 1 有时做重新编译,但并非在所有情况下都应重新编译。不过,我还是失败了。在创建这篇文章时,我无法重现这种行为。相反,makefile 变体 1 确实总是声称只要 PDF 存在,就什么也不做——无论代码中的更改有多严重(即使我删除了编译 PDF 中存在的所有内容并创建了全新的内容,它仍然不会重新编译)。因此我的问题是:我之前是否只是记错了/错误地识别了它,变体 1 有时也会重新编译(即使 PDF 存在),还是真的绝不只要结果 PDF 存在,它就会重新编译吗?如果它有时确实会重新编译(这是我在撰写本文之前所相信的),我会很高兴有 MWE,只是出于好奇。
谢谢你!
答案1
首先,make 不是 LaTeX 专用的工具,而是用于构建内容的通用工具。这很有用,因为它可以与许多不同的工具一起使用,但不幸的是,这也意味着您必须手动找出依赖项(或与 make 结合使用其他工具,但这超出了本文的范围)。
其次,目标名称不仅仅是标签。它们通常是要构建的文件的名称。
make 的工作是首先确定目标是否存在,如果存在则确定它是否“最新”。如果不存在或“过期”,则构建它,如果是最新的则跳过它。
要确定它是否是最新的,它会查看目标之间的依赖关系以及非目标文件。如果目标的依赖关系本身就是目标,那么将首先查看它们。如果目标比其依赖关系旧,那么它将被视为“过时”并将被重建。
您的问题是您的目标没有依赖项。因此,如果目标文件存在,则它始终被视为“最新的”。您需要在源文件上添加依赖项。
关于文档,make 有多种实现,具有不同的功能,但目前最常见的可能是 gnu make。您可以在以下位置找到它的文档https://www.gnu.org/software/make/manual/make.html
* 还存在一些不对应文件但始终运行的“虚假”目标,但这超出了本文的讨论范围。