整理一下关于 pdflatexxelatexlatexmk 的基本使用和配置。 这部分的中文资料其实比较少,因为大部分资料都在关注 LaTeX 应该怎么写,而不是怎么用命令去编译, 本文参考:

pdflatex & xelatex

基本使用

这里只考虑 pdflatexxelatex 的命令行基本用法,对于含有中文的文档只考虑使用 xelatex 编译。

最基本的用法如下,使用 pdflatexxelatex 编译指定的源文件,源文件的.tex后缀名可以省略。

1
2
pdflatex [options] main.tex
xelatex [options] main.tex

在源文件之前可以添加若干的选项,选项形如-<option1>-<option2>=<string>,具体选项见下文,注意必须在源文件之前,不允许出现在源文件之后。

默认情况下,编译成功后输出文件<filename>.pdf,还会产生很多各种后缀的杂项文件(例如<filename>.log), 它们存放的位置是执行命令的目录,而不是源文件所在的目录,可以使用下面的选项更改所有文件生成的位置。

注意:

  • 源文件的文件名不要含有\斜杠,对于路径分隔符只支持使用/
  • 如果遇到错误可能会输出 ? 并等待输入,可以输入QX回车退出(不区分大小写),或者直接ctrl+z退出。不同的退出方式有一些区别,但是不用管这些,因为编译报错内容的可读性实在太低了(和C++模板报错有得一拼),直接退出算了。

常见选项

pdflatexxelatex 命令的帮助信息列出了许多常见选项

1
2
pdflatex -help
xelatex -help

以下是对一些公共的主要选项的解释。

首先是关于编译过程如何处理交互和错误的:

  • -interaction=STRING:(常用)设置交互模式,用于控制编译过程中如何输出信息和处理错误,方便调试。STRING 包括以下几种模式:
    • errorstopmode: (默认)遇到错误时停止编译,等待用户输入或干预。
    • batchmode: 不在命令行中输出任何有关编译的信息,遇到错误时也不提示或等待用户输入,直接继续编译。
    • nonstopmode: 遇到错误时不会暂停编译,继续执行,直到最后显示出来错误的位置与内容。
    • scrollmode: 在屏幕上输出编译信息, 遇到错误会跳过, 但是会在找不到文件时停止编译并等待用户输入。
  • -file-line-error / -no-file-line-error:(常用)控制是否启用 file:line:error 样式的错误消息。启用此选项后,错误消息中会包含文件名和行号,方便快速定位错误。
  • -halt-on-error:(似乎不常用)遇到第一个错误时立即停止编译。使用这个选项时,当文档中出现任何错误,编译会中断,帮助更快定位问题。

然后是一些特殊需求的选项:

  • -synctex=NUMBER:(常用)是否启用 SyncTeX,用于将源文件与生成的 PDF 文件进行同步和双向跳转。NUMBER 控制同步信息的详细程度:默认0代表关闭,1代表开启,2代表开启并且更详细。这个选项对使用 LaTeX 编辑器(如 TeXShop 或 TeXworks)进行实时预览时非常有用,具体实现基于xxx.syntex.gz文件,在清理时需要保留。

  • -output-directory=DIR:(常用)将所有生成的文件输出到指定的目录 DIR 中(包括PDF文件),默认情况下会输出到当前目录中,这个选项可以避免生成的辅助文件(如 .log.aux 文件)混杂在源文件目录中,有助于管理输出文件。

  • -jobname=STRING:将编译任务的名称设置为 STRING,这会影响生成的输出文件的名称。默认情况下,输出文件名与输入的 .tex 文件名一致,可以通过此选项更改输出文件名。

  • -shell-escape / -no-shell-escape:启用或禁用 \write18 命令,它允许 LaTeX 执行外部的 shell 命令(如调用图形转换程序)。-shell-restricted 是一种更安全的方式,只允许执行预定义的受限命令。启用 shell escape 可能带来安全风险,因此默认情况下是禁用的。但是

注意:

  • 对于-output-directory=DIR选项的路径,如果是相对路径,那么相对的是执行命令是的目录,而不是源文件位置。编译器没有自动创建目录的能力,因此需要手动保证DIR目录已经存在。(latexmk类似选项的行为却不相同,见下文)
  • 对于-shell-escape选项,某些宏包(例如minted)在正常使用时需要启用此选项,pdflatex插入eps图片时可能也需要开启这个选项(测试发现,Windows上需要开启,否则编译报错,但是Linux上不需要)。

多次编译

对于复杂情况下的LaTeX文件编译,由于存在交叉引用和文献引用,仅仅执行一遍编译是不够的,需要进行多次编译,并且对于参考文献,还需要在其中搭配 bibtexbiber 编译,例如下面的示例源文件main.tex

1
2
3
4
5
6
7
8
9
10
% main.tex
\documentclass{article}
\begin{document}

text\cite{key1}

\bibliographystyle{plain}
\bibliography{reference.bib}

\end{document}

执行如下的多次编译

1
2
3
4
pdflatex main.tex
bibtex main.aux
pdflatex main.tex
pdflatex main.tex

大致解释一下每次编译的行为:

  • 第一次 pdflatex\cite 的的参数 (也就是使用到的 .bib 文件中的 key) 信息写入了 main.aux 文件
  • bibtex 读取哪些 key 被用到了, 然后根据这些 key 生成 main.bbl 文件
  • 第二次 pdflatex 读取 main.bbl 文件, 将 \cite 引用的正确的序号写进 main.aux
  • 第三次 pdflatex 读取 main.aux 文件, 在输出文件中使用正确的 \cite 编号

latexmk

介绍

除了手动执行多次编译,还有一种值得介绍的自动化工具:latexmk,它会自动探测并执行多次编译。 可以将其理解为针对\(\LaTeX\)定制的 make,它基于 Perl 实现,另一种类似的处理多次编译的工具是 MikTex 的 textify

最近还有一些人试图模仿latexmk开发新工具,例如基于Python实现的PyTeXMK,因为基于Perl实现的latexmk从各个方面来看都有点过时了。

基本使用

latexmk 支持如下命令行选项来指定编译引擎:

  • -pdf:(常见)当使用 pdflatex 的时候确保输出 PDF 文件(否则会生成dvi文件,很奇怪)
  • -xelatex:(常见)指定使用xelatex并生成 PDF 文件,关闭 DVI/PS 模式
  • -lualatex:(常见)指定使用lualatex并生成 PDF 文件,关闭 DVI/PS 模式

最基本的用法如下

1
2
3
latexmk -pdf main.tex
latexmk -xelatex main.tex
latexmk -lualatex main.tex

latexmk 提供如下清理命令

1
2
latexmk -c main.tex
latexmk -C main.tex

这个命令会自动清理所有相关的杂项文件,前者会保留pdf等输出文件,后者则会将pdf文件也删除,源文件有时也可以缺省,会自动检测。

使用-pv选项可以实现在 PDF 阅读器中进行预览,例如

1
latexmk -pdf -pv main.tex

使用-pvc选项可以在预览的同时开始持续更新,即程序会在终端中会保持等待状态,一旦检测到文件改动,就会自动进行编译。

1
latexmk -pdf -pvc main.tex

可以使用下面的命令检查latexmk执行具体指令时的具体行为(受到配置文件影响后的实际行为)

1
latexmk -commands

常见选项

使用latexmk -help可以查看到支持的选项,有很多细节上的选项不用管,下面只列出值得注意的选项:(对选项的解析同时支持---开头)

  • -auxidr=-aux-directory=DIR:指定辅助文件的存放位置,例如采用./.aux作为杂项文件的存放位置,目录不存在时可以自动创建,相对目录是相对于执行命令时所在的目录,而不是源文件所在目录。
  • -outdir=DIR-output-directory=DIR:指定输出位置:主要是pdf文件,也包括.syntex.gz文件
  • -cd:执行命令之前,切换到源文件所在的目录(在自动化脚本中可以调整实际命令执行的位置,这里也可以进行设置)
  • -r:指定latexmk读取的配置文件

此外,latexmk还会将一些选项直接传递给pdflatex等编译命令, 例如最常见的-synctex=1-interaction=nonstopmode-shell-escape等。

配置文件

latexmk 除了通过命令行参数设置具体的编译选项,也支持通过配置脚本设置,它会在如下位置寻找配置文件:

  • 当前LaTeX主文件所在目录,.latexmkrclatexmkrc 均可。
  • 任何其他位置,执行 latexmk 时由 -r 参数指定。
  • 个人家目录, $HOME/.latexmkrc,也支持 $HOME/.config/latexmk/latexmkrc
  • 系统目录,如 /usr/local/lib/latexmk/LatexMk ,视系统设置而定。

注意:

  • 配置文件的语法类似Perl,因为 latexmk 本身就是基于 Perl 实现的。
  • make 不同,即使没有配置文件,latexmk 也可以自动执行得很好。
  • Overleaf 等在线平台的编译方式是基于 latexmk 的,允许选择不同的编译命令(pdflatexxelatexlualatex),Overleaf 使用的配置文件看起来很复杂,但是平台提供了导出latexmk实际内容的办法

有几份配置文件可以参考:

其中有两个值经常被设置:

  • $pdf_mode 用于设置pdf生成模式,支持的值包括:(默认为0,参考配置文件都设置为5
    • 0:代表不生成 pdf
    • 1:代表使用 $pdfltex 选项的命令
    • 2:代表使用 $ps2pdf 选项的命令
    • 3:代表使用 $dvipdf 选项的命令
    • 4:代表使用 $lualatex 选项的命令
    • 5:代表使用 $xelatex 选项的命令
  • $bibtex_use用于设置 bibtex 或 biber 的使用规则,支持的值包括:(默认为1,普遍都设置为1.5
    • 0: 不使用 bibtex 或 biber; 清空的时候不会清空 .bbl 文件
    • 1: 只有 bib 文件存在才使用 bibtex 或 biber;清空的时候不会清空 .bbl 文件
    • 1.5: 只有 bib 文件存在才使用 bibtex 或 biber;当 bib 文件存在时会清空 bbl,否则不会清空
    • 2: 有必要更新bbl文件时,运行 bibtex 或 biber,无需测试 bib 文件存在与否;清空删除 bbl

最终选择没有使用.latexmkrc,直接使用latexmk命令加上一些选项就足够了,而且在没搞懂的情况下,盲目进行任何配置都可能导致编译错误。

LaTeX的编译真的是天坑,系统平台差异,版本差异就不说了,各种编译器之间的差异,各种缓存文件没清理干净就容易报错,而且输出信息乱七八糟,一大堆问题,比C++的编译系统都混乱得多。