本文介绍对Emacs源码进行编译构建的整个过程。
1. Autoconf 介绍
下载并完成解压后,我们看到源码目录下没有可以完成编译配置的 configure 文件,只有 configure .ac 这个文件。一般我们是通过执行 configure 文件完成编译配置的,例如编译 Qt库。下面对 configure.ac 文件进行介绍。

configure.ac 是 Autoconf 工具的输入文件,需要先通过 Autoconf 生成标准的 configure 脚本才能继续编译。什么是 Autoconf 工具呢?
Autoconf 是一个用于生成强可移植性的软件配置脚本(configure 脚本)的工具套件,属于 GNU 构建系统(Autotools)的核心组件之一。
它主要有以下作用:
1. 自动检测系统环境:检查编译器、库、头文件等依赖;测试系统功能和特性;识别平台差异。
2. 生成配置脚本:根据 configure.ac(或 configure.in)模板,生成可移植的 shell 配置脚本(configure)。
configure.ac: 这是一个源代码文件,由开发者编写,包含了如何检测系统特性(如库、函数、编译器)的宏指令。它本身是一个脚本"蓝图",不能直接执行。
configure: 这是一个可执行的 shell 脚本,由 autoconf 命令处理 configure.ac 后生成。它才是在编译时实际运行的配置脚本。
Autoconf 核心工作流程如下图所示:

Autoconf 依赖一系列工具,例如autoconf、automake、autogen及texinfo等工具。
autoconf: 用于生成 configure 脚本。
automake: 用于生成 Makefile.in 模板(如果项目使用了 Automake)。
make: 最基本的编译工具。
gcc / clang: C 编译器。
texinfo: 用于生成 GNU 软件的文档(Emacs 必需)。
本文在 Windows 上进行 Emacs 的编译工作,Autoconf 等 GNU 工具链需要在类 Unix 环境下运行,因此下面使用 MSYS2 环境。
MSYS2 是一个为 Windows 提供完整的类 Unix 构建环境的软件分发和开发平台,也是当前在 Windows 上使用 Autoconf 等 GNU 工具链的首选环境。
在 x64 Native Tools Command Prompt for VS 2019 中启动 MSYS2 后,输入下列命令,完成相关依赖包文件的安装。
pacman -S --needed base-devel autoconf automake autogen texinfo mingw-w64-x86_64-gtk3

安装时,速度较慢,要更换 MSYS2 的默认源。修改 mirrorlist.mingw 与 mirrorlist.msys 文件,将默认源修改为阿里源。
Server = https://mirrors.aliyun.com/msys2/mingw/$repo/
Server = https://mirrors.aliyun.com/msys2/msys/$arch/
有一点十分要注意!!!
不能使用 MSYS2 MSYS 环境,要使用 MSYS2 MINGW64/UCRT64 环境。
本文使用的 UCRT64 环境也是基于 mingw 编译器的,在 Windows 上兼容性不太好,后面再介绍基于 MSVC 编译器的编译方法。

| 特性 | MSYS2 MSYS 环境 | MSYS2 MINGW64/UCRT64 环境 |
|---|---|---|
| 核心目标 | 提供一个类似于Cygwin的POSIX兼容环境,用于编译运行在MSYS2子系统内部的程序 | 使用MinGW-w64工具链,编译原生的、不依赖MSYS2环境的Windows程序,可以直接在Windows上运行 |
| 工具链前缀 | 软件包没有 mingw-w64-x86_64- 前缀,例如直接叫 gnutls | 软件包带有 mingw-w64-x86_64- 或 mingw-w64-ucrt-x86_64- 前缀 |
| 运行时依赖 | 编译出的程序依赖 msys-2.0.dll,只能在MSYS2终端里运行 | 编译出的程序依赖标准的 msvcrt.dll 或 ucrtbase.dll,可以在任意Windows命令行中运行 |
| configure 检测结果 | host 类型通常为 x86_64-pc-msys | host 类型为 x86_64-w64-mingw32 |
2. 构建过程介绍
bash
# 1. 生成 configure 脚本和所有相关的构建文件
./autogen.sh
# 如果 autogen.sh 不存在,则需要手动运行:
# autoreconf -iv
# 2. 运行 configure 脚本来检测系统并生成 Makefile
./configure
# 你可以在这里添加很多选项,例如:
# --with-native-compilation (启用原生编译,需要 libgccjit)
# --with-x-toolkit=gtk3 (指定 GUI 工具包)
# --without-x (不编译 X11 图形界面,只保留终端版)
# --prefix=E:/OpenSrcProj/emacs/lib/msvc2019_64 (指定安装路径)
# 注意,一般不在源码路径下直接运行 configure 脚本,这样会导致生成的构建文件与源码混在一起。
# 标准做法是在源码目录之外创建一个全新的目录,然后在该目录中运行 configure 脚本,并通过相对或绝对路径指向源码。
# 3. 开始编译 (使用 -j 参数可以多核并行加速)
make -j16
# 4. 安装到系统
sudo make install

3. 运行问题
构建完成后,在 ucrt64 中能够正常启动 emacs 应用,但是用鼠标双击打开,会提示缺少 libgmp-10.dll 与 libwinpthread-1.dll库。


libgmp-10.dll (GNU 多精度运算库) 和 libwinpthread-1.dll (POSIX 线程库的 Windows 实现) 是 GCC 工具链的核心组成部分。当在 UCRT64 环境中编译时,Emacs 会动态链接到这些库。双击运行时,Windows 会在系统路径中搜索这些 DLL,但普通 Windows 系统默认没有它们。
为了确保没有遗漏其他依赖,可以使用 MSYS2 自带的工具进行完整检查,找出所有依赖的 DLL。
在 UCRT64 终端中,进入 emacs.exe 所在目录,执行 ldd ./emacs.exe。这会列出 emacs.exe 直接和间接依赖的所有 DLL 及其当前查找路径。输出中所有指向 ucrt64/bin/ 的 DLL,都可能需要被复制。执行结果如下所示,通过输出结果能够看到,缺少 libgmp-10.dll 与 libwinpthread-1.dll 库。

将这两个库文件复制到exe文件所在路径下后,emacs.exe 能够正常运行。
