(TIL)解决 emacs 在 macOS 下编译报错无法找到 libgccjit.so 的问题

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. 初步怀疑与排查方向

根据错误特征,最可能的几类原因:

  1. GCC / libgccjit 安装版本不一致:Emacs 链接的是老版本,但系统安装的是新版本。
  2. 动态库路径未加入环境变量:GUI 进程找不到 libgccjit.dyliblibemutls_w.a
  3. pkg-config 或 libgccjit.pc 丢失:Emacs 无法确定 libgccjit 的安装位置。
  4. 架构不一致(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 founderror invoking gcc driver 消失;
  • native-comp 正常启动,Emacs 无任何报错。

6. 根因总结

  • 直接原因/opt/homebrew/opt/libgccjit 链接损坏,Emacs 在默认路径找不到 libgccjit.dylib
  • 间接原因:运行期动态库搜索路径未包含 libgccjit 和 GCC 的 libemutls_w,导致 native compiler 链接失败。
  • 解决核心:修复 opt 链接 + 注入动态库路径 + 保证 GUI 环境继承。
2 个赞