告别 MSYS2:在纯 Windows 环境下解决 Emacs Tree-sitter 兼容性问题
起因
最近我的折腾理念发生了转变:追求原生,拒绝复杂
- 安装原则:能 winget install 的,就不手动编译。
- 编译工具:能用 Windows 原生的 cl (MSVC),就不用 Clang;能不用 Unix-like 环境(如 MSYS2/Cygwin),就坚决不用。
- 实现目标:减少环境依赖,降低系统复杂度。
当然也有例外情况:像 OCaml 这种强依赖特定环境的语言,我选择交给它自己的 opam 托管,卸载时直接删除整个 opam 目录就行,没必要在系统层面清理 MSYS2 依赖。这种沙盒式的管理,属于是我这种懒人福音了。
所以我马上就把系统里的 MSYS2 卸了,下一秒就遇到问题了🤣
问题一:treesit install 失效
在移除 MSYS2 后,我在写 Rust 时遇到了这样的问题,treesit-install-language-grammar 无法正常工作,看了下源码,貌似是因为它用 cc 来编译所需的 parser
由于我移除了 MSYS2,系统回退到了自带的 Clang,但也不知为什么提示不支持 -fPIC,我又懒得研究 Clang,所以决定跳过源码编译,直接使用别人预编译好的 parser
问题二:ABI 版本不匹配
我最开始用的 tree-sitter-langs,但新的问题又来了:
我通过 winget 安装的 Emacs 版本是 30.2,内置的 ts-mode 似乎只支持旧版本的 parser(我是咋知道的,嗯……执行 (treesit-language-available-p 'rust t),返回 abi version mismatch,所以盲猜是 parser 太新了),还是得手动编译 parser
但我已经卸载了 MSYS2,似乎陷入了两难,但就在这个时候,我想到 Tree-sitter 官方有个 CLI 工具 (tree-sitter-cli)。它本身不需要 MSYS2 环境就能在 Windows 上运行,也许可以用它来代替 gcc
解决方案
- 安装 tree-sitter-cli
如果你有 Rust 环境
cargo binstall tree-sitter-cli
注意我这里用的是 cargo-binstall
如果你有 node 环境
npm install -g tree-sitter-cli
- 获取源码并编译 Parser
(此处以 ABI 14 为例,适配 Emacs 30.2)
mkdir tree-sitter
cd tree-sitter
git clone https://github.com/tree-sitter/tree-sitter-rust
cd tree-sitter-rust
# 官方自带的 parser abi 都太新了
tree-sitter generate --abi 14
# 编译所需的 dll 文件
tree-sitter build
cp rust.dll ~\.emacs.d\tree-sitter\libtree-sitter-rust.dll
PS
如果你像我一样,有写 clojure/ocaml 的需求,然而这几个 ts-mode 用的是指定版本的 recipe,记得在 tree-sitter generate 前先切换到指定的分支,拿 clojure 举例子
# clojure
git clone https://github.com/sogaiu/tree-sitter-clojure
cd tree-sitter-clojure
git switch unstable-20250526
tree-sitter generate --abi 14
tree-sitter build
cp clojure.dll ~\.emacs.d\tree-sitter\libtree-sitter-clojure.dll
# markdown-inline
git clone https://github.com/tree-sitter-grammars/tree-sitter-markdown
cd tree-sitter-markdown/tree-sitter-markdown-inline/src
git switch v0.5.2
tree-sitter generate --abi 14
tree-sitter build
cp markdown-inline.dll ~\.emacs.d\tree-sitter\libtree-sitter-markdown-inline.dll
# regex
git clone https://github.com/tree-sitter/tree-sitter-regex
cd tree-sitter-regex
tree-sitter generate --abi 14
tree-sitter build
cp regex.dll ~\.emacs.d\tree-sitter\libtree-sitter-regex.dll
最后
这么整完,发现舍弃掉 msys2 的确是可行的。如果你像我一样是个懒人,可以参考下我的做法。
也许有人会问,主包主包,你这么折腾不是更麻烦吗?也许吧,但我的初因只是想减少一下系统环境的复杂度(我实在是懒得折腾了🤣)并且 Emacs 稳定版的更新频率很慢,手动处理这么一下,几个月都不需要再手动更新了