使用ccls作为C/C++的补全方案
前言
最近使用 C/C++
开发,在 Emacs
下使用 Cmake
作为编译工具,结合 ccls
进行代码补全,有着不错的体验,于是记录一下。
ccls 介绍
ccls
是基于cquery的 C/C++/Objective-C
的代码补全的工具,它实现了 C/C++/Objective-C
的Language Server Protocol的服务端。支持代码补全,代码的引用查找和跳转,有着良好的体验。
我使用 ccls
是由于它能支持 lsp
,可以在 Emacs
中使用。当然也是支持 Atom
、 Vim
、 VSCode
等编辑器的。
安装ccls
Mac
在 mac
下安装 ccls
使用 brew install ccls
十分的方便,但是这个版本还停留在 0.20190823.6
实在是太老旧了。使用过程中发现并不能很好的工作,建议采用源码编译。
编译过程如下
cmake &llvm
ccls
的编译需要 cmake
和 llvm
,所以在编译之前需要安装 cmake
和 llvm
。
|
|
使用 brew
安装的 llvm
路径在 /usr/local/Cellar/llvm/10.0.1
,编译 ccls
会用到。
编译ccls
|
|
ccls
会被安装到 /usr/local/bin/ccls
。
其中 -DCMAKE_PREFIX_PATH
需要换成你的 llvm
的安装路径。
这样 ccls
就编译好了。
Linux
我所使用的 Linux
发行版是 Manjaro
,所以安装起来就非常方便了。
|
|
命令执行完,也就安装好了,非常省事。
其它 Linux
发现版,可以参考 Build · MaskRay/ccls Wiki
为项目配置 ccls 补全
当我们装好 ccls
后,就可以使用 Emacs
结合 lsp
打开 C/C++
的项目,在项目的根目录下就会生成 .ccls-cache
的文件夹。这就表示当前项目被 ccls
识别了。
做完上面之后,我们打开文件,会发现许多文件都会找不到头文件,补全也不完整,甚至连 iostream
都找不到,这就很纳闷了。
我的 C/C++
项目采用的是 cmake
作为编译工具,所以在查找官网资料后,发现只要在使用 cmake
的时候加上 -DCMAKE_EXPORT_COMPILE_COMMANDS=On
,然后把 compile_commands.json
放到根目录就行。
具体操作入下
|
|
-DCMAKE_EXPORT_COMPILE_COMMANDS
会告诉 cmake
把编译的指令都导出到 compile_commands.json
中,当 ccls
解析 compile_commands.json
后就知道源码在哪里了,知道去哪里找头文件等等。
除了在命令行加上 -DCMAKE_EXPORT_COMPILE_COMMANDS
参数外,还可以在 cmake
中设置,这样就可以避免每次编译都要输入,或者忘记。
|
|
如果你不是使用 cmake
作为编译工具可以参考 Project Setup · MaskRay/ccls Wiki
在 QT 中使用 ccls
在上面提到过,要为项目配置 ccls
关键就是 compile_commands.json
,所以想要在 QT
中使用 ccls
就需要生成 compile_commands.json
文件。
在 QtCreate
的菜单栏中,选择构建 -> Generate Complation Database for xxx
就会在编译的目录(Build directory,可以项目的构建设置中查看)下生成 compile_commands.json
文件。
最后把 compile_commands.json
软连接到项目的根目录,这样就能够使用 ccls
来补全代码了。
更新ccls
随着时间的流逝,我们的软件包在不断的更新,这时候就会碰到,我们的程序明明是对的,但是还是报错,就连最基本的 std::cout
都报错,这时候就需要考虑是不是升级了 llvm
。
如果你升级了 llvm
那么你是需要重新编译一下 ccls
,因为 llvm
的路径变了,所以查找的路径也跟着变了。
这时候我们只需要照着上面的步骤再执行一遍就可以了。别忘记编译参数 DCMAKE_PREFIX_PATH
要更新。
更新完之后就可以正常使用了。
错误 c++ is not able to compile a simple test program
|
|
碰到这个问题的解决办法是需要删除掉 Release
目录,就能正常编译。
|
|