本文介绍了基于 VSCode 的 C/C++ 开发环境的搭建方法。
1. 简介
VSCode是微软推出的一款跨平台开源编辑器,凭借强大的第三方插件支持C/C++、Python、Java等众多语言,体积小巧功能丰富,适合小型工程项目的开发调试。下面简单介绍VSCode开发环境的部署。
注意,VSCode仅仅是一个前端文本编辑器,本质上与记事本并无不同,在没有插件和编译器的情况下只能进行文件的读写,并不能进行源程序编译调试。与之相对,微软自家的Visual Studio是一个集成开发环境(IDE),下载安装后可以直接进行源程序的编译调试。
一个现代编译器的主要工作流程如下: 源代码 (source code) => 预处理器 (preprocessor) => 编译器 (compiler) => 汇编程序 (assembler) => 目标代码 (object code) => 链接器 (Linker) => 可执行文件 (executables)。VSCode 本身仅仅是一个源代码编辑器。不过,当配合插件和编译器后,VSCode也能够完成绝大部分的源代码编译调试工作。
2. 下载与安装
前往官网(https://code.visualstudio.com)下载安装,支持Windows、Linux和Mac系统。可以下载安装版,也可以选择解压即用的绿色版。区别在于安装板会向系统路径写入配置信息,绿色版所有的依赖信息和配置信息均存放于一个目录中。安装版可以在线下载更新和安装更新,绿色版只能下载新版本的绿色安装包解压后覆盖来更新。
安装完成后,点击左侧的扩展商店,搜索chinese,下载中文简体汉化包(可能需要翻墙)。
安装完成后重启VSCode,即可发现所有界面均已汉化。
注意:
VSCode基于文件夹进行编译和调试,每个项目必须对应一个文件夹作为工作路径(根目录),根目录内包含一个.vscode文件夹存放配置文件(json格式);
VSCode默认编码为UTF8,对中文支持并不完美,特别是打开已有的包含中文注释的源代码文件时要特别注意,可能导致中文乱码,且在保存文件时弹出警告。因此,对于包含中文注释的已有文件,一般需要新建一个空白文件,保存为UTF8编码格式,然后重新输入中文注释部分再进行保存。
3. 配置C/C++开发环境
3.1. 部署编译器
扩展商店搜索“C”,安装微软官方出品的C/C++扩展。然后重启VSCode。
然后配置C/C++编译器。在Windows环境下,VSCode支持MSVC编译器和MinGW-w64编译器,二者选一个即可。
- MSVC编译器 即为Visual Studio使用的C/C++编译器(核心文件为cl.exe),如果下载安装了VS的某个版本(如VS2019),则该编译器已经自动部署到了计算机中。采用VSCode作为编辑器时,可以只单独安装编译器而无需安装完成的VS IDE。前往MSVC官网( https://visualstudio.microsoft.com/downloads/#other) ,找到并展开“Visual Studio 2019 工具”,选择“Visual Studio 2019 生成工具”,下载并按照提示进行安装。下载大小约为1GB,安装后磁盘空间占用约为4GB,远小于VS2019所需的20+GB。
- MinGW-w64编译器 是 Windows 下广泛使用的GCC编译器,MinGW 的全称是:Minimalist GNU on Windows 。它实际上是将C语言编译器 GCC 移植到了 Windows 平台下,并且包含了 Win32API ,因此可以将源代码编译为可在 Windows 中运行的可执行程序。而且还可以使用一些 Windows 不具备的,Linux平台下的开发工具。一句话来概括:MinGW 就是 GCC 的 Windows 版本 。MinGW-w64 与 MinGW 的区别在于 MinGW 只能编译生成32位可执行程序,而 MinGW-w64 则可以编译生成 64位 或 32位 可执行程序。前往MinGW-w64官网(https://www.mingw-w64.org/downloads/ )下载并安装编译器。对于 Windows 环境,下载
MingW-W64-builds
版本,目前最新为12.1.0/10.0.0
,选择x86_64-12.2.0-release-win32-sjlj-rt_v10-rev0.7z
版本。安装时路径必须为全英文。
- 线程模型:任意均可
- [ posix ]:线程使用
pthread
的 Windows 版本。posix 是操作系统统一接口标准,不同操作系统需要提供相同的接口以方便应用移植,降低移植成本,但是只支持 POSIX 线程模型。pthread 是在 Linux 下常用的线程库,使用 posix 接口意味着应用的多线程模型移植更方便,哪怕从 Linux 下拉过来一个应用框架也可以较小代价修改代码。但在某些情况下会引起性能下降,毕竟不是 Windows 原生的线程库,C 标准可能到 C11 以上,并且支持 C11(C 语言编码标准)的特性;- [ win32 ]:使用 Windows 原生线程库,性能等方面表现更出色,兼容性更好,没有 C11 那些眼花缭乱的特性,就看你是否熟悉 Windows 相关接口。
- 异常模型:选择sjlj
- [ sjlj ]:setjmp/longjmp,这个版本的编译器支持 Windows 下的异常抛出。即你的程序出现错误时,可以调用 Windows 的异常处理,比如 Linux 下在程序运行错误时会报 Segment Fault,同时也支持在自己的程序中插入
setjmp()
或者longjmp()
函数以完成类似 goto 功能。这个版本支持 win32 和 win64,但是用这个编译器时你的代码编译成的二进制文件大小会膨胀,运行性能上损失约 15% 或更多,哪怕你的代码没有走到异常分支也是这样。即增大了性能开销,毕竟 Windows 嘛。- [ seh ]:zero overhead exception,异常分支处理零开销,即不会调用 Windows 的异常处理回调,完全由用户自己设计实现。该版本支持 win64。
- [ dwarf ]:dwarf(DW2,dwarf-2) 是一种可执行文件的格式,类似于 Linux 下的
elf
文件,以及 Windows 专用的.exe
或者安卓的.apk
安装包内的可执行二进制文件。dwarf 内部描述了可执行程序的函数符号信息、关联的动态库、变量、堆栈大小等一系列信息。该版本会将程序编译成以 dwarf 格式的二进制文件,Windows 本身支持该类型的可执行文件,但有个缺陷:如果你想调试你的程序,如 gdb 打断点调试,就不能调试 dll 接口,这样对于调用 dll 接口地方的传参就没有办法调试,从而没有办法得知是否是数据入参不正确或者库函数接口调用方式不正确。并且这个版本只有 win32 版本,而且编译时所有调用栈信息都会用 dwarf 格式存储,而非兼容 Windows 可执行格式。
3.2. MSVC 生成配置文件
VSCode进行编译连接等操作依赖一系列.json
格式的配置文件,这些配置文件都位于工作路径下的.vscode
文件夹内。
3.2.1. 语言配置(c_cpp_properties.json)
打开VSCode,打开一个工作文件夹,写一个hello world的.cpp程序。在工作路径的根文件夹中,然后按快捷键ctrl+shift+P,搜索“c/c”,选择 “编辑配置(JSON)” 。VSCode将自动创建.vscode/c_cpp_properties.json
配置文件。或者,我们也可以手动创建该配置文件并填充内容。
根据个人安装MSVC编译器的位置不同,配置compilerPath
路径(即cl.exe的路径)。以下图为例,除compilerPath
外,其它配置项保持与图中一致。
注意,该路径也需要保存在系统的环境变量 Path
中。否则会导致 cl
命令不可用。
3.2.2. 编译配置(task.json)
再次ctrl+shift+P,搜索 “task”,选择 “配置默认测试任务” → “使用模板创建…” → “Others 运行任意外部命令的示例”。VSCode将会自动创建.vscode/task.json
配置文件,我们同样也可以手动创建该文件。然后,用以下代码替换文件的所有内容:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
{
"version": "2.0.0",
"tasks": [
{
"label": "msvc build",
"type": "shell",
"command": "cl.exe",
"args": [
"/I'E:\\ProgramFiles\\Microsoft Visual Studio\\2019\\BuildTools\\VC\\Tools\\MSVC\\14.25.28610\\include'",
"/I'C:\\Program Files (x86)\\Windows Kits\\10\\Include\\10.0.18362.0\\shared'",
"/I'C:\\Program Files (x86)\\Windows Kits\\10\\Include\\10.0.18362.0\\ucrt'",
"/I'C:\\Program Files (x86)\\Windows Kits\\10\\Include\\10.0.18362.0\\um'",
"/I'C:\\Program Files (x86)\\Windows Kits\\10\\Include\\10.0.18362.0\\winrt'",
"/I'${workspaceFolder}\\AAA\\AAAA\\'",
"/I'${workspaceFolder}\\BBB\\'",
"/I'${workspaceFolder}\\'",
"/nologo",
"${workspaceFolder}\\CCC\\CCCC\\*.c",
"${workspaceFolder}\\DDD\\*.c",
"${workspaceFolder}\\EEE\\*.cpp",
"${workspaceFolder}\\*.cpp",
"${workspaceFolder}\\*.c",
"/Zi",
"/EHsc",
"/Fo:${workspaceFolder}\\build\\",
"/Fe:winFFF.exe",
"/link",
"/libpath:'E:\\ProgramFiles\\Microsoft Visual Studio\\2019\\BuildTools\\VC\\Tools\\MSVC\\14.25.28610\\lib\\x64'",
"/libpath:'C:\\Program Files (x86)\\Windows Kits\\10\\Lib\\10.0.18362.0\\ucrt\\x64'",
"/libpath:'C:\\Program Files (x86)\\Windows Kits\\10\\Lib\\10.0.18362.0\\um\\x64'"
],
"group": {
"kind": "build",
"isDefault": true
},
"presentation": {
"reveal": "always"
},
"problemMatcher": "$msCompile"
}
]
}
下面对该文件中的 "args"
进行详细解读:
"/I'includepath'"
为程序依赖的头文件存放路径,/I
即include。第一条路径为MSVC编译器的头文件路径,后四条路径为Windows 10包含的头文件路径。具体路径根据个人的系统和编译器而异。这五条路径为必备的包含路径;"/I'${workspaceFolder}\\AAA\\AAAA\\'"
等等为工程项目源代码所依赖的头文件的存放路径,其中${workspaceFolder}
为项目的工作路径根目录,AAA和AAAA为项目自定义的文件夹名,根据个人项目的具体情况设置。后面的BBB、CCC等类似;"/nologo"
表示取消显示版权标志在编译器启动时和在编译期间显示信息性消息;"${workspaceFolder}\\CCC\\CCCC\\*.c",
等等表示项目包含的需要编译的源代码文件(.c,.cpp);"/Zi"
选择为程序创建的调试信息的类型,此处将此信息保存在程序数据库(PDB)中;"/EHsc"
选择异常处理模型,此处为同步异常处理模型;"/Fo:${workspaceFolder}\\build\\",
设置创建的.object
文件的存放路径,此处为工作路径下的build文件夹;"/Fe:winFFF.exe"
设置生成的可执行文件.exe
的名称,此处为winFFF.exe
;"/link"
传输指定的参数给link,此处表示将后面的路径传递给连接器用于连接;"/libpath:'winlibpath'"
为 Window 10 的库文件存放路径,根据Windows环境而异。这三条路径为必备的库文件路径;
以一个最简单的一个hello world程序为例,源代码文件名为hello.cpp
,相应的 task.json
文件中的 "args"
如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
"args": [
"/I'D:\\Programs\\Microsoft Visual Studio\\2019\\Community\\VC\\Tools\\MSVC\\14.24.28314\\include'",
"/I'C:\\Program Files (x86)\\Windows Kits\\10\\Include\\10.0.18362.0\\shared'",
"/I'C:\\Program Files (x86)\\Windows Kits\\10\\Include\\10.0.18362.0\\ucrt'",
"/I'C:\\Program Files (x86)\\Windows Kits\\10\\Include\\10.0.18362.0\\um'",
"${workspaceFolder}\\hello.cpp",
"/Zi",
"/EHsc",
"/Fo:${workspaceFolder}\\hello.obj",
"/Fe:${workspaceFolder}\\hello.exe",
"/link",
"/libpath:'D:\\Programs\\Microsoft Visual Studio\\2019\\Community\\VC\\Tools\\MSVC\\14.24.28314\\lib\\x64'",
"/libpath:'C:\\Program Files (x86)\\Windows Kits\\10\\Lib\\10.0.18362.0\\ucrt\\x64'",
"/libpath:'C:\\Program Files (x86)\\Windows Kits\\10\\Lib\\10.0.18362.0\\um\\x64'"
],
其中,hello.cpp
也可以采用通配符的形式写为 *.cpp
,方便后续扩展。
3.2.3. 调试配置(launch.json)
点击 “调试” 图标菜单,选择 “添加配置” => “C++(Windows)” => “Default Configuration”,VSCode将自动创建 launch.json
文件,同样也可以手动创建该配置文件。
用以下内容替换该文件的全部默认内容。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{
"version": "0.2.0",
"configurations": [
{
"name": "MSVC: 运行",
"type": "cppvsdbg",
"request": "launch",
"program": "${workspaceFolder}/winFFF.exe",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": true
}
]
}
注意,program
字段中的可执行文件名,必须与前面 tasks.json
中 args
字段的 "/Fe:"
参数完全一致(此处均为 winFFF.exe
)。
至此,完成所有配置文件的生成。需要提醒的是,VSCode是基于工作路径进行编译调试的,若需要在其他文件夹(项目)中使用已有的配置时,只需要将当前的 .vscode
子文件夹复制到该项目的工作路径下,然后修改其中相应的参数项(如C/C++文件路径、可执行文件名称等)即可。
3.3. MingW-W64 生成配置文件
3.3.1. 语言配置(c_cpp_properties.json)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
"configurations": [
{
"name": "Win32",
"includePath": [
"${default}",
"${workspaceFolder}/**"
],
"defines": [
"_DEBUG",
"UNICODE",
"_UNICODE"
],
"windowsSdkVersion": "10.0.17763.0",
"compilerPath": "E:/ProgramFiles/mingw64/bin/g++.exe", // <--modified here
"cStandard": "c11",
"cppStandard": "c++17",
"intelliSenseMode": "windows-gcc-x64" // <--modified here
}
],
"version": 4
}
3.3.2. 编译配置(task.json)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
{
"version": "2.0.0",
"tasks": [
{
"type": "cppbuild",
"label": "C/C++: g++.exe build", // <-- user defined
"command": "g++.exe",
"args": [
"-fdiagnostics-color=always",
"-std=c++11",
"-g",
"${workspaceFolder}/3rdparty/json/*.c",
"${workspaceFolder}/3rdparty/sofa/*.c",
"${workspaceFolder}/src/*.cpp",
"${workspaceFolder}/src/basic/calc/*.cpp",
"${workspaceFolder}/src/basic/fcn/*.cpp",
"${workspaceFolder}/src/class/*.cpp",
"${workspaceFolder}/src/devices/sensors/*.cpp",
"${workspaceFolder}/src/devices/computers/*.cpp",
"${workspaceFolder}/src/devices/actuators/*.cpp",
"${workspaceFolder}/src/io/*.cpp",
"-I${workspaceFolder}/3rdparty/json", // <-- include header files here and after using "-Ixxxx"
"-I${workspaceFolder}/3rdparty/sofa",
"-I${workspaceFolder}/src",
"-I${workspaceFolder}/src/basic/calc",
"-I${workspaceFolder}/src/basic/config",
"-I${workspaceFolder}/src/basic/fcn",
"-I${workspaceFolder}/src/basic/struct",
"-I${workspaceFolder}/src/class",
"-I${workspaceFolder}/src/devices",
"-I${workspaceFolder}/src/devices/sensors",
"-I${workspaceFolder}/src/devices/computers",
"-I${workspaceFolder}/src/devices/actuators",
"-I${workspaceFolder}/src/io",
"-o",
"${workspaceFolder}/winDSS-gcc.exe",
"-lws2_32" // <-- link lib here and for windows socket
],
"options": {
"cwd": "${fileDirname}"
},
"problemMatcher": [
"$gcc"
],
"group": "build",
"detail": "编译器: g++.exe" // user defined
}
]
}
3.3.3. 调试配置(launch.json)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
{
"version": "0.2.0",
"configurations": [
{
"name": "GCC:调试运行",
"type": "cppvsdbg",
"request": "launch",
"program": "${workspaceFolder}/winDSS-gcc.exe",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": true,
"preLaunchTask": "C/C++: g++.exe build" //在启动调试之前默认先编译,以便生成目标程序
},
{ // used for python, can be deleted
"name": "Python: 当前文件",
"type": "python",
"request": "launch",
"program": "${file}",
"console": "integratedTerminal"
}
]
}
3.4. 编译调试运行
打开前面编写的 hello.cpp
,同时按下快捷键 Ctrl + Shift + B
。VSCode会启动生成任务并在终端中显示其生成过程。生成完毕后,按 F5
进行调试运行,可在终端中查看运行结果。
至此,我们完成了全部的C/C++开发环境部署。官方同样给出了详细的基于MSVC编译器的开发环境部署方法,见参考文献[1]。
3.5. 快捷键
Ctrl + Shift + N
新建一个 VSCode 窗体
Alt + left/right
回到上/下一个光标停留的位置
Ctrl + Shift + P
调出执行命令的输入面板
Ctrl + ,
调出设置面板
Ctrl + K, Ctrl + 0
折叠所有代码块
Ctrl +K, Ctrl + J
展开所有代码块
4. 参考文献
[1] Micsosoft. Configure VS Code for Microsoft C++.