Visual Studio Code官网文档 https://code.visualstudio.com/docs/cpp/config-wsl
官网文档还有编译Python、Java的文档,包括win、linux、macos,写得很通俗,建议去看,flag:过四级的看不懂我倒立吃屏幕。
徒手翻译原文,翻译人是直译翻译者的死对头,多处使用意译翻译。
文档的很多内容可能用不到,结尾有总结,不想看翻译的请滚到最后看配置项及说明。
官网文档翻译
在WSL上用VS code写C++
在这个教程中,你会在Windows Subsystem for Linux(WSL)的Ubuntu系统上配置VS code,来使用GCC编译工具和GDB调试工具。GCC代表GNU编译器集合;GDB是GNU的调试器。WSL是Windows系统上的Linux子系统,它直接在真机上运行,而不是虚拟机。
注:教程的大部分内容可以直接在Linux设备上使用VS code做C++相关的工作。
VS code支持在WSL内直接用Remote-WSL扩展进行工作。我们推荐使用WSL开发模式,所有源码文件还有编译器都由Linux发行版管理。更多信息详见VS Code Remote Development。
这个向导完成后,你将有能力创建并配置你的C++工程,并可以探索VS code的文档,获取更多关于它的特性的信息。此向导不会教你GCC、Linux或C++语言,关于这些问题的资源可以从网上获得很多。
如果你有任何问题,请放心地在VS Code documentation repository为此教程提问。
前提条件
为了成功地完成此向导,你必须做下面几项工作:
- 安装VS code
- 安装Remote - WSL extension
- 安装Windows Subsystem for Linux,然后在页面链接上安装你选择的Linux发行版本。此教程使用Ubuntu。安装时务必记住你的Linux用户密码,因为在安装其他软件时需要它。
设置你的Linux环境
- 打开WSL的Bash终端。如果你安装了一个Ubuntu发行版,在Windows搜索栏搜索“Ubuntu”然后在结果列表中点击它。对于Debian发行版,搜索“Debian”一样。
终端会显示命令提示符,默认由你的用户名和电脑名组成,并将你至于用户的家目录下。在Ubuntu上看起来像这样:
- 创建一个目录
projects
,然后在其中创建子目录helloworld
:
mkdir projects
cd projects
mkdir helloworld
-
你将会在Linux系统用VS code编辑源代码,也会用g++编译器编译代码。同时,你也会在Linux中用GDB进行调试。这些工具在Ubuntu中默认不安装,所以你要亲自安装它们。幸运的是,这些工作很简单!
-
在WSL的命令提示符中,先运行
apt-get update
来更新Ubuntu的包列表。过时的版本有时会干扰新软件包的安装。
sudo apt-get update
你也可以执行sudo apt-get update && sudo apt-get dist-upgrade
指令,下载最新版本的系统包,但是这会因为网络连接速度的约束而花费更多时间。
- 在命令行中安装GNU编译工具和GDB调试工具,命令如下:
sudo apt-get install build-essential gdb
- 通过定位g++和gdb来核实安装是否成功。如果文件名没有在
whereis
命令中返回,试试再次运行更新命令。
whereis g++
whereis gdb
注:安装g++编译器和GDB调试器的步骤在Linux设备上进行而不是WSL。你要在你的helloworld工程中运行VS code,以及编辑、编译和调试。
在WSL中运行VS code
在WSL的终端里切换到你的helloworld工程目录,用code .
打开VS code:
cd $HOME/projects/helloworld
code .
你会看到一条“安装VScode Server”的消息。这时VS code正在给Linux端下载并安装一个小服务器,桌面上的VS code会和它建立联系。随后VS code会启动并打开helloworld
目录。文件管理器在标题栏显示[WSL:Ubuntu],代表VS code正在WSL中运行。
你也可以在状态栏看到远程环境
如果点击远程状态栏,你会看到远程命令会话的列表。比如,你想结束WSL上的会话,你就可以在列表中选择 关闭远端连接 命令。在WSL命令提示符中执行 code .
命令会重新启动VS code。
code . 命令会在当前目录打开VS code,这个目录就是你的“工作空间”。随着教程的进行,你将看到在工作目录的.vscode
目录中会创建三个文件:
c_cpp_properties.json
(编译路径和智能配置)tasks.json
(编译说明)launch.json
(调试设置)
添加源代码文件
在文件管理标题栏上选择 新文件 按钮,创建一个 helloworld.cpp
文件。
安装C/C++扩展
创建文件后,VS code会识别出它是个C++语言的文件,如你没有安装Microsoft C/C++ extension,它会提示你进行安装。
扩展窗口显示操作按钮,选择安装,然后重新加载,完成C/C++扩展的安装。
如果你已经在VS code中本地安装了C/C++语言的扩展,你要在扩展扩展窗口(Ctrl+Shift+X)中把那些扩展安装到WSL中。选择 安装到WSL 按钮并 重新加载 ,本地安装的扩展就会安装到WSL上。
添加helloworld源代码
粘贴这段代码
#include <iostream>
#include <vector>
#include <string>
using namespace std;
int main()
{
vector<string> msg {"Hello", "C++", "World", "from", "VS Code", "and the C++ extension!"};
for (const string& word : msg)
{
cout << word << " ";
}
cout << endl;
}
按Ctrl+S保存文件。在VS code侧边栏的 文件管理 窗口(Ctrl+Shift+E)中,注意你刚添加的文件是怎样显示的。
你也可以打开自动保存功能,自动保存文件的改动,在 文件 主菜单中点击 自动保存 。
你可以在最左侧的活动栏打开不同窗口,比如 搜索 、 源代码管理 和 运行 。在这个教程的后面你会看到 运行 窗口。你可以在VS code用户接口文档找到更多关于其他窗口的信息。
智能提示
在新建的 helloworld.cpp
文件中,把鼠标停在 vector
或者 string
上可以看到类型信息。声明 msg
变量后,你想调用它的成员函数就要以 msg.
开头。之后你会看到一个完整的列表显示所有成员函数,旁边还有一个窗口显示 msg
对象的类型信息。
你可以按 Tab
键插入选择的成员函数;之后,当写上左括号时,你会看到该函数所有参数的信息。
编译helloworld.cpp
接下来,你要创建 tasks.json
文件,告诉VS code怎样编译程序。这个工作会借助WSL的g++编译器创建一个源代码的可执行文件。
在主菜单栏选择 终端 > 配置默认生成任务 ,出现一个下拉列表,展示了各种预定义的C++编译器。选择 g++ build active file ,这个选项会创建一个在编辑器中立刻显示。
这个步骤会在.vscode
目录中创建一个tasks.json
文件,并在编辑器中打开它。
新创建的 tasks.json
文件应该像JSON格式,比如下面这样:
{
"version": "2.0.0",
"tasks": [
{
"type": "shell",
"label": "g++ build active file",
"command": "/usr/bin/g++",
"args": ["-g", "${file}", "-o", "${fileDirname}/${fileBasenameNoExtension}"],
"options": {
"cwd": "/usr/bin"
},
"problemMatcher": ["$gcc"],
"group": {
"kind": "build",
"isDefault": true
}
}
]
}
command
选项指明要运行的程序,这个例子中时g++。 args
数组指明要传给g++的命令行参数,这些参数的顺序必须符合编译器要求。这项工作是调用g++编译目标文件(${file}
),并在当前目录(${fileDirname}
)创建一个没有文件后缀的、与目标文件同名的可执行文件,此教程中的例子创建helloworld
文件。
注:你可以在变量参考了解更多关于
tasks.json
的变量内容。
label
选项的值会在任务列表中显示,你可以任性地修改它。
group
对象中的"isDefault":true
内容代表按Ctrl+Shift+B快捷键开始工作。这项配置只是为了方便;如果你把它设为false,你仍然可以在终端菜单中用运行生成任务来运行。
运行编译
-
返回
helloworld.cpp
。你将编译helloworld.cpp
。 -
按
Ctrl+Shift+B
或者在终端主菜单中选择运行生成任务,运行定义在tasks.json
文件的编译任务。 -
任务开始时,源代码编辑框下面会出现终端面板。编译完成后,终端会输出编译是否成功的相关信息。编译成功的样子像这样:
- 点击+按钮创建新终端,这个终端运行在WSL环境中,以
helloworld
文件的目录为工作目录。执行ls
命令可以看到可执行文件helloworld
(没有文件后缀)。
- 在终端输入
./helloworld
运行helloworld
。
修改tasks.json
你可以tasks.json
来比编译更多C++文件,比如用".cpp"
代替${file}
。你也可以将${fileDirname}/${fileBasenameNoExtension}
换成一个固定的名字来修改输出的文件名(比如改成“helloworld.out”)。
调试helloworld.cpp
接下来,你要创建一个launch.json
文件来配置VS code,让它在你按F5
时调用GDB调试程序。在主菜单选择运行 > 添加配置… 然后选择 C++(GDB/LLDB)。
出现一个列表显示各种预定义的调试配置。选择g++ build and debug active file。
VS code创建一个launch.json
文件并在编辑器中打开,然后编译运行“helloworld”。
{
"version": "0.2.0",
"configurations": [
{
"name": "g++ build and debug active file",
"type": "cppdbg",
"request": "launch",
"program": "${fileDirname}/${fileBasenameNoExtension}",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
],
"preLaunchTask": "g++ build active file",
"miDebuggerPath": "/usr/bin/gdb"
}
]
}
program
选项指定要调试的程序。这里设置的目标文件目录${fileDirname}
和无扩展名的目标文件${fileBasenameNoExtion}
对应helloworld.cpp
生成的目标文件helloworld
。
这里默认,C++扩展不会源代码中添加任何断点,stopAtEntry
的值为false
。将stopAtEntry
设为true
会在开始调试时停在main
函数位置。
剩下的步骤时可选联系,可以帮助你熟悉编辑和调试。
开始调试会话
-
返回
helloworld.cpp
,这是目前的目标文件。 -
按
F5
或主菜单选择运行 > 启动调试。在单步调试之前,我们用一分钟来了解一下用户界面的改变:
- 代码编辑框下面出现终端。在调试控制台标签中,你可以看到调试器开始运行的输出信息。
- 编辑器在
main
函数的第一行高亮显示。这是C++默认为你设置的断点:
- 左侧运行窗口显示调试信息。在此向导的后面有例子。
- 在编辑器顶部出现一个调试控制面板。你可以抓着左侧的几个点移动它。
单步调试代码
现在你可以准备开始单步调试代码了。
- 在调试控制面板上点击Step over图表。
这会让程序执行到循环的第一行,并在创建和初始化msg
变量时跳过vector
和string
类的所有内部函数。注意左侧变量窗口的变化。
这个例子中,理应会出现问题,虽然变量名对循环来说是可见的,但是还没有执行到,所以这一步没有内容可以读。msg
变量可以看到,因为那条语句已经完成了。
-
再次按Step over让程序执行到下一个声明(跳过所有初始化循环的内部代码)。现在,变量窗口会展示循环中的变量信息。
-
再按Step over执行到
cout
语句。(注意,在2019年3月发行的VS code中,C++扩展在循环结束前不会在调试控制台输出任何信息。) -
你可以一直按Step over直到向量中的所有单词都打印出来。如果你对Step Into按钮很好奇,可以点击它试一试,这会跳到C++标准库代码的内部!
要想回到你的代码,一个方法是一直按Step over;另一个方法是切换到helloworld.cpp
中,在程序循环内的cout
语句处按F9
添加断点。在左侧空白位置出现一个红点表明断点已添加到这一行。
然后按F5
在标准库中开始执行,程序会停在cout
语句的位置。以可以再次按F9
取消断点。
循环结束后,在调试控制台可以看到输出信息,同时还有GDB的其他调试信息。
设置监视器
有时,你可能想在程序执行时跟踪变量的值。你可以为变量设置监听实现这一功能。
- 把光标聚焦在循环中,在监视窗口点击添加表达式然后输入循环的变量
word
。接下来,在调试时看着监视窗口。
-
在循环前加
int i = 0;
语句,在循环中添加++i
语句,同上一步添加i
变量的监视。 -
执行到断点时,如果想快速看到任何变量的值,你可以把鼠标停在它上面。
C/C++配置
如果你想对C/C++扩展进行更多控制,你可以创建一个c_cpp_properties.json
文件,在其中可以配置很多设置,比如编译器路径、头文件包含路径和C++标准(默认C++17)等等。
你可以在命令面板(Ctrl+Shift+P
)运行C/C++: Edit Configurations (UI)命令打开C/C++用户界面配置。
这会打开C/C++配置页面。当你在其中进行修改时,VS code会把修改内容写到.vscode
目录的c_cpp_properties.json
文件中。
如果你的程序的头文件不再工作目录或标准库的头文件中,你只修改Include path就够了。
VS code会将这些设置放到.vscode/c_cpp_properties.json
文件中,如果直接打开它,它看起来像这样:
{
"configurations": [
{
"name": "Linux",
"includePath": ["${workspaceFolder}/**"],
"defines": [],
"compilerPath": "/usr/bin/gcc",
"cStandard": "c11",
"cppStandard": "c++17",
"intelliSenseMode": "clang-x64"
}
],
"version": 4
}
关闭WSL会话
当你在WSL上完成工作后,你可以在主文件菜单和命令面板(Ctrl+Shift+P
)执行关闭远程连接命令退出会话。这会重新启动运行在本地的VS code。你可以在文件 > 最近打开列表中选择带**[ WSL] **后缀的文件,重新打开WSL会话。
其他步骤
- 探索VS code用户导航。
- 回顾C++扩展概述。
- 创加一个新的工作空间,把你的.json文件复制到其中,为新的工作空间调整需要的设置,程序名等等,然后开始敲代码!
配置总结
文档讲的是在WSL上的ubuntu系统,不影响直接在ubuntu系统中进行配置。打开一个目录作为工作空间,设置时会在.vscode目录下创建两个文件tasks.json和launch.json。可以直接手动创建目录和文件,不用在VS code中设置。
- 创建
tasks.json
文件,用于编译。菜单栏选择 终端 > 配置默认生成任务 ,出现一个下拉列表,展示了各种预定义的C++编译器。选择 g++ build active file。参考如下:
{
"version": "2.0.0",
"tasks": [
{
"type": "shell",
"label": "g++ go!go!go!",
"command": "/usr/bin/g++",
"args": [
"-g",
"${file}",
"-o",
"${fileDirname}/${fileBasenameNoExtension}"
],
"options": {
"cwd": "/usr/bin"
},
"problemMatcher": [
"$gcc"
],
"group": {
"kind": "build",
"isDefault": true
}
}
]
}
command指明g++。args数组g++参数。当前文件目录${fileDirname}
。无文件后缀的、与源文件同名的可执行文件${fileBasenameNoExtension}
。label随便改。
isDefault:true代表按Ctrl+Shift+B快捷键开始工作。详细内容参考Variables Reference。
- 创建
launch.json
文件,用于运行调试。主菜单选择运行(调试) > 添加配置… 然后选择 C++(GDB/LLDB)。选g++ build and debug active file。launch.json参考:
{
// 使用 IntelliSense 了解相关属性。
// 悬停以查看现有属性的描述。
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "come on!",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/${fileBasenameNoExtension}",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"setupCommands": [
{
"description": "为 gdb 启用整齐打印",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
]
}
]
}
program选项指定要调试的程序。
之后就能编译、调试了。调试前记得先编译源文件。