我有一个如下所示的乳胶项目:
project/
|-- main.tex
|-- main.bib
|-- preamble.tex
|-- preamble.fmt
|-- makefile
前言(preamble.tex
)正在预编译为preamble.fmt
。main.bib
是使用file contents
中的环境生成的main.tex
。
这就是我的makefile
TEX = pdflatex -shell-escape -interaction=nonstopmode -file-line-error
PRE = $(TEX) -ini -job-name="preamble" "&pdflatex preamble.tex\dump"
BIB = bibtex
.PHONY: all view
all : main.pdf
view :
open main.pdf
main.pdf : main.tex preamble.fmt main.bbl main.blg
$(TEX) main.tex
main.bbl main.blg : main.bib main.aux
$(BIB) main
main.aux : main.tex
$(TEX) main.tex
main.bib : main.tex
$(TEX) main.tex
preamble.fmt : preamble.tex
$(PRE) preamble.tex
问题在于bibtex
依赖于main.aux
生成的,并且main.aux
每次运行时都会重新生成pdftex
。这导致每次运行时都会重新生成 bibtex 文件,从而导致 makefile$(TEX) main.tex
再次运行(它认为.bbl
和.blg
文件已更改,因为它查看了它们的编辑时间)。
因此,基本上每次我调用make all
latex 时都会编译两次,即使文档中任何地方的引用都没有更改(因此这没有必要)。
有没有办法让我知道make
它只编译两次,如果有一个实际的改变到.aux
和.bib
文件。也许通过检查 md5 总和?
我对整个 makefile 还不太熟悉,所以我想在这里问一下。这可能有点离题,但我认为这个网站上的 latex 专家可能会有答案。
答案1
latexmk
就是您要找的答案。
众所周知,使用 Makefile 很难“正确”地使用 LaTeX,因为它可能需要多次编译(例如更新.aux
文件)才能获得最终结果。一般的Makefile(与为特定文档量身定制的 Makefile 不同)非常难,这就是为什么有现成的解决方案。其中,latexmk
包含在普通 LaTeX 发行版中,这就是为什么我认为它是首选。
诀窍是为您可能拥有的每个自定义步骤 x-to-TeX(或 x-to-PDF 或其他)提供一个 Makefile 规则,并找出latexmk
所有与 LaTeX 相关的内容,同时依靠 Makefile 完成其余部分(通过-use-make
)。
# You want latexmk to *always* run, because make does not have all the info.
# Also, include non-file targets in .PHONY so they are run regardless of any
# file of the given name existing.
.PHONY: MyDoc.pdf all clean
# The first rule in a Makefile is the one executed by default ("make"). It
# should always be the "all" rule, so that "make" and "make all" are identical.
all: MyDoc.pdf
# CUSTOM BUILD RULES
# In case you didn't know, '$@' is a variable holding the name of the target,
# and '$<' is a variable holding the (first) dependency of a rule.
# "raw2tex" and "dat2tex" are just placeholders for whatever custom steps
# you might have.
%.tex: %.raw
./raw2tex $< > $@
%.tex: %.dat
./dat2tex $< > $@
# MAIN LATEXMK RULE
# -pdf tells latexmk to generate PDF directly (instead of DVI).
# -pdflatex="" tells latexmk to call a specific backend with specific options.
# -use-make tells latexmk to call make for generating missing files.
# -interaction=nonstopmode keeps the pdflatex backend from stopping at a
# missing file reference and interactively asking you for an alternative.
MyDoc.pdf: MyDoc.tex
latexmk -pdf -pdflatex="pdflatex -interaction=nonstopmode" -use-make MyDoc.tex
clean:
latexmk -CA
此设置对于通过 引用的任何内容均能完美运行\include
。
但是,\include
可能并不适用于所有情况。首先,它不可嵌套(即一个\include
文件可能不嵌套\include
另一个文件)。它还会自动将内容添加\clearpage
到文档中,即\include
内容会开始一个新页面。它还具有优点,例如如果内容被修改,则可以缩短重建时间,但有时您需要嵌套,或者引用文件的内容应该嵌入到页面中。
你需要\input
这个。
遗憾的是,这\input
会破坏构建。如果pdflatex
遇到丢失的\input
文件,它会生成一个错误(而不是像 那样的警告\include
),并停止编译。是的,latexmk
将生成文件并重新启动pdflatex
,但这是低效的,并且如果您有多个这样的文件引用,则会完全中断,因为最终编译将以“重新运行次数过多”消息结束。
約翰·柯林斯' 我对有关此问题的提问的回答提供了一种解决方法:
\newcommand\inputfile[1]{%
\InputIfFileExists{#1}{}{\typeout{No file #1.}}%
}
此宏生成警告而不是错误直线\input
,并允许latexmk
在第一遍中生成所有缺失的文件。
笔记:%.pdf: %.tex
由于内部原因和复杂原因,一旦开始\includeonly
在文档中使用具有通用目标的规则,就会给您带来麻烦。这就是我使用特定规则而不是通用规则的原因。
其实latexmk
我还可以推荐一种替代方案。如果你正在考虑更复杂的项目设置,你可以考虑CMake,Kenneth Moreland 对此做出了出色的贡献使用LATEX.cmake模块。
然而,这有点太复杂了,无法在本答案的范围内提供操作方法。
答案2
TeX 项目的公开 Makefile
这里有一些 TeX 项目的 makefile 示例。欢迎添加更多。
作者:Matthias Vallentin
许可证:CC BY-NC-SA 4.0
关联:https://github.com/mavam/stat-cookbook/blob/master/Makefile
包括input
指令、独立图表、参考书目latexmk
和重播。stat-cookbook
存储库的一部分,提供了一些有关事物如何协同工作的背景信息。
作者:Yannick Copin
许可证:未提及
关联:https://web.archive.org/web/20061205102406/http://snovae.in2p3.fr/ycopin/soft/Makefile.latex
批量处理.tex
文件,包括参考书目。支持无重新运行latexmk
。
作者:Chris Rost
许可证:未提及
关联:https://stuff.mit.edu/people/jcrost/latexmake.html
作者:Kyle Woerner 等人
许可证:未提及
链接(第 5 页):https://oceanai.mit.edu/k_w/latex_lab/lab_latex_8.pdf
作者:Petter Kallstrom
许可证:CC BY-SA 3.0
答案3
答案4
我使用的一个技巧是,从常规调用 (pdf)latex 时,使用 %.log 文件的 shell 循环Makefile
检查是否存在字符串,以确保重新运行 LaTeX 所需的次数来解析所有引用。while
grep
Rerun to get
我的Makefile
通常开始是这样的:
# requires GNU make
SHELL=/bin/bash
.DELETE_ON_ERROR:
%.pdf %.aux %.idx: %.tex
pdflatex $<
while grep 'Rerun to get ' $*.log ; do pdflatex $< ; done
%.ind: %.idx
makeindex $*
%.bbl: %.aux
bibtex $*
%.pdftex %.pdftex_t: %.fig
fig2dev -L pdftex_t -p $*.pdftex $< $*.pdftex_t
fig2dev -L pdftex $< $*.pdftex
事情变得棘手的是涉及 %.aux 作为依赖项的规则,这可能导致循环依赖。