可能会碰到的在 Windows 下通过 msys2 编译的 tree-sitter parser 无法被 emacs 加载的问题及其解决方法

太草了,被这个问题折腾了一晚上。

今天换了电脑想尝试配置下 Rust 开发环境,现在 rust-ts-mode 已经内置了,我就顺便装个 libtree-sitter-rust.dll。在把得到的 dll 放到 .emacs.d/tree-sitter 目录下后调用 treesit-language-available-p 时却返回了 nil

(treesit-language-available-p 'rust) => nil

之前使用的系统是 Win10,现在换到 Win11 了我怀疑是不是兼容性出问题了。后来经过:怀疑系统兼容性 → 怀疑 Emacs 本身 → 怀疑编译参数设置 → 怀疑动态库路径问题 → 怀疑编译环境,我才找到了问题所在。我直接使用了 pacman -S gcc 来安装 gcc 编译器,而它的编译产物会依赖 msys-2.0.dll,因此加载时会因为找不到 msys-2.0.dll 而无法加载。

要生成不依赖这个兼容层的 dll,我们需要安装 ucrt 版的 gcc,MSYS2 UCRT64 shell

pacman -S mingw-w64-ucrt-x86_64-gcc

之后使用以下命令编译就行了:

gcc -fPIC -c -I. parser.c 
gcc -fPIC -c -I. scanner.c
gcc -fPIC -shared *.o -o libtree-sitter-rust.dll

当然了你也可以设置好 treesit-language-source-alist 然后像 Building tree-sitter languages for Emacs 一样编译。如果在 Windows 上可以在 msys2 shell 中打开 emacs 然后编译,它需要 git 和 gcc,所以还得 pacman 装一下。

根据 Windows 的 DLL 搜索规则,把 msys-2.0.dll 放到 emacs 可执行文件目录下应该也能正常加载,但是我懒得尝试了。

另:Windows 下可以使用 lucasg/Dependencies 查找 DLL 依赖,老版本的 Dependency Walker 有些过时了。下面的上图和下图分别是新老版本的输出:

具体原因可以参考 windows - Dependency Walker: missing dlls - Stack Overflow

如果跟着 官方教程 安装的话我就不会碰到这个问题,这次属于是大意了。

可以参考我用git action编译的仓库,加个-s参数就没有msys的依赖了,我本机是不装msys的

:call_me_hand: