什么是 VScode Visual Studio Code(VScode) 是一个轻量级但功能强大的源代码编辑器,可在桌面上运行,并且可用于Windows,macOS和Linux。VS code 包括一整套系统:比如内部支持 JavaScript,TypeScript 和 Node.js,能够进行多种语言扩展(如 C++,C#,Java,Python,PHP,Go),也能够进行多种运行扩展(如.NET 和 Unity)。
简单的说就是 notepad+compiler+extensions。
VScode 特点 【VScode 使用初步】之前我也没有用过 VScode,一直用的都是 VS,Qt 这样的工具,但是真的用上 VScode 之后,就发现其实如果了解一下 VScode 的使用方式的话,这个工具使用起来还是比较简单的。主要的特点有:
- 跨平台。VScode 能够运行在 macOS,Linux,Windows操作系统上
- 轻便灵活。VScode 在最初安装只包含了开发流程共享的基本组件,只实现了包括编辑器,文件管理,窗口管理,首选项设置, JavaScript/TypeScript 语言服务和 Node.js 调试器等基本功能,此时的 VScode 就是一个代码编辑器
- 可扩展。VS Code 扩展可以添加对以下内容的支持:
- 语言:C++,C#,Go,Java,Python
- 工具:ESLint,JSHint,PowerShell
- 调试器:Chrome,PHP XDebug。
- 键盘映射:Vim,Sublime Text,IntelliJ,Emacs,Atom,Visual Studio,Eclipse
前提条件
- GCC
- GDB
- VScode
VScode 不同于 VS,Qt 可以直接新建工程,在 VScode 中需要自己手动建立工程目录。其实就是新建一个文件夹,也不需要在文件夹中包含类似 CMakeLists.txt 的文件,因为这样的文件会在之后自动生成。
然后打开 VScode,利用菜单栏中的 File 打开刚刚新建的新文件夹,该文件夹就是工程目录。
代码编辑
此时先写一个简单的 hello world 程序:
// main.cpp
#include using namespace std;
int main()
{
cout<<"Hello world!"<
.vscode
默认情况下,在工程目录中会自动生成隐藏目录 .vscode,该文件中主要包含三个文件:
- task.json(编译器构建设置)
- launch.json(调试器设置)
- c_cpp_properties.json(编译器路径和IntelliSense设置)
从这里来看,该隐藏文件夹有点像是 Qt 中的 .pro 文件。
task.json
既然代码已经写完了,接下来就是 build task 了。
在主菜单中,选择 Terminal > Configure Default Build Task。出现一个下拉列表,显示用于C++编译器的各种预定义构建任务。选择C/C++: g++ build active file。
这将在 .vscode 文件夹中创建 tasks.json 文件,并在编辑器中将其打开。tasks.json 文件应类似于以下 JSON:
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"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
}
}
]
}
此时可以看到隐藏文件目录 .vscode 自动被创建。上边的参数有:
- Command: 指定要运行的程序,在这种情况下是 g++
- Args: 指定将传递给 g++ 的命令行参数。参数必须按照编译器期望的顺序指定
- Label: 就是在任务列表中看到的值,可以随意命名
- Group: "isDefault": true指定当按Ctrl+Shift+B时将运行此任务。此属性仅仅是为了便利性,如果将其设置为false,仍然可以通过terminal菜单中的Tasks: Run Build Task运行
运行程序
- 返回 main.cpp,任务将构建活动文件。
- 要运行 tasks.json 中定义的构建任务,按 Ctrl+Shift+B 或从 terminal 菜单中选择 Run Build Task。
- 任务启动时,会看到集成终端面板出现在源代码编辑器下方。任务完成后,终端将显示编译器的输出,指示构建成功还是失败。
- 使用 + 按钮创建一个新终端,这将在 WSL 上下文中运行一个 bash 终端,并以当前文件夹作为工作目录。
- 此时可以在终端运行 main。
此时只是构建了任务,生成了可执行程序,但是想要调试的话还需要用到 launch.json 来设置调试器的相关内容。
- 在菜单栏中选择 Run > Add Configuration...,然后选择 C++ (GDB/LLDB)
- 然后将出现各种预定义调试配置的下拉列表。选择 g++ build and debug active file
- VS Code 创建 launch.json 文件,在编辑器中打开为:
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"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}和没有扩展名的活动文件名${fileBasenameNoExtension},如果helloworld.cpp是活动文件,则为helloworld
- 默认情况下,C++扩展不会在源代码中添加任何断点,因此stopAtEntry值设置为false。stopAtEntry值为true时,调试器启动调试时遇到main方法停止
- 返回 main.cpp,使其成为活动文件
- 按 F5 或从主菜单中选择 Run > Start Debugging。此时用户界面会发生一些更改:
- 集成终端出现在源代码编辑器的底部。在 Debug Output 选项卡中,可以看到指示调试器已启动并正在运行
- 编辑器突出显示main方法中的第一条语句。这是 C++ 扩展自动设置的断点
- 左侧的 run 视图显示调试信息
- 在代码编辑器的顶部,将显示一个调试控制面板
WATCH
在调试的时候,左侧边栏会出现一个 WATCH 的栏目,利用 WATCH 可以实现对变量跟踪:
- 在 WATCH 窗口中,单击加号,然后在文本框中键入 var(变量名),此时可以逐步调试程序,可以看出该变量一直显示在 WATCH
- 在断点开启时,要快速查看任何变量的值,可以使用鼠标指针悬停在其上
编程中通常会使用到一些第三方库,如果要用到第三方库的头文件的话,就需要在该文件中添加头文件目录,不过此时添加的头文件目录只是为了编程更加方法,实现智能感知,而并没有真正的链接。
真正的链接需要在 task.json 文件中设置参数,才能够正常编译。
可以通过从 Command Palette (Ctrl+Shift+P) 运行命令 C/C++: Edit Configurations (UI) 来查看 C/C++ 配置 UI。
- 当在此处进行更改时,VS Code会将更改写入.vscode文件夹中的c_cpp_properties.json文件中。
- 仅当程序包含不在工作空间或标准库路径中的头文件时,才需要修改includepath设置。
当需要进行外部库链接时,至少需要在 tasks.json 中进行头文件包含和外部库链接,如果需要使用代码提示等智能感知功能的话,还需要修改 c_cpp_properties.json 文件。
以下用一个 C 语言的实例来简单说明需要进行外部库链接的情况(这里的静态库是利用这篇文章中的文件生成的):
// main.c
#include
#include int main()
{
printf("insert a node from tail\n");
ND *head = createListTail();
//printf("insert a node from head\n");
//ND *head = createListHead();
printf("traval all node using next\n");
travalListNext(head);
printf("insert a node\n");
insertList(head,10);
travalListNext(head);
//printf("traval all node using pre\n");
//travalListPre(head);
printf("calculate the length of list\n");
int length = lenList(head);
printf("The length of list is %d\n",length);
printf("search a node in list from single direction\n");
ND *pp = searchNodeSdir(head,10);
printf("The search node is %d\n",pp->data);
//printf("search a node in list from both direction\n");
//pp = searchNodeBdir(head,10);
//printf("The search node is %d\n",pp->data);
printf("delete a node\n");
deleteNode(pp);
travalListNext(head);
printf("sort list by swap data\n");
sortSwapData(head,9);
travalListNext(head);
//printf("sort list by swap pointer\n");
//sortSwapPointer(head,9);
//travalListNext(head);
printf("destroy list\n");
destroyList(head);
}
// tasks.json
{
"version": "2.0.0",
"tasks": [
{
"type": "shell",
"label": "gcc build active file",
"command": "/usr/bin/gcc",
"args": [
"-g",
"${file}",
"-I",
"~/libr",
"-L",
"~/libr",
"-l",
"node",
"-o",
"${fileDirname}/${fileBasenameNoExtension}"
],
"options": {
"cwd": "/usr/bin"
},
"problemMatcher": [
"$gcc"
],
"group": {
"kind": "build",
"isDefault": true
}
}
]
}
// launch.json
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "gcc - 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": "gcc build active file",
"miDebuggerPath": "/usr/bin/gdb"
}
]
}
// c_cpp_properties.json
{
"configurations": [
{
"name": "Linux",
"includePath": [
"${workspaceFolder}/**",
"~/libr/**"
],
"defines": [],
"compilerPath": "/usr/bin/gcc",
"cStandard": "c11",
"cppStandard": "c++17",
"intelliSenseMode": "clang-x64"
}
],
"version": 4
}
- 该工程需要的编译器是 gcc,而不是 g++
- 如果在 c_cpp_properties.json 文件中没有为 includePath 参数添加头文件,则在 main.c 文件中的 #include
会出现下划线,也就是说编辑器找不到该函数,但是实际是能够编译的。 - 在 tasks.json 文件中添加了一些参数,如 -I,-L,-l 等,这些参数包含了头文件和外部链接库。
- 不需要调试的话,可以不用添加 launch.json 文件
因此,运行任务时一定要保证当前活动文件为包含 main 函数的文件。