type
status
date
slug
summary
tags
category
icon
password
众所周知,VS Code 只是一个文本编辑器,而不是 IDE(集成开发环境,比如Dev-C++),如果想要获得如IDE一般的体验需要我们手动DIY。
想直接跟着配置的同学可以跳到“正式开始配置”章节开始阅读
前言介绍
LSP(Language Server Protocol)
👉 Question:什么是LSP呢?
在传统 IDE 中要为编程语言提供代码自动补全或跳转到定义等功能,非常具有挑战性且耗时。 通常需要使用编写IDE的语言编写域模型(扫描程序、分析程序、类型检查器、生成器等)。
这意味着在 Eclipse 中支持 C/C++的插件,是采用 Java 编写的,因为 Eclipse 本身是采用 Java 编写的。而在 Visual Studio Code 中需要用 TypeScript 实现 C/C++ 域模型,在 Visual Studio 使用 C# 实现单独的域模型。
但是现在,通过LSP这一抽象层,我们可以复用域模型了。
语言服务器在其自己的进程中,文本编辑器与语言服务器通过进程间通信实现交互。 来回发送的消息遵循约定的协议。
Intelligence for C++
网上的教程大多都会推荐C/C++ Extension Pack,这和VS Code同属微软出品,但实际上这个插件的提示比较卡顿、更新频率低,也并不是LSP。
现在有更好的插件就是LLVM出品的Clangd,它是支持LSP的,安装好插件后,还需要安装language Server。
同时,clang全家桶还带来许多特色功能:自动插入头文件、clang-format、clang-tidy等。许多北美名校的Lab现在都是使用的clang工具链准备的。
其他
需要注意的是,单独一个源代码文件是不支持Intelligence的,但是我们可以通过CMake快速生成一个项目。
Intelligence的原理是分析
complie_command.json
文件,我们通过CMake构建系统可以快速生成这个文件。(后面有详细讲解)编译器(Compiler)
建议用系统默认的三大家:
- windows —— msvc
- mac —— clang
- linux —— gcc
通过g++ -v我们可以发现mac上的g++实际上是clang
使用默认工具链是最简单有效的方式。相应的,升级工具链也是最困难的一件事,比如各种基于 centos 的魔改操作系统 锁死了gcc4.8.5。
构建工具
👉 Question:构建工具解决了什么问题?
同一个项目,使用不同编译器,编译命令也不相同,所以我们需要通过构建工具统一。同时当项目变得复杂了之后,我们绝对不会想要每次都输一长串内容,通过构建工具能大大节省我们手上的活和心智负担。这也就是我们所谓的“write once build everywhere“
有些同学会认为shell脚本简化编译命令也能做相同的事情。如果是写shell,你需要自己处理好一切细节,渐渐地,你开始处理Shell脚本的时间将几乎与处理实际代码的时间一样多。而构建工具能够自动帮助你管理项目,同时也提供了更多的功能。
(有兴趣了解构建系统的同学,可以看下面的文章)
各家的构建工具对比(点击左边展开)
1️⃣ 大名鼎鼎的CMake
✅ pros:
- 最流行的构建工具,稍微有点名气的开源项目都会提供 CmakeList
- 功能齐全
❌ cons:
- 语法比较复杂,难以调试
- 历史债务多,类似modern c++,也有人为此写了modern cmake。
- 抽象层级太低,cmake只帮你生成了更低层级的编译配置(makefile、ninja、sln),它甚至不会去调用编译器。如果你不会c++本身的编译过程,就比较难用好cmake
2️⃣ bazel
✅ pros:
- 语法简单,抽象程度适中(至少能直接 bazel build)
- 支持分布式编译
❌ cons:
- 流行度不高
- 限制多(或者说功能少,大道至简),适合monorepo模式
- 自定义规则(宏) 比较烦人
bazel是一个适合大公司的构建工具,需要一些定制化开发,限制每个人操作范围来方便管理(和同属Google出品的go一样,大道至简)。但是对开源社区并不友好。
3️⃣ xmake
✅ pros:
- 轻量。每个平台安装都非常简单。
- 使用lua配置。不像cmake、bazel那样自己造DSL(domain-specific language,一门自定义的语言)
- 自定义规则简单。rule和plugin两张,得益于lua而不是dsl,写起来舒服多了。
- lua虽然不算特别火,但在基建工具方面还是被广泛使用的(Nvim也支持使用lua进行配置)。
- 抽象程度高。自动发现编译工具链、调用工具链。
- 快!支持本地缓存,windows下会发现编译比之前快太多,非大公司没有二次开发能力也能享受到良好的开发体验
- 社区活跃。安利的人多,用过都说好
- 命令行提示友好
❌ cons:
- 社区虽然比较活跃,但是比较依赖核心开发者@ruki,缺少大公司背书。
非常适合自己私下倒腾项目使用,也在慢慢流行起来。
C++的包管理/依赖管理
由于语言标准中缺失包管理的部分,不同于其他语言的用户主动发布包,c++的包管理器基本都是使用一个仓库(官方或者用户自建,不限于github仓库),在仓库里按照一定格式维护依赖的索引(URI、编译指令、测试指令等等),然后构建工具自动调用包管理器下载依赖包。
各家的包管理工具对比(点击左边展开)
1️⃣ 微软的vcpkg
- 推出时间比较早,可以在cmake、vs中使用,功能非常多(可以写成manifest的形式)。非windows平台使用体感较差。
2️⃣ xmake的xrepo
- 和xmake集成使用非常方便,支持语义化版本,依赖的索引维护也比较简单(写lua总是比cmake好写),还可以从多种包管理器里添加包(vcpkg,conda等)。
3️⃣ bazel的bzlmod
- 推出时间比较晚,观望
总体来说,包管理器和构建工具有比较强的绑定关系。选择了什么构建工具基本决定你使用什么包管理器。
正式开始配置
先看最终效果
可以看到支持代码提示、一键编译运行、debug等功能
安装需要的软件和文件
下载VS Code对同学们来说应该问题都不大,直接略过
另外,同学可以下载我提供的文件夹来测试是否设置成功(应该会用git吧🤔):
安装插件
首先我们需要安装如下插件:
- clangd:为了Code IntelliSense
- CodeLLDB:为了在Mac上debug
- gdb需要x86架构,所以Mac用不了,我们只能使用lldb。但既然在VS Code里使用UI界面了,所以底层是什么db关系不大。
- Code Runner:一键运行代码
- CMake
配置插件
接下来我们需要对插件进行一些配置:
- 首先是安装LSP:
使用 Cmd + Shift + P 打开 VS Code 的命令面板,然后输入clangd,选择Download languafe server就能自动下载clangd提供的LSP了。
- 配置一键运行C++文件的命令(其他语言同理)
在Code Runner上点击右键,选择扩展设置a(Extension Settings)
让运行的程序支持input: 在插件配置中勾选 Run in Terminal(你可以暂时不勾选,试试input失效是什么样子的)
然后随便选一个Edit settings.json打开(都一样的)
更改语言对应的运行命令(我这里是添加了对C++17的支持)
Code Runner本质原理就是根据文件的拓展名,自动输入一条对应的编译运行指令
神秘的.vscode
文件夹
.vscode
是VSCode的配置文件夹,里面放有各种配置文件,下面举几个重要的例子:tasks.json
:定义任务(Tasks)。任务是在VS Code中执行的命令或脚本,可以自动化一些常见的工作流程,如编译代码、运行测试、构建项目等。
launch.json
:配置调试器(debugger),设置调试选项,如指定调试目标(例如Node.js、Python等),设置启动参数、环境变量等
c_cpp_properties.json
:包含了编译器路径、头文件搜索路径等信息,主要用于编辑的代码智能提示(IntelliSense)使用clangd后不用配这个了
extensions.json
:这个文件用于记录项目所依赖的扩展插件。当共享项目时,其他人可以根据这个文件安装所需的插件,以便与大家的开发环境保持一致。
settings.json
:这个文件包含了项目的设置选项。如设置代码风格、启用或禁用扩展插件、定义编辑器的行为等。这些设置会覆盖全局设置,只对当前项目有效。
文件内容
💠 launch.json
💠 task.json
💠 c_cpp_properties.json
使用includePath指出非标准路径之外的路径
测试文件(C++11)
添加对Debug的支持
前面的配置文件够了,这里只是说明原理
只写
launch.json
文件的话,如果想边对文件进行修改,边进行debug调试,需要每次改完都生成一次可执行文件。那么我们可以通过与Task配合,达到每次debug前都会自动重新build生成全新可执行文件的效果。只需要在
launch.json
文件加入一个"preLaunchTask"字段(上面的文件里已经写了)- 需要注意的是,preLaunchTask需要与task里面的label一致
从终端直接打开VS Code
然后在终端通过
code main.cpp
能够直接打开 VS Code 来编辑main.cpp文件Clangd配置常见问题
有些同学可能会遇到代码Intelligence失效的问题。
那么我们可以打开clangd进程(在整个窗口的左下角),查看日志,它在说发现找不到编译数据库
那么这个所谓的编译数据库在哪里呢?
clangd依赖
compile_commands.json
文件生成compilation database, clangd靠这个编译数据路来完成对项目的解析,之后便可提供代码跳转,自动补全、重构、格式化等功能。我们可以使用CMake在build文件夹里自动生成这个文件。我们只需要通过命令面板里输入Quick Start就能立马将一个项目(注意得是文件夹,而不是一个文件)配置完成。(如下图)
一键配置好项目后,会发现文件夹中多了一个build子目录,里面有好多文件,这些都是配置文件。
支持万能头文件bits/stdc++.h
标准头文件是一个写算法题时很方便的库,里面包含了所有头文件。
tl;dr:复制下面的文件内容,直接放在工作区内通过相对路径使用(弊端是只在当前工作去有效)
<bits/stdc++.h>
文件
TL;DR:
And you can use it on MacOS now!
MacOS ships by default with the LLVM/Clang compiler which does not support GNU/GCC extensions such as the
bits/stdc++.h
header file.Note:
After the XCode 6.0.1 update the headers are now located here:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1
如果网络错误:
手动复制粘贴一下吧
bits/stdc++.h
是GCC的库而不是标准库,而Mac的默认编译器是Clang,因此不包含这个库。首先,我们要知道问题根源所在,为什么引入
iostream头文件
可以,而引入bits/stdc++.h
不行?我们发现在VS Code中尝试万能头文件的时候显示未定义,而尝试
isotream
的时候可以跳转到某个文件,在这个文件的路径下会发现有好多头文件的定义,我们vscode引入头文件就是从这里寻找引入的。那么我们把
<bits/stdc++.h>
也放在这个地方就好了。注意一个细节:
stdc++.h
才是头文件名,它在bits
这个文件夹下的。所以我们要做的就是新建一个名为bits
的文件夹。然后在其中新建一个文件stdc++.h
。如果做完这些,VS Code在编译时还是找不到头文件:
问题原因: clang编译时需要通过参数指定从非标准路径搜索标准库头文件。
解决办法:修改vscode的settings,加入配置
主要是fallbackFalgs(头文件搜索路径)
代码片段
在左下角进入配置
写代码时通过前缀可以直接触发
我的代码片段(主要是快速起一个main函数和一些数据结构定义(面试时白板写代码可以直接用))
就是丝般顺滑~~~
(具体可以看后面我的演示视频)
其他内容
VS Code快捷指令的Cheat Sheet:
VS Code原理
VS Code本质只是一个浏览器,它是基于Monaco Editor实现的(更底层就是Electron)。所以如今VS Code能够直接在网页端(https://vscode.dev/)运行也是顺理成章的事。
VS Code里的终端是基于Xterm.js的。
VS Code Config的逻辑:
- 基于JSON:复杂的选项可能只能通过JSON
- 基于UI
现在很多公司也会直接在容器内安装一个VS Code,员工通过端口连接进去开发,实现了环境的统一。(尤其是容器位于海外的时候,各种软件安装都非常流畅)
最后给大家推荐一本书——《玩转VS Code》
无关的东西
💠 欢迎大家在上面画图玩
居然能在Google搜到自己
- URL:/6ca7166cea0e43ab9b060bdb7185d210
- Copyright:All articles in this blog, except for special statements, adopt BY-NC-SA agreement. Please indicate the source!