如何正确地‘制作’乳胶项目?

如何正确地‘制作’乳胶项目?

我有一个如下所示的乳胶项目:

project/
   |-- main.tex
   |-- main.bib
   |-- preamble.tex
   |-- preamble.fmt
   |-- makefile

前言(preamble.tex)正在预编译为preamble.fmtmain.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 alllatex 时都会编译两次,即使文档中任何地方的引用都没有更改(因此这没有必要)。

有没有办法让我知道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

关联:https://en.wikibooks.org/wiki/Make/Examples

答案3

有答案类似的问题。 特征:

  • 展示如何在必要时使用带有受控时间戳的校验和文件。
    • 在那里,它不是.aux要而是要.bbl索引文件,但你明白了。.nlo.nls
  • 另外建议latexmk
    • 展示如何latexmk在 GNU Makefile 中使用自动依赖跟踪。
    • 包使用的latexmkrc自定义文件的示例配置。makeindexnomencl

玩得开心。

答案4

我使用的一个技巧是,从常规调用 (pdf)latex 时,使用 %.log 文件的 shell 循环Makefile检查是否存在字符串,以确保重新运行 LaTeX 所需的次数来解析所有引用。whilegrepRerun 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 作为依赖项的规则,这可能导致循环依赖。

相关内容