写这篇东西的起因很简单——上周帮一位师弟看配置好的LaTeX环境他打开VS Code点了一下绿色的Build LaTeX project按钮几秒钟之后底部弹出一条红色的报错Recipe terminated with error. Retry building the project.讲真这条报错对刚接触LaTeX的人来说劝退效果拉满。看起来好像什么都没发生页面没出PDF日志区也没跳出一大段警报就一行英文甩在脸上翻译成人话就是构建流程挂了要不要重试。可问题在于它没说哪里挂了也没说为什么挂。对新手来说这一行字和你的电脑炸了没有区别。这篇文章不打算讲什么高深的理论我把自己从看到这条报错就头大到能够在三分钟之内定位问题的完整思路写出来包括报错的本质、日志怎么看、最常见的几个坑、以及一套能稳定复现成功编译的VS Code LaTeX配置方案。不管你是刚装好LaTeX正准备写第一篇论文还是已经被这个报错折磨了一晚上的老倒霉蛋这篇文章都值得你花十分钟看完。1. 报错现象描述与最初的判断思路先承认一件事我第一次遇到这个报错的时候第一反应是把VS Code关了重开。没解决问题又试了把整个项目文件夹重新打开还是没用。后来把%TEMP%目录下的临时文件全删了一通依旧报错。这时候我才冷静下来意识到一个问题——这个错误信息本身只是一种结果不是原因。LaTeX Workshop这个VS Code扩展在执行构建任务时会把整个流程拆成几步先生成.tex源码对应的中间文件然后调用底层的编译引擎比如pdflatex、xelatex或latexmk去编译最后再把生成的PDF文件交给内置的查看器预览。任何一步出了岔子扩展都只会统一抛出一句Recipe terminated with error。换句话说这句报错的本质是LaTeX Workshop在执行一条预定义好的构建命令时这条命令的退出码不是0。理解到这层整个排查思路就清晰多了。我不用再对着Retry building这几个单词发呆而是要去回答三个更具体的问题VS Code到底执行了哪条命令这条命令在哪个环节失败了失败的具体原因是什么这三个问题每一个都能在VS Code的输出面板里找到答案。对就是那个平时被大多数人忽略的输出面板——LaTeX Workshop 的所有运行日志都往那里扔。我个人的建议是遇到这个报错的第一件事不是关重开而是立刻打开输出面板看清楚日志的最后几行。这一步能省掉后续80%的无头苍蝇式排查。不过日志也不是随便看看就行的。新手最容易犯的错是打开日志之后发现满屏都是英文就慌神了觉得这么长一定很复杂我看不懂。实际上绝大部分日志都是无关紧要的状态记录你需要关注的只有最后那几行——凡是真正的报错内容LaTeX Workshop都会用大写的ERROR标出来特别好辨认。2. 日志面板的正确打开方式先定位是哪一步挂了VS Code里查看日志的位置说实话藏得有点深很多用了一两年VS Code的人都未必留意过。你需要点击顶部菜单栏的终端然后在下拉菜单里找到输出这一项或者直接用快捷键Ctrl Shift UWindows和Linux打开输出面板。面板打开之后在右上角的下拉菜单里选择LaTeX Workshop这个选项这样你才能看到这个扩展自己的日志而不是VS Code通用日志或者终端里其他无意义的内容。选好之后你看到的日志大致长这样[12:30:01] Building the project. [12:30:01] Recipe step 1: xelatex -synctex1 -interactionnonstopmode -file-line-error -pdf main.tex [12:30:02] Recipe step 2: bibtex main [12:30:03] Recipe step 3: xelatex -synctex1 -interactionnonstopmode -file-line-error -pdf main.tex [12:30:05] Recipe step 4: xelatex -synctex1 -interactionnonstopmode -file-line-error -pdf main.tex [12:30:05] Recipe terminated with error.这里能看清楚两个信息。第一LaTeX Workshop 执行的是xelatex引擎不是pdflatex。这个信息非常重要因为不同引擎对编译内容的要求不一样。比如你想在文档里使用中文用pdflatex就非常难搞必须借助CJK宏包用xelatex就简单得多因为xelatex默认支持UTF-8编码配合ctex宏包几乎零门槛。如果你用的是学校毕业论文模板或者期刊模板模板里往往会有个main.tex文件里面可能会\RequirePackage{ctex}或者\documentclass[UTF8]{ctexart}这种情况下用xelatex是必须的。第二整个Recipe分了好几步。上面这个例子里一共四步第一次跑xelatex生成辅助文件然后跑bibtex处理参考文献再跑两次xelatex解决交叉引用和目录的更新问题。latexmk本身就是这个逻辑自动判断需要跑几遍。问题就出在这儿——每一步单独拆开看都可能出错。比如bibtex这步如果main.tex里根本没有引用任何.bib文件或者.bib文件不在main.tex所在的目录里bibtex就会直接报错退出。再比如最后一步xelatex如果文档里某个宏包的某个选项和当前引擎不兼容也会在编译过程中报错。所以当你看到Recipe terminated with error时一定要往上翻日志看最后一条状态是Recipe step 1还是Recipe step 3。如果是step 1就失败了问题基本出在编译引擎或者源码本身如果是step 3、step 4失败了那大概率是交叉引用或者参考文献的依赖关系出了问题。这里还要补充一个非常实用的经验日志里真正有含金量的不是LaTeX Workshop打印的那些状态记录而是LaTeX引擎自己输出的错误信息。这些信息会被原样打印在日志里通常以!开头。比如! LaTeX Error: File enumerate.sty not found. Type X to quit or RETURN to proceed, or enter new name. (Extension to load)这行里面写得清清楚楚——enumerate.sty这个文件找不到。enumerate.sty是LaTeX里一个非常基础的工具包用来处理列表环境。如果连它都找不到说明你的TeX发行版安装本身就有问题或者环境变量没配好。小结一下看到Recipe terminated with error之后最快的定位路径是打开输出面板切到LaTeX Workshop日志找到最后一条Recipe step N看N之后紧接着的日志如果底层引擎报了!开头的错误看那一行根据错误类型去解决缺宏包、缺文件、代码语法错误等。3. 最常见的翻车原因一TeX发行版与你安装的宏包不完整排在第一位的坑是TeX发行版本身装得不完整或者装完之后没有更新宏包索引。LaTeX不像普通软件是一个大而全的二进制文件它更像一个毛坯房——一个核心引擎加上几千个可选宏包。不同的宏包负责不同的功能写数学公式要amsmath插图片要graphicx调页面边距要geometry写论文摘要要abstract……这些宏包默认情况下并不一定都装在你的电脑上而是按需从仓库里下载安装。在Windows平台上大多数人用的是MiKTeX。MiKTeX有一个很贴心的功能叫自动安装缺失宏包默认开启。理论上讲如果你的文档里用了某个没装的宏包MiKTeX会弹出一个小窗口显示正在从仓库下载xxx.sty下载完了自动继续编译。听起来很完美对吧但实际使用中这个功能有两个很要命的问题一是弹出安装窗口的时候VS Code全屏状态可能看不到。你有事切出去了一会儿回头发现编译停了点了一下Retry结果因为宏包没有安装成功直接报Recipe terminated with error。二是MiKTeX的自动安装依赖仓库源如果你所在的网络连不上默认仓库或者仓库源响应很慢自动安装就会一直卡住卡到超时直接失败。我自己第一次遇到这个报错就是因为台式机上装的是很长时间之前下载的MiKTeX安装包它的宏包数据库特别老连ctex都找不到。折腾了很久之后我把MiKTeX重装了一遍又一次顺手把它内置的宏包管理器和格式化器全都更新了一遍才彻底解决。这里有个经验可以分享安装完TeX发行版之后第一件事情不是打开VS Code而是把宏包索引更新到最新。MiKTeX的操作方式是打开MiKTeX Console在开始菜单里搜一下就有切到更新一栏点击检查更新。TeX Live的话命令行操作Windows用户可以在命令提示符里执行tlmgr update --self --all这个命令会更新TeX Live自身以及所有已安装的宏包时间取决于网速一般几分钟到几十分钟不等。更新完之后再回到VS Code里点编译很多莫名其妙的报错都会消失。还有一类特殊情况值得单独提一下有的期刊模板或毕业论文模板会依赖一些很冷门的宏包这些宏包可能不在任何TeX Live/MiKTeX的默认仓库里。那种情况下编译报错会明确告诉你File xxx.sty not found而你检查发现整个仓库里都没有这个文件。这时候你需要去模板的官方页面看看是不是有额外的texmf目录需要手动放置或者需要把模板的sty文件复制到当前文档目录下。这一类问题已经不是配置环境的范畴而是模板使用的问题但现象一模一样所以我把它们归到一起了。4. 最容易迷惑新手的坑编辑器、终端与环境的割裂接下来说一个特别隐蔽、但坑了无数人的问题。你用的是VS CodeVS Code里跑LaTeX WorkshopLaTeX Workshop去调用xelatex或latexmk。这个链路的终端环境和你自己电脑上的系统环境不是一回事。什么意思呢举个例子你在系统设置里把D:\texlive\bin\windows加到了PATH环境变量里然后在终端里敲xelatex -v能正常显示版本号。你以为这就万事大吉了结果回到VS Code里点编译弹出来的错误是xelatex: command not found或者Recipe terminated with error。原因在于VS Code可能没有继承到你最新修改的环境变量。这个问题在Windows上尤其明显。因为Windows的GUI程序包括VS Code在启动的时候会读取当前用户的环境变量但如果你是在VS Code已经运行的情况下才修改的PATH那么这个VS Code进程里跑的所有子进程都读不到新加的路径。解决办法很朴素把VS Code完全关掉再重新打开一次让它重新加载一遍系统环境变量。但还有更隐蔽的情况。有些同学喜欢用WSLWindows Subsystem for Linux里面装好的TeX发行版。在WSL环境下装TeX Live然后从VS Code的WSL远程窗口中打开文件夹直接使用WSL里的xelatex编译。这套方案本身没什么问题但有个前提——WSL里的TeX发行版要装好而且要在WSL的PATH里。很多人在WSL里用sudo apt install texlive-latex-base装了一个精简版这玩意儿只包含最基础的LaTeX支持什么ctex、graphicx、amsmath好多常用宏包都没装一编译就报错而且报错方式五花八门什么File not found、什么Undefined control sequence都有最后全都归到Recipe terminated with error这一个笼统的报错上。如果遇到这种情况我的建议是不要贪图省事直接用完整安装。WSL的TeX Live用户可以在WSL终端里执行sudo apt install texlive-latex-extra texlive-lang-chinese texlive-fonts-recommendedtexlive-lang-chinese这个包尤其重要它包含ctex宏包以及中文字体配置。装了它之后写中文文档才不会有缺少中文字体或CJK 字体资源之类的坑。说回Windows平台。如果你用的是MiKTeX还有一个容易被忽略的细节MiKTeX的自动安装缺包功能和VS Code的输出面板没有直接关联如果某个宏包需要安装MiKTeX可能会在后台默默下载而这个过程中VS Code的编译进程已经等不及超时了。遇到这种情况最稳妥的办法是换用总是使用MiKTeX自带的命令行工具来安装宏包。打开终端执行mpm --installctexmpm是MiKTeX的宏包管理命令行工具--install后面跟包名就能手动安装指定的宏包。这样至少能确保宏包在编译之前就到位了而不是等到编译时才去拉。5. 问题定位的关键细节从哪一步失败到为什么失败前面讲了定位思路和常见环境坑但还有一个场景特别常见而且特别气人——所有环境都正确宏包也都齐了但编译依然报错。这时候光看Recipe terminated with error已经完全不够了你需要的是底层编译器的详细输出。这一步有两个关键配置我建议你一开始就配好。第一个是latexmk的-interactionnonstopmode参数。TeX Live和MiKTeX默认在遇到错误时可能会停下来等待用户输入这在VS Code这种非交互场景下就会卡死。加上nonstopmode之后编译器遇到错误不会停而是继续往下跑把尽量多的错误信息一股脑打印出来。虽然日志会变得很难看但总比卡住强。第二个是-file-line-error参数。只要在编译命令里加了这个参数报错信息里就会带上具体的文件和行号。对于定位代码里的语法错误来说这是救命级别的功能。配置方法很简单LaTeX Workshop的latex-workshop.latex.recipes和latex-workshop.latex.tools两个配置项在VS Code的设置文件里改参考下面这段latex-workshop.latex.tools: [ { name: xelatex, command: xelatex, args: [ -synctex1, -interactionnonstopmode, -file-line-error, -pdf, %DOC% ] }, { name: latexmk, command: latexmk, args: [ -xelatex, -synctex1, -interactionnonstopmode, -file-line-error, %DOC% ] } ]上面的%DOC%是LaTeX Workshop的占位符表示当前打开的.tex文件的主文件名不带扩展名。配好之后再点编译日志里报错信息的长相就不一样了会比原来清晰得多会直接出现./main.tex:45: Undefined control sequence. l.45 \foobar这一行的意思是main.tex第45行出现了一个未定义的控制序列也就是你写了一个LaTeX引擎不认识的命令在第45行叫\foobar。可能是宏包拼错了可能是自定义命令忘了定义也可能只是想把\textbf写成\testbf。这种错误对新手来说极其常见但好在定位也极其简单——日志里给了具体行号打开对应文件改掉那行就行。还有一类典型报错是Missing $ inserted。这个通常是因为你在正常的文本段落里直接写了数学符号比如_或者^LaTeX引擎找不到数学环境就会强行给你加一个$符号但输出往往不是你想要的。解决办法也很简单要么用\( ... \)把数学表达式括起来要么用$ ... $。如果你用的是ctrl B生成的粗体命令想写下标却写错了也容易出这个问题具体哪个位置出问题日志里同样会标明行号。再讲一个我遇到的比较刁钻的例子! Package fontspec Error: The font SimSun cannot be found.这个报错的场景是这样的——中文模板里用了ctex宏包ctex默认会用系统中文字体比如宋体、黑体。但如果你的系统里根本就没装宋体或者字体名称和ctex内部记录的不一样就会报cannot be found。解决办法有两种一种是在ctex宏包的选项里手动指定字体集比如\documentclass[UTF8, fontsetfandol]{ctexart}fandol是TeX Live自带的开源中文字体这是最省事也最稳妥的方式。另一种是在系统层面安装完整中文字体。如果你的文档是学校毕业论文模板模板里可能还会自己定义一些字体比如仿宋、楷体系统里没有的话同样的错误会在不同字体上反复出现。这时候直接选用fontsetfandol或者让ctex自动检测系统里能用的字体是更推荐的做法。6. 参考文献与交叉引用一半的Recipe terminated都死在这如果日志里显示的失败发生在Recipe step 2或者后面的步骤那要警惕一个特别容易让人崩溃的场景BibTeX或biber处理参考文献失败。先说原理。在LaTeX里整理参考文献有三套主流的工具链老牌的bibtex新一代的biber以及配合bibtex使用的natbib宏包等。不管用哪一套流程都是先编译一遍LaTeX把文档引用的参考文献信息写进辅助文件.aux再调用bibtex去读取.bib文件生成参考文献列表然后再编译两遍把所有引用编号对上。这个流程的任何一个环节出错都会导致最终编译结果不完整LaTeX Workshop也会直接判定Recipe失败。最容易翻车的点有三个。第一.bib文件的路径不对。你写的是\bibliography{refs}但refs.bib实际上不在main.tex的目录下而在另一个子文件夹里。这种情况bibtex会提示找不到数据库文件。解法是把refs.bib放在与main.tex同级目录下或者在\bibliography命令里用相对路径写清楚。第二bibtex和biber的选择与宏包不匹配。你用了\usepackage[stylegb7714-2015]{biblatex}又用\addbibresource{refs.bib}和\printbibliography这套是biber的流程但工具链配置里配的却还是老掉牙的bibtex两边对不上肯定报错。解决办法是检查使用的宏包和工具是否匹配传统\bibliography{} 普通bibtex流程biblatexbiber流程。两者不要混用。第三引用的key在.bib里不存在。文档里写了\cite{abc2023}但是refs.bib里的所有条目都没有abc2023这个key。这样的报错在日志里会显示Warning--I didnt find a database entry for abc2023但后面的LaTeX Warning: Citation abc2023 undefined也一并出现。这种情况严格来说不会阻止编译完成但如果你开了把警告当作错误之类的严格模式或者你的模板本身写了一些检查逻辑它也会导致Recipe终止。如果你用的是biber日志里的错误关键词通常是Biber error或者ERROR -而bibtex的报错则会明确提到I couldnt open database file或者I found no \citation commands。看到这些关键词的时候基本上能断定问题出在参考文献这一环节。我个人更推荐初学者直接使用latexmk作为默认Recipe因为它能自动判断该跑几遍xelatex和bibtex/biber并且能在缺参考文献时自动触发bibtex。在LaTeX Workshop的配置里把默认Recipe指到latexmk那一项能少操很多心。7. 一套省心的VS Code LaTeX配置方案直接抄作业说了这么多排查思路最后给一套我自己用了两年、到目前为止还算顺手的配置方案。不是唯一标准但至少能帮你绕开大部分坑。第一步安装TeX发行版。Windows上推荐MiKTeX或TeX LiveLinux上推荐TeX LivemacOS推荐MacTeX。无论哪个安装完成后一定先做宏包更新前面提到的那两步所谓磨刀不误砍柴工。第二步安装VS Code扩展。打开VS Code在扩展市场里搜索LaTeX Workshop作者是James Yu安装量最大那个就是。顺便可以再装一个LaTeX Language Support体验更好不过核心功能都在LaTeX Workshop里。第三步配置settings.json。打开VS Code的设置搜索latex-workshop.latex.recipes把它和latex-workshop.latex.tools一起编辑成适用于你环境的版本。我遇到过换电脑之后重装VS Code时忘了保存配置的尴尬情况所以配置文件建议直接放到自己的dotfiles仓库或者网上某个私有gist里随时能拷过去。下面是一份可以直接套用的配置{ latex-workshop.latex.recipes: [ { name: latexmk (xelatex), tools: [latexmk] } ], latex-workshop.latex.tools: [ { name: latexmk, command: latexmk, args: [ -xelatex, -synctex1, -interactionnonstopmode, -file-line-error, %DOC% ] } ], latex-workshop.view.pdf.viewer: tab, latex-workshop.latex.autoBuild.run: onSave, latex-workshop.latex.clean.fileTypes: [ *.aux, *.bbl, *.blg, *.idx, *.ind, *.lof, *.lot, *.out, *.fls, *.fdb_latexmk, *.synctex.gz ] }用这套配置之后按Ctrl S保存.tex文件时LaTeX Workshop就会自动调用latexmk去编译编译成功之后PDF会在右侧的标签页里实时刷新预览不需要手动点构建按钮。latexmk的一大优势就是它能自动管理多次编译和参考文献工具链对新手非常友好。第四步检查编译命令是否可用。在VS Code里按Ctrl 打开终端输入latexmk -v如果能显示版本号说明终端能找到latexmk一般来说VS Code也能找到。如果提示不是内部或外部命令说明环境变量有问题需要先处理环境变量再回来配VS Code。这里顺便提一个检查思路VS Code里报错Recipe terminated但你在系统终端里手打同一条命令却能正常编译这通常就是环境变量的问题。因为VS Code作为GUI程序它的环境变量读取时机和你终端不一样最直接的解法就是重启VS Code再不行就重启电脑让环境变量彻底刷新。8. 最后再说说Retry按钮为什么没什么用很多人在报错之后点了Retry building the project期望它能奇迹般成功。我负责任的讲绝大多数情况下这个按钮是没用的。它做的事情很简单把刚才那套Recipe原封不动地再执行一遍。如果导致失败的问题没有被修复再多Retry十次也是同样的结果。唯一的例外情况是网络问题。如果你的MiKTeX或TeX Live正在后台联网下载宏包第一次编译因为等待下载而超时Retry一次之后宏包已经装好了也许就能成功。但即便如此我依然不建议你靠Retry来碰运气。真正有效率的做法是点开输出面板看日志找到错误修改保存让它触发自动构建。改对了一次就成改不对Retry一万次也是白搭。还有一个经验值得单独分享每次编译报错不要只盯着最后一行。LaTeX引擎产生的错误往往有连锁反应一个宏包没加载成功后面所有依赖它的命令都会跟着报错。日志里可能会刷出十几个错误但实际上根因只有一个。正确的做法是先看第一个错误解决它然后保存重编译。后面那些错误很可能就跟着消失了。反过来如果你一头扎进第12个报错去改代码大概率是在浪费时间。还有一点不要忽略.log文件。LaTeX每次编译都会生成一个和主文件同名的.log文件比如main.log里面记录了完整的编译过程。VS Code输出面板里的日志是从LaTeX Workshop的角度展示的而.log文件里才是LaTeX引擎自己写下的完整日记。当你在输出面板里找不到有效报错信息的时候直接Ctrl Shift U旁边的终端里敲一句code main.log或者用记事本打开main.log翻到末尾几行很多玄学问题都能在这里找到真正的答案。最后聊一下心态。Recipe terminated with error这个报错本质上就是LaTeX编译没有平滑跑完的笼统翻译。学会看日志之后你会发现它的杀伤力大减——无非就是宏包缺了、路径错了、语法写错了、工具链配错了这么几大类。把这几个方向记在心里哪怕英文日志看不太懂看到not found就往缺文件方向想看到Undefined control sequence就往语法错误方向想看到Cannot find就往字体或路径方向想基本上没有定位不到的问题。我自己从第一次遇到这个报错到现在中间跨过了不少烂坑也总结出一句话别把编译失败看成程序在刁难你它其实是试卷上标出了哪道题做错了——剩下的只是你能不能静下心去解析答案而已。 SEO 优化官网定制响应式建站教育培训建站