1. 问题出现:Native Compiler 报错无法编译
一开始 Emacs 启动时持续报错:
comp--native-compile: Native compiler error:
ld: library 'emutls_w' not found
libgccjit.so: error: error invoking gcc driver
典型症状是:
- 每次启动都会卡在 trampoline 编译 (
handle-switch-frame); - 报错指向
emutls_w缺失; libgccjit调用 GCC 驱动失败。
这意味着 native-comp 阶段链接器没找到 GCC 的运行时库,无法完成 .eln 编译。
2. 初步怀疑与排查方向
根据错误特征,最可能的几类原因:
- GCC / libgccjit 安装版本不一致:Emacs 链接的是老版本,但系统安装的是新版本。
- 动态库路径未加入环境变量:GUI 进程找不到
libgccjit.dylib或libemutls_w.a。 - pkg-config 或 libgccjit.pc 丢失:Emacs 无法确定 libgccjit 的安装位置。
- 架构不一致(arm64 vs x86_64):导致库无法被加载。
初步检查确认:
- Emacs 报
emutls_w not found; pkg-config找不到libgccjit;/opt/homebrew/opt/libgccjit/lib/libgccjit.dylib不存在。
→ 基本锁定为 libgccjit 链接损坏 + 路径未加入环境。
3. 深入定位:真正的根因
进一步文件检查:
/opt/homebrew/Cellar/libgccjit/15.1.0/lib/gcc/15/libgccjit.dylib
/opt/homebrew/opt/libgccjit/lib/libgccjit.dylib: No such file or directory
结论非常明确:
- Homebrew 的 “opt” 链接损坏,
/opt/homebrew/opt/libgccjit并没有正确指向 Cellar 中的版本。 - Emacs 在运行期默认查找
opt路径,结果找不到libgccjit.dylib; - 同时
libemutls_w所在的gcc/15目录也未加入动态库搜索路径; - 导致链接器报错、native compiler 无法启动。
4. 修复过程:三步解决所有问题
第一步:修复 opt 链接
恢复符号链接,让 Emacs 能在默认路径找到 libgccjit:
brew unlink libgccjit
brew link libgccjit --force --overwrite
这一步解决了「libgccjit.dylib 不存在」的问题。
第二步:注入正确的库路径(终端环境)
保证编译时能找到 emutls 与 libgccjit:
export PATH="$(brew --prefix gcc)/bin:$PATH"
export CC=gcc-15 CXX=g++-15
export LIBRARY_PATH="$(brew --prefix gcc)/lib/gcc/15:$(brew --prefix gcc)/lib:$(brew --prefix libgccjit)/lib/gcc/15:${LIBRARY_PATH}"
export DYLD_FALLBACK_LIBRARY_PATH="$(brew --prefix gcc)/lib/gcc/15:$(brew --prefix gcc)/lib:$(brew --prefix libgccjit)/lib/gcc/15:${DYLD_FALLBACK_LIBRARY_PATH}"
这里两类路径必须同时加:
…/gcc/15/:包含libemutls_w.*…/libgccjit/lib/gcc/15/:包含libgccjit.dylib
第三步:让 GUI 进程继承环境
GUI 启动不会自动继承 shell 环境,必须通过 launchctl 注入:
launchctl setenv PATH "$PATH"
launchctl setenv LIBRARY_PATH "$LIBRARY_PATH"
launchctl setenv DYLD_FALLBACK_LIBRARY_PATH "$DYLD_FALLBACK_LIBRARY_PATH"
这样 Finder/图标启动的 Emacs 也能访问到相同的库路径。
5. 验证结果与结论
执行完以上三步后:
.eln缓存可正常重新编译;emutls_w not found和error invoking gcc driver消失;- native-comp 正常启动,Emacs 无任何报错。
6. 根因总结
- 直接原因:
/opt/homebrew/opt/libgccjit链接损坏,Emacs 在默认路径找不到libgccjit.dylib。 - 间接原因:运行期动态库搜索路径未包含
libgccjit和 GCC 的libemutls_w,导致 native compiler 链接失败。 - 解决核心:修复
opt链接 + 注入动态库路径 + 保证 GUI 环境继承。