ubuntu vscode安装_ccls 和 vscode 一种在vscode以外的c++方案

4812087b118cbad8a18916c607bc1efb.png

什么是ccls

使用vscode写c++在知乎上已经是一个谈烂了的话题了,基本上可以简化为安装c++插件,写launch.json,然后debug。但是今天要介绍一个不一样的姿势,通过ccls,体验lsp的美妙,先上效果,这里以浏览webrtc代码为例,ccls提供了基于语义的高亮、代码的引用统计、补全

ccls还同时可以提供基于编译结果的跳转和引用查找、vscode的tag等功能,面对大型的工程也能有良好的性能表现

b3b76066d69625d6bec233221ace8e15.png
https://github.com/MaskRay/ccls​github.com

获取ccls

ubuntu/linux用户可以通过官方文档编译安装

编译建议在安装了libclang后直接使用libclang编译,以下是ubuntu18.04编译的方法

sudo apt install clang libclang-dev
# 下载ccls源码
git clone https://github.com/MaskRay/ccls
cd ccls
# 在ccls根目录下执行
# 第0步,下载第三方依赖(主要是rapidjson)
git submodule update --init --recursive
# cmake 生成makefile
cmake -H. -Bbuild/Release -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
make -C ./build/Release -j4
sudo make install -C ./build/Release

如果最后一步出现了找不到optional头文件的问题,那你需要安装一个支持c++17的编译器,这里以clang-7为例,将上面的最后三句替换为

cmake -H. -Bbuild/Release -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_CXX_COMPILER=clang++-7
make -C ./build/Release -j4
sudo make install -C ./build/Release

如果想要指定ccls编译的llvm的版本的话可以在cmake的命令前加一句

# 以指定到llvm-7为例
cmake -H. -Bbuild/Release 
          -DCMAKE_EXPORT_COMPILE_COMMANDS=ON 
          -DCMAKE_CXX_COMPILER=clang++-7 
          -DClang_DIR=/usr/lib/llvm-7/lib/cmake/clang 
          -DLLVM_DIR=/usr/lib/llvm-7/cmake/
make -C ./build/Release -j4
sudo make install -C ./build/Release

或者从官方下载预编译包开始入手

# 下载ccls源码
git clone https://github.com/MaskRay/ccls
cd ccls
# 在ccls根目录下执行
# 第0步,下载第三方依赖(主要是rapidjson)
git submodule update --init --recursive
# 第一步,下载llvm的二进制包
# 这一步可以用任何下载工具代替,只要使用的是这个网址的结果即可
wget -c http://releases.llvm.org/8.0.0/clang+llvm-8.0.0-x86_64-linux-gnu-ubuntu-18.04.tar.xz
# 解压二进制包
tar xf clang+llvm-8.0.0-x86_64-linux-gnu-ubuntu-18.04.tar.xz
# 在当前文件目录下执行cmake 执行结果保存到Release文件夹中
cmake -H. -BRelease -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH=$PWD/clang+llvm-8.0.0-x86_64-linux-gnu-ubuntu-18.04
cmake --build Release
# 开始编译并安装
cd Release
# 这里使用4线程编译,当然如果你的电脑够强的话,可以直接-j或者使用更搞核数加快编译
make -j4
# 编译完成,安装
sudo make install

mac用户想要使用最新版的ccls,那么在编译的时候必须指定llvm的版本,在通过homebrew下载llvm之后,可以通过以下操作安装

# 下载依赖
brew install llvm
# 下载ccls源码
git clone https://github.com/MaskRay/ccls
cd ccls
# 在ccls根目录下执行
# 第0步,下载第三方依赖(主要是rapidjson)
git submodule update --init --recursive
cmake -H. -Bbuild/Release 
          -DCMAKE_EXPORT_COMPILE_COMMANDS=ON 
          -DClang_DIR=/usr/local/opt/llvm/lib/cmake/clang 
          -DLLVM_DIR=/usr/local/opt/llvm/lib/cmake
make -C ./build/Release -j
sudo make install -C ./build/Release

需要注意的是如果安装了brew里的rapidjson似乎会造成找不到json头文件的问题。可以在cmake中增加-DUSE_SYSTEM_RAPIDJSON=off参数不使用brew安装的版本

当然home-brew中提供了更简单的安装方式,但是那个版本和最新版已经相差半年,两者的性能差距较大,这里不建议安装brew的版本

brew install ccls

让我们看看安装好的ccls

6fcd7a41e387d956676b65506d64cadb.png

ccls和vscode的结合

接下来轮到折腾vscode了

安装vscode相对简单这里不再赘述,到vscode的插件商店直接下载就可以了,我们需要先安装一个插件作为ccls的客户端

50a3d14caf625ea3e0b7ec8b31a73607.png

这个看起来像没人维护的插件的就是ccls如假包换的客户端了(目前ccls还没有logo欢迎issuer提供意见),安装好就可以开始体验了,让我们随便打开一个main.cpp文件开始编辑,然后就发现没有补全

292b7ba217b9ada18c3ef939fd83f9d5.png

显然事情并没有这么简单,ccls基于llvm前端,需要编译条件才可以工作,我们创建一个.ccls文件,填入以下内容,然后打开整个文件夹

clang
%c -std=c11
%cpp -std=c++2a
%h %hpp

我个人推荐开启详细补全以获得更好的体验(补全结果中的类型提示)vscode的设置方法如下

{
    // 开启更加详细的补全结果
    "ccls.completion.detailedLabel": true,
}

如果你是一个linux用户,且你的文件显示是这样,那么恭喜你,折腾结束可以开始下一章的内容了,

6310fd5501abcfb0a91701ef790cdbad.png

但是如果你是一个mac用户,你看到的可能是这样

cf6be6e050a7ab62eccc38965a843141.png

显然,这些补全是有了,但是编译结果并不对,尤其是mac上会出现这种问题,这是因为homebrew下载的ccls在编译的时候不使用自带clang编译导致的,我们在vscode的工作区设置里 加上这么几句,之后重启vscode以生效(理论上重启ccls就可以了,但是实际上有时会没有效果,我还是建议直接重启整个vscode)

{
    // 开启更加详细的补全结果
    "ccls.completion.detailedLabel": true,
    "ccls.clang.extraArgs": [
        "-isystem",
        "/Library/Developer/CommandLineTools/usr/include/c++/v1",
    ],
    "ccls.clang.resourceDir": "/usr/local/Cellar/llvm/9.0.0/lib/clang/9.0.0",
    "ccls.launch.args": [
        // 添加log文件的输出
        "-log-file=/tmp/ccls_vscode.log",
        // 关闭ccls的代码折叠,ccls的代码折叠不如原生的好用
        "--init={"capabilities": {"foldingRangeProvider": false}}",
    ]
}

fe2169b9ca5888b037e572c2df23a1ce.png

这下ccls可以提供正确的补全信息了

基于语义的着色

本文的一开始有提到ccls还有另外一个大招,基于语义的着色,我的着色方案如下,可以放到vscode的设置中体验,为了提高读代码的体验,我将所有的类型都设置了不同的颜色,注意完成设置之后需要重启vscode生效

  "ccls.highlight.function.face": [ "enabled" ],
  "ccls.highlight.function.colors": [ "#e5b124", ],
  "ccls.highlight.member.face": [ "textDecoration: underline" ],
  // Mix of variable.face and global.face
  "ccls.highlight.global.face": [ "fontWeight: bolder" ],
  "ccls.highlight.static.face": [ "fontStyle: italic" ],
  "ccls.highlight.namespace.face": [ "enabled", "fontWeight: bolder" ], 
  "ccls.highlight.namespace.colors": [ "#00d780", ],
  "ccls.highlight.type.face": [ "enabled", "fontWeight: bolder" ],
  "ccls.highlight.type.colors": [ "#4ec8af", ],
  "ccls.highlight.macro.face": [ "enabled", "fontWeight: bolder" ],
  "ccls.highlight.macro.colors": [ "#5f0087", ],
  "ccls.highlight.variable.face": [ "enabled" ],
  "ccls.highlight.variable.colors": [ "#26cdca", ],
  "ccls.highlight.globalVariable.face": [ "variable", "global" ],
  "ccls.highlight.parameter.face": [ "variable", "color:#306b72" ],
  "ccls.highlight.memberVariable.face": [ "variable", "member", "color:#7ca6b7" ],
  "ccls.highlight.enum.face": [ "enabled", "fontWeight: bolder", "color:#397797" ],

效果可以看最上面的效果图,这里需要特别注明的是,ccls支持一个类型给多个配色,目前默认环境下ccls会为一种类型设置多个颜色,如果想要改颜色的话,建议还是不要删掉对应的设置而是写明是哪一种的为好。

另外一个需要注意的点是,ccls当前似乎只会在文件重新保存的时候更新语义着色,所以有时发现着色的结果不对的话,可以考虑保存文件再看看。

d92869c2fbceb99447b4d1723538a305.png
下面两个函数是新写上去的,没有着色的结果,但是构造函数着色正确

我的工程很大,怎么写.ccls文件呢

对于大型的工程,通过手写.ccls文件实现配置显然不现实,我们可以通过使用编译数据库(compile database) ,常见工程产生compile_commands.json 的方法可以见官方文档,大多数只需要运行时添加一些参数即可获得,获得compile_commands.json之后需要将这个文件放到根目录下生效

MaskRay/ccls​github.com
1820d3f2d3c439f8c7ba0e2d1190e6d4.png

这里以webrtc的ninja工具为例:webrtc编译完成之后ninja的文件一般在out目录下,我们可以通过以下命令产生 compile_commands.json

ninja -C out -t compdb cxx cc > compile_commands.json 

在其他地方可以修改-C参数之后的目录即可

重启vscode 之后可能会开始卡,这是ccls在"编译"工程,等到ccls的工作做完就安静了

c538f7c39e82b3a3994c317092df12f2.png

之后就可以尽情享受ccls带来的补全和跳转了

fb7ed60bb940e874796a22b65cf4feae.png

对于cmake用户而言,创建compile_commands.json文件就很简单了,保证你的cmake版本在3.9以上(尤其你是ubuntu16.04以前的用户的话),然后安装cmake插件,微软出品,自然是好用

899d01508a6cb8bedf18343a12b61b6c.png

当然如果你和我一样喜欢自己整,对cmake有自己的需求需要命令行编译,执行的时候需要指定产生compile_commands.json,命令大概如下

cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON ..

在你的工作区设置中加入这两行,保证cmake的编译目录和ccls查找compile_commands.json时用的是同一个文件夹

// ${workspaceRoot}指工作区根目录
"cmake.buildDirectory": "${workspaceRoot}/build",
// ccls的设置似乎只能选择相对根目录的位置
"ccls.misc.compilationDatabaseDirectory": "build",

按F7编译之后重启ccls,就可以了

如果你的cmake使用的是ninja作为编译管理,产生的compile_commands.json内包含相对路径,这个时候如果编译数据库中的第一个参数不是clang++会导致ccls无法正常工作,可以用下面这个命令替换一下

sed -i".origin" -e "s//Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++//usr/local/opt/llvm/bin/clang++/g" <Path/to/compile_commans.json>

缓存ccls的编译结果

ccls在默认情况下是会缓存ccls的编译结果的,这可以避免每一次都需要重新编译工程

在vscode中我们可以通过添加缓存文件夹的形式保存编译结果加快启动速度,避免不必要的启动开销,默认是.ccls-cache,如果你不喜欢这个文件夹,可以通过以下设置修改

  "ccls.cache.directory": ".ccls-cache-vscode"

参考ccls的wiki相关的部分,其他客户端可以在这里找到

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值