LaTeX 命令行编译
整理一下关于 pdflatex
,xelatex
和
latexmk
的基本使用和配置。
这部分的中文资料其实比较少,因为大部分资料都在关注 LaTeX
应该怎么写,而不是怎么用命令去编译, 本文参考:
- LaTeX技巧912:使用latexmk自动编译LaTeX
- 在终端中编译 LaTeX
- latexmk 的学习
- Latex 编译和编写方案配置 — latexmk + latexworkshop
- Using Latexmk
pdflatex & xelatex
基本使用
这里只考虑 pdflatex
和 xelatex
的命令行基本用法,对于含有中文的文档只考虑使用 xelatex
编译。
最基本的用法如下,使用 pdflatex
和 xelatex
编译指定的源文件,源文件的.tex
后缀名可以省略。
1
2pdflatex [options] main.tex
xelatex [options] main.tex
在源文件之前可以添加若干的选项,选项形如-<option1>
、-<option2>=<string>
,具体选项见下文,注意必须在源文件之前,不允许出现在源文件之后。
默认情况下,编译成功后输出文件<filename>.pdf
,还会产生很多各种后缀的杂项文件(例如<filename>.log
),
它们存放的位置是执行命令的目录,而不是源文件所在的目录,可以使用下面的选项更改所有文件生成的位置。
注意:
- 源文件的文件名不要含有
\
斜杠,对于路径分隔符只支持使用/
- 如果遇到错误可能会输出
?
并等待输入,可以输入Q
或X
回车退出(不区分大小写),或者直接ctrl+z
退出。不同的退出方式有一些区别,但是不用管这些,因为编译报错内容的可读性实在太低了(和C++模板报错有得一拼),直接退出算了。
常见选项
pdflatex
和 xelatex
命令的帮助信息列出了许多常见选项 1
2pdflatex -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文件编译,由于存在交叉引用和文献引用,仅仅执行一遍编译是不够的,需要进行多次编译,并且对于参考文献,还需要在其中搭配
bibtex
或 biber
编译,例如下面的示例源文件main.tex
:
1 | % main.tex |
执行如下的多次编译 1
2
3
4pdflatex 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
3latexmk -pdf main.tex
latexmk -xelatex main.tex
latexmk -lualatex main.tex
latexmk 提供如下清理命令
1 | 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主文件所在目录,
.latexmkrc
或latexmkrc
均可。 - 任何其他位置,执行
latexmk
时由-r
参数指定。 - 个人家目录,
$HOME/.latexmkrc
,也支持$HOME/.config/latexmk/latexmkrc
。 - 系统目录,如
/usr/local/lib/latexmk/LatexMk
,视系统设置而定。
注意:
- 配置文件的语法类似Perl,因为
latexmk
本身就是基于 Perl 实现的。 - 和
make
不同,即使没有配置文件,latexmk
也可以自动执行得很好。 - Overleaf 等在线平台的编译方式是基于
latexmk
的,允许选择不同的编译命令(pdflatex
,xelatex
,lualatex
),Overleaf 使用的配置文件看起来很复杂,但是平台提供了导出latexmk实际内容的办法
有几份配置文件可以参考:
其中有两个值经常被设置:
$pdf_mode
用于设置pdf生成模式,支持的值包括:(默认为0
,参考配置文件都设置为5
)0
:代表不生成 pdf1
:代表使用$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++的编译系统都混乱得多。