1. 这个报错到底卡在哪一步
如果你在用 LaTeX 写文档,尤其是用 MiKTeX 这套发行版,某天编译时突然蹦出一行红字:Sorry, but miktex-makemf did not succeed,然后编译就停在那儿不动了,后面跟着一堆The log file hopefully contains the information to get MiKTeX going again之类的提示。第一次遇到的人基本都会懵——我明明没改什么配置,昨天还能编译,今天怎么就挂了?
这个报错的核心,是 MiKTeX 在尝试为一个字体生成MF(Metafont)位图文件时失败了。miktex-makemf是 MiKTeX 自带的一个工具,专门负责调用 Metafont 引擎,把.mf源文件编译成.tfm(字体度量文件)和.pk(打包位图字体)等中间产物。当它失败时,通常意味着字体文件缺失、路径配置有问题、或者权限不足导致它没法把生成的文件写进目标目录。
它影响的范围其实比想象中大:不只是你正在编译的那一个文档,而是所有依赖这个字体的文档都会挂。更麻烦的是,MiKTeX 的字体生成机制是按需触发的,也就是说,只有当你第一次用到某个字体时它才会去生成,所以这个问题往往在你换了一台机器、重装系统、或者升级 MiKTeX 之后才突然冒出来。
这篇文章适合谁看?如果你正在用 MiKTeX + LaTeX 写论文、做简历、排书稿,或者维护一套自动化编译流程,遇到这个报错又不想重装整个发行版,那下面的内容基本能帮你把问题定位到具体环节。我会从报错原理讲起,然后给出可复现的排查步骤和修复方案,最后附上我踩过的几个坑。
2. 报错背后的字体生成机制
2.1 MiKTeX 的按需安装与字体生成逻辑
MiKTeX 和 TeX Live 最大的区别之一,就是它的按需安装机制。TeX Live 通常是全量安装,几个 GB 的包一次性装完;而 MiKTeX 默认只装基础包,当你编译时用到某个缺失的宏包或字体,它会临时去下载并安装。这个设计在磁盘空间紧张或者网络环境一般的情况下很实用,但也带来了一个副作用:字体生成环节变得更容易出错。
字体这块的流程大致是这样的:LaTeX 编译时,引擎需要某个字体的度量信息(.tfm文件)。如果这个.tfm不存在,MiKTeX 就会去找对应的字体源文件(.mf或.pfb等),然后调用miktex-makemf或miktex-makepk来生成。生成过程中,它需要读取 Metafont 的配置文件(mf.base、plain.mf等),还需要把结果写到 MiKTeX 的字体缓存目录里。
问题就出在这个链条上:只要其中任何一环断了——源文件缺失、配置文件路径不对、缓存目录没写权限、或者 Metafont 引擎本身有问题——miktex-makemf就会返回失败,然后整个编译流程卡住。
2.2 为什么偏偏是 makemf 失败
很多人会问:为什么不是makepk失败,也不是mktexfmt失败,偏偏是makemf?这跟 Metafont 的工作方式有关。Metafont 是一个用来描述字体形状的编程语言,它输出的不是直接的位图,而是需要经过一系列步骤才能得到可用的字体文件。miktex-makemf负责的是最前面那一步:把.mf源文件编译成.tfm和.gf(通用字体格式)文件。
这一步失败,常见原因有这么几类:
- 字体源文件根本没装:比如你用了某个冷门字体,MiKTeX 的包仓库里没有对应的
.mf文件,或者按需安装时网络中断导致下载不完整。 - Metafont 的初始化文件缺失或损坏:
mf.base是 Metafont 的预编译格式文件,如果它不存在或者版本不匹配,makemf就没法启动。 - 路径里有中文或空格:Metafont 对路径的处理比较古老,遇到非 ASCII 字符或者空格时容易出问题。
- 缓存目录权限不足:MiKTeX 需要往用户目录下的缓存文件夹写文件,如果权限被限制,写入就会失败。
- MiKTeX 的 filename database(FNDB)过期:FNDB 是 MiKTeX 用来快速定位文件的索引,如果它没更新,
makemf可能找不到需要的文件。
理解这些原因之后,排查就有了方向。下面我会按从简到繁的顺序,给出具体的操作步骤。
3. 一步步定位问题源头
3.1 先看日志文件,别急着瞎猜
报错信息里通常会提到一个日志文件路径,类似C:\Users\你的用户名\AppData\Local\MiKTeX\miktex\log\miktex-makemf.log或者 Linux 下的~/.miktex/texmfs/data/miktex/log/miktex-makemf.log。这个日志才是真正的线索来源,里面会记录makemf具体是在哪一步失败的。
打开日志,重点看这几类信息:
- 有没有
not found或cannot find字样,说明某个文件缺失。 - 有没有
permission denied或access is denied,说明权限问题。 - 有没有
metafont: command not found或类似提示,说明 Metafont 引擎本身没装好。 - 有没有关于
mf.base的报错,说明初始化文件有问题。
我遇到过一种情况:日志里显示makemf在找cmr10.mf,但实际路径下只有cmr10.tfm,源文件被误删了。这种就是典型的源文件缺失,重新安装对应字体包就能解决。
3.2 检查字体源文件是否存在
确认日志里提到的字体名之后,你可以手动去 MiKTeX 的安装目录下找找看。比如在 Windows 上,字体文件通常在C:\Program Files\MiKTeX\fonts\source\或者用户目录下的AppData\Roaming\MiKTeX\fonts\source\。Linux 下一般在/usr/share/miktex/fonts/source/或者~/.miktex/texmfs/install/fonts/source/。
如果对应的.mf文件确实不在,那问题就明确了:需要重新安装这个字体包。可以用 MiKTeX Console 的包管理器搜索字体名,或者直接用命令行:
mpm --install=字体包名比如cmr10属于cm字体包,那就mpm --install=cm。安装完之后,记得刷新 FNDB:
initexmf --update-fndb3.3 验证 Metafont 引擎是否可用
有时候问题不在字体,而在 Metafont 本身。你可以手动跑一下makemf看看它能不能正常工作:
miktex-makemf --version如果这个命令都报错,那说明 MiKTeX 的 Metafont 组件没装好或者损坏了。这种情况下,最直接的办法是通过 MiKTeX Console 重新安装miktex-metafont相关的包,或者干脆修复整个 MiKTeX 安装。
在 Windows 上,MiKTeX Console 有个“检查更新”和“修复”功能,可以扫描并修复损坏的组件。Linux 下如果用的是包管理器安装的 MiKTeX,可以尝试重新安装miktex-metafont包。
3.4 路径与权限的坑
路径问题在 Windows 上特别常见。如果你的项目放在D:\我的文档\论文\这种带中文的路径下,Metafont 很可能因为编码问题找不到文件。我建议把项目路径改成纯英文、无空格的,比如D:\work\paper\。
权限问题则多见于 Linux 和 macOS。如果你用sudo编译过文档,MiKTeX 的缓存目录可能被 root 用户占用了,之后普通用户再编译时就没法写入。解决办法是找到缓存目录,把所有权改回当前用户:
sudo chown -R $USER ~/.miktexWindows 上如果 MiKTeX 装在Program Files下,普通用户可能没有写权限。这种情况下,建议把 MiKTeX 的缓存目录设置到用户目录下,在 MiKTeX Console 的“设置”里可以改。
4. 修复方案与实操记录
4.1 方案一:刷新 FNDB 并重新生成格式文件
这是最轻量的修复方式,适合那些只是索引过期或者格式文件损坏的情况。操作步骤如下:
- 打开命令行,切换到 MiKTeX 的 bin 目录,或者确保
miktex相关命令在 PATH 里。 - 刷新文件名数据库:
initexmf --update-fndb- 重新生成所有格式文件:
initexmf --dump- 如果上一步报错,可以指定具体格式,比如:
initexmf --dump=latex- 清理字体缓存(可选,但有时候很有效):
initexmf --mkmaps这套操作下来,很多因为索引或格式文件导致的问题都能解决。我实测过几次,在 MiKTeX 升级之后遇到makemf失败,跑一遍--update-fndb和--dump基本就好了。
4.2 方案二:手动安装缺失的字体包
如果日志明确指向某个字体缺失,那就直接装对应的包。MiKTeX 的包管理命令是mpm,常用操作如下:
| 操作 | 命令 |
|---|---|
| 搜索包 | mpm --find=关键词 |
| 安装包 | mpm --install=包名 |
| 卸载包 | mpm --uninstall=包名 |
| 列出已安装 | mpm --list |
| 更新包数据库 | mpm --update-db |
比如报错涉及cmr10,那就mpm --install=cm。如果涉及ecrm1000,那可能是ec字体包。装完之后别忘了initexmf --update-fndb。
这里有个小技巧:如果你不确定字体属于哪个包,可以在 MiKTeX Console 的图形界面里搜索字体文件名,它会告诉你对应的包名。命令行下也可以用mpm --find=文件名来查。
4.3 方案三:重建 MiKTeX 的字体缓存
有时候字体文件都在,FNDB 也刷新了,但makemf还是失败。这种情况可能是字体缓存目录里的文件损坏了。解决办法是直接删掉缓存目录,让 MiKTeX 重新生成。
缓存目录的位置:
- Windows:
C:\Users\你的用户名\AppData\Local\MiKTeX\ - Linux:
~/.miktex/texmfs/data/ - macOS:
~/Library/MiKTeX/
删掉里面的miktex文件夹或者fonts缓存子目录,然后重新编译。MiKTeX 会自动重建缓存。注意,删之前最好关掉所有正在使用 MiKTeX 的程序,否则可能删不干净。
我遇到过一次缓存损坏的情况,表现是makemf报错说某个.tfm文件已存在但无法读取。删掉缓存目录后重新编译,问题就消失了。
4.4 方案四:切换编译器或改用 Type1 字体
如果某个字体反复出问题,而你又不急着用 Metafont 生成位图,可以考虑换个思路。比如:
- 用
pdflatex代替latex,因为pdflatex默认使用 Type1 字体,不需要 Metafont 生成位图。 - 在文档里显式指定 Type1 字体,比如用
\usepackage{times}代替默认的 Computer Modern。 - 如果必须用某个 Metafont 字体,可以尝试用
mktextfm手动生成,看看具体报什么错。
这个方案的本质是绕过 Metafont 环节,适合那些对字体要求不严格、只想赶紧把文档编译出来的场景。
5. 常见问题速查与避坑心得
5.1 常见问题速查表
| 现象 | 可能原因 | 解决办法 |
|---|---|---|
日志显示file not found | 字体源文件缺失 | mpm --install=包名 |
日志显示permission denied | 缓存目录权限不足 | 修改目录所有权或换缓存路径 |
makemf --version都报错 | Metafont 组件损坏 | 重装miktex-metafont |
| 路径含中文或空格 | Metafont 路径解析失败 | 项目移到纯英文路径 |
| 升级 MiKTeX 后突然报错 | FNDB 或格式文件过期 | initexmf --update-fndb+--dump |
| 反复报同一个字体错误 | 缓存损坏 | 删除缓存目录重建 |
| 网络环境差时按需安装失败 | 下载不完整 | 手动安装或换稳定网络 |
5.2 几个我踩过的坑
第一个坑是用管理员权限编译。在 Windows 上,如果你用管理员身份运行编辑器或命令行,MiKTeX 会把缓存写到管理员目录下,之后普通用户编译时就找不到缓存,导致makemf失败。解决办法是始终用普通用户权限编译,除非确实需要装包。
第二个坑是同时装了多个 LaTeX 发行版。比如系统里既有 MiKTeX 又有 TeX Live,PATH 里混在一起,makemf可能调用了错误的 Metafont 引擎。这种情况下,要么卸载一个,要么在编辑器里显式指定 MiKTeX 的路径。
第三个坑是杀毒软件拦截。某些杀毒软件会把miktex-makemf.exe当成可疑程序,阻止它写入文件。表现就是makemf静默失败,日志里也看不出明显原因。把 MiKTeX 的目录加入杀毒软件白名单就能解决。
第四个坑是磁盘空间不足。Metafont 生成位图字体时会占用不少临时空间,如果磁盘满了,makemf也会失败。这个原因比较隐蔽,因为报错信息不会直接说磁盘满,但日志里可能会有no space left on device之类的提示。
5.3 预防性维护建议
与其等报错了再修,不如平时做点预防。我的习惯是:
- 每次升级 MiKTeX 之后,跑一遍
initexmf --update-fndb和initexmf --dump。 - 定期清理 MiKTeX 的缓存目录,避免缓存文件堆积导致冲突。
- 项目路径坚持用英文,不用空格,不用特殊字符。
- 如果经常用冷门字体,提前用
mpm把相关包装好,别依赖按需安装。 - 保留一份编译成功的日志,出问题时可以对比。
这些习惯看起来琐碎,但能省下大量排查时间。尤其是路径和权限这两块,一旦出问题,表现往往很隐蔽,不如一开始就规避掉。
6. 从报错到修复的完整复盘
回到最初那个报错:Sorry, but miktex-makemf did not succeed。它本质上是一个字体生成链条断裂的信号,而不是一个孤立的错误。修复它的关键,是顺着日志找到断裂的具体环节——是源文件缺失、权限不足、路径问题,还是缓存损坏。
我的建议是,遇到这个报错时不要急着重装整个 MiKTeX,先按下面的顺序排查:
- 打开
miktex-makemf.log,看具体报错信息。 - 确认字体源文件是否存在,缺失就装包。
- 检查路径是否含中文或空格,有就改路径。
- 检查缓存目录权限,不对就改所有权。
- 刷新 FNDB 并重新生成格式文件。
- 如果还不行,删缓存目录重建。
- 最后才考虑重装 MiKTeX 或换发行版。
这套流程走下来,绝大多数makemf失败都能解决。我自己的经验是,真正需要重装的情况不到一成,大部分问题都出在路径、权限和缓存这三块。
最后分享一个小技巧:如果你在团队里维护自动化编译流程,可以在编译脚本里加一步initexmf --update-fndb,每次编译前自动刷新索引。这样即使有人误删了字体文件或者改了路径,也能在早期发现,而不是等到编译到一半才报错。这个习惯帮我省了不少半夜排查的时间。