告别 MSYS2:在纯 Windows 环境下解决 Emacs Tree-sitter 兼容性问题

告别 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

解决方案

  1. 安装 tree-sitter-cli

如果你有 Rust 环境

cargo binstall tree-sitter-cli

注意我这里用的是 cargo-binstall

如果你有 node 环境

npm install -g tree-sitter-cli
  1. 获取源码并编译 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 稳定版的更新频率很慢,手动处理这么一下,几个月都不需要再手动更新了

6 个赞

windows系统的好处dll分发很方便,我一直用 GitHub - casouri/tree-sitter-module: Building script for tree-sitter language definitions · GitHub 也是不用装mysys2

2 个赞

对我来说用别人分发的 dll 总是有各种各样的问题,一是 abi 版本不一致就会导致用不了(例如我文中提到的 tree-sitter-langs),二是跟我需要的 libtree-sitter-*.dll 不符(例如你给的这个仓库里就缺少 ocaml,zig 的上游地址也不对)

而我又不想装 msys2,只能通过官方提供的 cli 做了😂

fork一个repo然后通过github action的windows虚拟机编译也可以的