基于msys2的irony安装经验

这两天尝试重新编译安装 irony 模式,发现有如下改变,首先是到无中文路径的,解压后的目录中的 server 目录下新建 build 目录,然后在 msys2 的环境中进入这个目录,确保在路径中加入 /d/dev/emacs/bin:/mingw64/bin ,最好加在最后面,以便 cmake 找到它们,然后只要用 /usr/bin/cmake.exe … 这个命令就可以正常构建,然后 make 就可以了。

步骤虽然不多,但其中花了不少时间来踩平各种坑,所以要记载一下。首先,为了测试的需要,我要在 windows7 上面,已经安装的 emacs 的基础上,另外建立一个 emacs 的配置文件夹,参考这篇文章:
在windows系统上指定emacs的启动文件支持多配置
412_在windows系统上指定emacs的启动文件支持多配置_grey_csdn的博客-CSDN博客

然而,文章中有个地方似乎有问题,按题主的说明,在他建立的快捷方式中,目标是: D:\emacs\bin\runemacs.exe -q --load=D:\emacs_test_dir.emacs.d\init.el --load=D:\emacs_test_dir.emacs

他说:“第二个参数是启动后,emacs默认访问的目录。”
但是,无论从 --load 的定义来看,还是看题主出示的截图,都说明加载的两个都是文件: init.el , .emacs 。

所以我就把后面那个 --load 参数去掉了,也没什么问题。

接下来是编译 irony-server 的问题,可谓一波三折。首先,在 windows 上使用 irony ,是需要 libclang.dll 的,我一直是通过 msys2 来安装 llvm 的,我知道 irony-server 可以在 emacs 中用 M-x irony-install-server 来安装,但是,由于我是个各种编程工具的爱好者,所以在系统中安装了各种编程工具,有些会设置 Path 环境变量,而我发现,如果没有把 msys2 的路径放在 Path 变量的最前面,编译出的 irony-server 或许也能用,比如网上一直说,如果用 irony-server --version 命令能够有版本号的输出的话,就说明 irony-server 安装成功了,但我发现其实,这样并不一定就是能在 emacs 中正常运行的,我就曾经编译出一个这样的可以显示版本号的 irony-server ,结果在 emacs 中用 company-irony 命令进行测试时,会显示:

“)) (:temp-file “d:/Personal/Temp/irony-unsaved-qEjeeK” :buffer-state #s(irony–buffer-state “d:/dev/temp/Cpp-Demo-Project-For-Emacs-master/Cpp-Demo-Project-For-Emacs-master/src/main.cpp” t t 51)) #s(irony-iotask-packaged-task (:start (lambda (file line column compile-options) (apply #'irony–server-send-command “complete” file line column “–” compile-options)) :update irony–server-command-update) (“d:/dev/temp/Cpp-Demo-Project-For-Emacs-master/Cpp-Demo-Project-For-Emacs-master/src/main.cpp” 8 3 (”-x" “c++”)) #s(irony-iotask-result nil nil nil nil) nil #s(irony-iotask-packaged-task (:start (lambda (prefix style) (irony–server-send-command “candidates” prefix (cl-case style (case-insensitive “case-insensitive”) (smart-case “smart-case”) (t “exact”)))) :update irony–server-query-update) (“h” exact) #s(irony-iotask-result nil nil nil nil) nil nil))) "(error . (file-read-error “failed to read unsaved buffer” “d:/dev/temp/Cpp-Demo-Project-For-Emacs-master/Cpp-Demo-Project-For-Emacs-master/src/main.cpp” "d:/Personal/Temp/irony-unsaved-qEjeeK ")

所以我觉得还是从 msys2 的命令行,手工编译 irony-server 算了。
那首先是要准备 msys2 中的 llvm 和 clang 环境,我用的是 msys2 的 64 位版本,

pacman -S mingw-w64-x86_64-make mingw-w64-x86_64-gdb mingw-w64-x86_64-clang mingw-w64-x86_64-clang-tools-extra mingw-w64-x86_64-polly

然后,我在 emacs 中使用 package 来安装那篇文章中提到的 irony-mode 等,

clang-format cmake-ide company irony company-irony markdown-mode company-irony-c-headers monokai-theme flycheck flycheck-irony yasnippet

没想到,一个简单的操作,引发了诡异的事情,package 抱怨说找不到公钥,在显示错误消息的缓冲区中,我发现 gnupg 说在某个目录下没有 public.kdbx ,然后这个目录好奇怪,看上去是两个目录的拼接。经过无数次的研究,我终于 确定问题是 msys2 自带的 gnupg 造成的,需要卸载这个自带版本的 gnupg ,用 mingw-w64-x86_64-gnupg 来代替。但是 gnupg 是不能卸载的,因为有依赖关系,所以我只好先安装正确版本的 gnupg ,然后用 pacman -Ql gnupg 来列出所有的文件,然后想办法从文件列表做个批处理,把原来的 gnupg 文件都移走。

现在可以到 irony 的 github 页面下载源代码,我目前看到最新的是 1.4.0 版本,下载后按前述解压编译,安装时放到哪个目录?这个可以参考 M-x irony-install-server 命令的参数,一看就知道它安装在哪里了。

然后还是环境变量的问题,我不喜欢把 msys2 的路径放在系统变量中,所以我尝试了两个方案,一个是在快捷方式中执行多个指令:

C:\Windows\System32\cmd.exe /C “set PATH=D:\dev\msys64\usr\bin;D:\dev\msys64\mingw64\bin;D:\dev\emacs_test_dir.emacs.d\irony\bin;%PATH%” & D:\dev\emacs\bin\runemacs.exe -q --load=D:\dev\emacs_test_dir.emacs.d\init.el

记得把图标改回 emacs 的,在 D:\dev\emacs\share\icons\hicolor\scalable\apps 。启动路径我觉得最好改在常用的目录。

现在,是根据这篇文章来设置 emacs 的 irony 配置的时候了:
打造 Mac OS 的 C++ IDE(Emacs 篇)
打造 Mac OS 的 C++ IDE(Emacs 篇) | Senlin's Blog

可惜了,windows 上面不能安装 rtags ,所以文章中有关 rtags 的部分就忽略了,基本上文中的配置是拿来就可以用,只是题主似乎漏掉了这个:

(add-hook 'c+±mode-hook 'company-mode)
(add-hook 'c-mode-hook 'company-mode)
(add-hook 'objc-mode-hook 'company-mode)

在加上这个之后,这段配置看起来是这样的:

;; 启动 company 模式
(require 'company)
(add-hook 'after-init-hook 'global-company-mode)
(add-hook 'c+±mode-hook 'company-mode)
(add-hook 'c-mode-hook 'company-mode)
(add-hook 'objc-mode-hook 'company-mode)

然后,下载一个
Cpp-Demo-Project-For-Emacs
GitHub - byuksel/Cpp-Demo-Project-For-Emacs: C++ Demo Project for Emacs Intellisense Setup

结果发现项目自带的头文件目录没有被 irony 和 flycheck 感知到,参考这篇文章:
Best way to include header paths in flycheck-mode and what role do flycheck-mode and company-mode play?
Best way to include header paths in flycheck-mode and what role do flycheck-mode and company-mode play? · Issue #340 · Sarcasm/irony-mode · GitHub

修改的是:

(setq irony-additional-clang-options '(“-std=c++11”
“-ID:/dev/temp/Cpp-Demo-Project-For-Emacs-master/Cpp-Demo-Project-For-Emacs-master/my_inc”
))

1 个赞

生命不息,折腾不止。。。

我看目前好像大都是用 lsp-mode 或者 eglot 这两个LSP前端配合 Clangd 或者ccls 后端。 这个irony 有什么优势吗?

我比较懒,用 eglot + clangd,开箱即用。