3962 words
20 minutes
Visual Studio Code配置指南

前言#

本文将手把手教你如何在Windows上配置Visual Studio Code(以下简称VS Code)并将其用于编写、调试运行单文件C/C++程序,如果你的操作系统环境是Linux或Mac OS,请阅读官方文档进行配置。

安装Visual Studio Code#

官网根据你的操作系统下载Visual Studio Code,如果你是Windows 7系统,在这里下载最后一个支持Windows 7的版本。

打开刚才下载的安装包,保持默认选项一路点确定即可:

这里可以将选项全部勾选:

安装完成后打开VS Code,点击左侧栏拓展按钮,搜索“Chinese”下载中文语言包,等待下载完成后点击弹出来的重启按钮,之后VS Code的语言将会变更为中文。

安装MinGW-W64#

事实上,VS Code是一个编辑器而非IDE,只有编辑器是无法像Visual Studio、CLion等IDE一样编译C/C++代码的,因此我们需要安装一个编译器。在Windows上我们推荐安装MinGW-W64(注意是MinGW-W64不是MinGW)作为编译器。MinGW是GNU工具(包括编译器GCC、GNU binutils和调试器GDB等)在Windows上的一个移植,但是它仅支持32位,而MinGW-W64是MinGW的一个分支,它提供了64位支持1

MinGW-W64有多个发行版本如mingw-builds、MSYS2、LLVM-MinGW等,这里我们选择mingw-builds。在GitHub上选择一个版本下载,本文选择x86_64-14.2.0-release-posix-seh-ucrt-rt_v12-rev0.7z作为安装版本,如果你的网络环境无法正常从GitHub上下载 ,也可以到山东大学镜像站下载。

下载完后得到一个拓展名为.7z的压缩包,解压后得到的就是MinGW-W64本体,把它放在一个你能找到的位置比如C盘根目录下面(不管放到哪里,路径不要含有中文防止出现奇怪的错误)。

接下来将它添加到Path,右键“此电脑”——属性——高级系统设置——环境变量:

选择系统变量下的Path一栏点击:编辑——新建,将刚才解压得到的MinGW文件夹里的bin文件夹路径写进去(如:C:\mingw64\bin)保存后MinGW就被添加到了Path里面。

保存更改之后打开Windows终端(或者你也可以在VS Code里点击终端——新建终端)输入:

gcc -v

回车后你将会看见关于MinGW-W64的版本信息,如果提示“‘gcc’不是内部或外部命令,也不是可运行的程序或批处理文件。”可尝试重启电脑,若仍出现该消息,说明没有成功添加到Path,请检查是否出现了拼写错误或路径错误。

配置Visual Studio Code#

首先,我们下载C/C++插件提供C/C++语言的代码补全、高亮、格式化、调试等功能。在拓展应用商店界面搜索C/C++并下载。

为了便于使用,我们通常会在一个文件夹内编写代码,你可以选择一个没有中文的路径新建一个文件夹用于编写代码,在VS Code内点击左上角的:文件——打开文件夹,选择你用于编写代码的文件夹,接下来在其中新建一个.vscode文件夹,在.vscode文件夹下新建tasks.json和launch.json两个文件。

接下来我们来对编译调与试功能进行配置。在tasks.json中粘贴如下内容:

{
    "tasks": [
        {
            "type": "cppbuild",
            "label": "g++ build and debug", // 编译C++的task,供launch.json使用
            "command": "C:/mingw64/bin/x86_64-w64-mingw32-g++", // 这里写存放mingw的路径
            "args": [ // 下面是编译参数
                "-fdiagnostics-color=always", // 强制编译器在输出错误和警告信息时使用颜色,便于阅读
                "-g", // 生成调试信息
                "-Wall", // 启用所有警告
                "-std=c++20", // 使用C++20作为标准进行编译
                "-lm", // 链接到数学库
                "${file}",
                "-o",
                "${fileDirname}\\${fileBasenameNoExtension}.exe"
            ],
            "options": {
                "cwd": "C:/mingw64/bin" // 这里写存放mingw的路径
            },
            "problemMatcher": [
                "$gcc"
            ],
            "group": {
                "kind": "build",
                "isDefault": true
            },
            "presentation": {
                "echo": true,
                "reveal": "always",
                "focus": true,
                "panel": "new"
            },
            "detail": "调试器生成的任务。"
        },
        {
            "type": "cppbuild",
            "label": "gcc build and debug", // 编译C的task,供launch.json使用
            "command": "C:/mingw64/bin/x86_64-w64-mingw32-gcc", // 这里写存放mingw的路径
            "args": [
                "-fdiagnostics-color=always", // 强制编译器在输出错误和警告信息时使用颜色,便于阅读
                "-g", // 生成调试信息
                "-Wall", // 启用所有警告
                "-std=c17", // 使用C17作为标准进行编译
                "-lm", // 链接到数学库
                "${file}",
                "-o",
                "${fileDirname}\\${fileBasenameNoExtension}.exe"
            ],
            "options": {
                "cwd": "C:/mingw64/bin" // 这里写存放mingw的路径
            },
            "problemMatcher": [
                "$gcc"
            ],
            "group": {
                "kind": "build",
                "isDefault": true
            },
            "detail": "调试器生成的任务。"
        }
    ],
    "version": "2.0.0"
}

在launch.json中粘贴如下内容:

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "g++", // 你可以自定义这个名字
            "type": "cppdbg",
            "request": "launch",
            "program": "${fileDirname}/${fileBasenameNoExtension}.exe",
            "args": [], // 要传递给程序的命令行参数,此处为空
            "stopAtEntry": false, // 设置为true会在程序入口处停止
            "cwd": "${fileDirname}",
            "environment": [], // 可以在这里定义环境变量,此处为空
            "externalConsole": false, // 设置为true会使用外部终端来运行程序,而不是VSCode内部终端
            "MIMode": "gdb",
            "miDebuggerPath": "C:\\mingw64\\bin\\gdb.exe", // 这里写存放mingw的路径
            "setupCommands": [
                {
                    "description": "为 gdb 启用整齐打印",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                },
                {
                    "description": "将反汇编风格设置为 Intel",
                    "text": "-gdb-set disassembly-flavor intel",
                    "ignoreFailures": true
                }
            ],
            "preLaunchTask": "g++ build and debug" // 在启动调试之前要执行的编译任务,要与tasks.json里的label对应
        },
        {
            "name": "gcc",
            "type": "cppdbg",
            "request": "launch",
            "program": "${fileDirname}/${fileBasenameNoExtension}.exe",
            "args": [],
            "stopAtEntry": false,
            "cwd": "${fileDirname}",
            "environment": [],
            "externalConsole": false,
            "MIMode": "gdb",
            "miDebuggerPath": "C:\\mingw64\\bin\\gdb.exe",
            "setupCommands": [
                {
                    "description": "为 gdb 启用整齐打印",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                },
                {
                    "description": "将反汇编风格设置为 Intel",
                    "text": "-gdb-set disassembly-flavor intel",
                    "ignoreFailures": true
                }
            ],
            "preLaunchTask": "gcc build and debug"
        }
    ]
}

现在我们可以一键编译、运行和调试C/C++代码了,打开C/C++文件,点击左侧栏的运行和调试按钮,我们可以选择g++或gcc两个配置选项。对于C++我们选择g++,对于C我们选择gcc,点击绿色三角即可开始编译调试,你也可以通过键盘快捷键F5进行调试或者Ctrl+F5以非调试模式运行(此时断点不生效)。实际上tasks.json和launch.json有更多的配置选项,具体可以到官方文档内查看。

WARNING

请务必选择正确的配置选项运行,否则将出现编译器报错。

如果终端提示

无法生成和调试,因为活动文件不是 C 或 C++ 源文件。

 *  终端进程启动失败(退出代码: -1)。 
 *  终端将被任务重用,按任意键关闭。

并弹出报错窗口,说明你尝试编译运行的不是C/C++文件,请确保当前选中的标签页是C/C++文件。

C/C++插件的可供选择的功能十分丰富,具体可以点击左下角齿轮——设置——搜索“C_Cpp”筛选出设置选项,你也可以对VS Code的其他设置选项进行自定义。

使用clangd作为语言服务器#

LSP即Language Server Protocol,是由微软推出的编辑器或IDE与语言服务器之间使用的协议,语言服务器提供自动补全、转到定义、查找所有引用等语言功能,同时具有较小的性能开销。如果你觉得C/C++插件不够好用,我们推荐使用clangd作为C/C++的语言服务器以提供上述的功能,事实上CLion使用的语言服务器之一就是clangd。

拓展商店里搜索“clangd”并下载,下载完后会弹出窗口询问是否要禁用C/C++插件的IntelliSense,因为我们的目的就是使用clangd提供IntelliSense等功能,点击Disable IntelliSense。

clangd插件仅提供了一个前端,现在需要我们安装clangd后端。按F1呼出VS Code的命令窗口,输入“clangd”,选择“clangd: Download language server”,clangd插件会开始下载clangd后端。

如果出现网络问题下载失败可以尝试在GitHub上下载Windows平台的clangd,下载并解压后将其中的bin文件夹内的clangd.exe路径填写到clangd插件设置的Path项中。

安装完clangd后可以对clangd进行一些设置,在设置界面点击右上角“打开设置(json)”打开VS Code的json配置文件,将以下内容粘贴进去(仅粘贴clangd部分的设置到大括号内即可):

{
    "workbench.colorTheme": "Default Dark+",
    "C_Cpp.intelliSenseEngine": "disabled",
    "clangd.arguments": [
        "--clang-tidy", // 启用Clang-tidy进行代码分析和修复建议
        "--all-scopes-completion", // 开启全局范围内的代码补全,提供更全面的建议
        "--header-insertion=never", // 禁止自动添加头文件
        "--pch-storage=memory", // 使用内存存储预编译头文件,以提高速度
        "--log=error", // 日志级别设置为error
        "--j=5", // 设置同时处理的任务数量
        "--background-index", // 启用后台索引以提升代码导航性能
        "--compile-commands-dir=.vscode" // 指定compile_commands.json的目录
    ],
    "clangd.fallbackFlags": [ // 若没有compile_commands.json时的设置
        "--target=x86_64-w64-mingw" 
    ],
    "editor.defaultFormatter": "llvm-vs-code-extensions.vscode-clangd", // 使用clangd作为格式化工具
}

clangd同时也可以格式化你的代码,这只需要在项目文件夹的根目录下新建一个.clang-format文件即可,我们给出一个参考:

# 语言: None, Cpp, Java, JavaScript, ObjC, Proto, TableGen, TextProto
Language: Cpp

# 基于LLVM的风格
BasedOnStyle: LLVM

# 访问说明符(public、private等)的偏移
AccessModifierOffset: -4

# 开括号(开圆括号、开尖括号、开方括号)后的对齐: Align, DontAlign, AlwaysBreak(总是在开括号后换行)
AlignAfterOpenBracket: Align

# 连续赋值时,对齐所有等号
AlignConsecutiveAssignments: false

# 连续声明时,对齐所有声明的变量名
AlignConsecutiveDeclarations: false

# 右对齐逃脱换行(使用反斜杠换行)的反斜杠
AlignEscapedNewlines: Right

# 水平对齐二元和三元表达式的操作数
AlignOperands: true

# 对齐连续的尾随的注释
AlignTrailingComments: true

# 不允许函数声明的所有参数在放在下一行
AllowAllParametersOfDeclarationOnNextLine: false

# 不允许短的块放在同一行
AllowShortBlocksOnASingleLine: true

# 允许短的case标签放在同一行
AllowShortCaseLabelsOnASingleLine: true

# 允许短的函数放在同一行: None, InlineOnly(定义在类中), Empty(空函数), Inline(定义在类中,空函数), All
AllowShortFunctionsOnASingleLine: None

# 允许短的if语句保持在同一行
AllowShortIfStatementsOnASingleLine: false

# 允许短的循环保持在同一行
AllowShortLoopsOnASingleLine: false

# 总是在返回类型后换行: None, All, TopLevel(顶级函数,不包括在类中的函数), 
# AllDefinitions(所有的定义,不包括声明), TopLevelDefinitions(所有的顶级函数的定义)
AlwaysBreakAfterReturnType: None

# 总是在多行string字面量前换行
AlwaysBreakBeforeMultilineStrings: false

# 总是在template声明后换行
AlwaysBreakTemplateDeclarations: true

# false表示函数实参要么都在同一行,要么都各自一行
BinPackArguments: true

# false表示所有形参要么都在同一行,要么都各自一行
BinPackParameters: true

# 大括号换行,只有当BreakBeforeBraces设置为Custom时才有效
BraceWrapping:
  # class定义后面
  AfterClass: true
  # 控制语句后面
  AfterControlStatement: true
  # enum定义后面
  AfterEnum: true
  # 函数定义后面
  AfterFunction: true
  # 命名空间定义后面
  AfterNamespace: true
  # struct定义后面
  AfterStruct: true
  # union定义后面
  AfterUnion: true
  # extern之后
  AfterExternBlock: true
  # catch之前
  BeforeCatch: true
  # else之前
  BeforeElse: true
  # 缩进大括号
  IndentBraces: false
  # 分离空函数
  SplitEmptyFunction: false
  # 分离空语句
  SplitEmptyRecord: false
  # 分离空命名空间
  SplitEmptyNamespace: false

# 在二元运算符前换行: None(在操作符后换行), NonAssignment(在非赋值的操作符前换行), All(在操作符前换行)
BreakBeforeBinaryOperators: NonAssignment

# 在大括号前换行: Attach(始终将大括号附加到周围的上下文), Linux(除函数、命名空间和类定义,与Attach类似), 
#   Mozilla(除枚举、函数、记录定义,与Attach类似), Stroustrup(除函数定义、catch、else,与Attach类似), 
#   Allman(总是在大括号前换行), GNU(总是在大括号前换行,并对于控制语句的大括号增加额外的缩进), WebKit(在函数前换行), Custom
#   注:这里认为语句块也属于函数
BreakBeforeBraces: Custom

# 在三元运算符前换行
BreakBeforeTernaryOperators: false

# 在构造函数的初始化列表的冒号后换行
BreakConstructorInitializers: AfterColon

#BreakInheritanceList: AfterColon

BreakStringLiterals: false

# 每行字符的限制,0表示没有限制
ColumnLimit: 0

CompactNamespaces: true

# 构造函数的初始化列表要么都在同一行,要么都各自一行
ConstructorInitializerAllOnOneLineOrOnePerLine: false

# 构造函数的初始化列表的缩进宽度
ConstructorInitializerIndentWidth: 4

# 延续的行的缩进宽度
ContinuationIndentWidth: 4

# 去除C++11的列表初始化的大括号{后和}前的空格
Cpp11BracedListStyle: true

# 继承最常用的指针和引用的对齐方式
DerivePointerAlignment: false

# 固定命名空间注释
FixNamespaceComments: true

# 缩进case标签
IndentCaseLabels: false

IndentPPDirectives: None

# 缩进宽度
IndentWidth: 4

# 函数返回类型换行时,缩进函数声明或函数定义的函数名
IndentWrappedFunctionNames: false

# 保留在块开始处的空行
KeepEmptyLinesAtTheStartOfBlocks: true

# 连续空行的最大数量
MaxEmptyLinesToKeep: 1

# 命名空间的缩进: None, Inner(缩进嵌套的命名空间中的内容), All
NamespaceIndentation: None

# 指针和引用的对齐: Left, Right, Middle
PointerAlignment: Right

# 允许重新排版注释
ReflowComments: false

# 允许排序#include
SortIncludes: false

# 允许排序 using 声明
SortUsingDeclarations: false

# 在C风格类型转换后添加空格
SpaceAfterCStyleCast: false

# 在Template 关键字后面添加空格
SpaceAfterTemplateKeyword: true

# 在赋值运算符之前添加空格
SpaceBeforeAssignmentOperators: true

# SpaceBeforeCpp11BracedList: true

# SpaceBeforeCtorInitializerColon: true

# SpaceBeforeInheritanceColon: true

# 开圆括号之前添加一个空格: Never, ControlStatements, Always
SpaceBeforeParens: ControlStatements

# SpaceBeforeRangeBasedForLoopColon: true

# 在空的圆括号中添加空格
SpaceInEmptyParentheses: false

# 在尾随的评论前添加的空格数(只适用于//)
SpacesBeforeTrailingComments: 1

# 在尖括号的<后和>前添加空格
SpacesInAngles: false

# 在C风格类型转换的括号中添加空格
SpacesInCStyleCastParentheses: false

# 在容器(ObjC和JavaScript的数组和字典等)字面量中添加空格
SpacesInContainerLiterals: true

# 在圆括号的(后和)前添加空格
SpacesInParentheses: false

# 在方括号的[后和]前添加空格,lamda表达式和未指明大小的数组的声明不受影响
SpacesInSquareBrackets: false

# 标准: Cpp03, Cpp11, Auto
Standard: Cpp11

# tab宽度
TabWidth: 4

# 使用tab字符: Never, ForIndentation, ForContinuationAndIndentation, Always
UseTab: Always

有时clangd的检查过于严格,会在我们认为不需要进行修改的地方标黄色波浪线(Warning),虽然我们应当小心谨慎地编写规范的代码,但有时确实无法完全按照标准去写懒得改,此时我们可以对clangd的配置文件进行修改以去掉刺眼的波浪线。按F1呼出VS Code的命令窗口,输入“clangd”,选择“Open user configuration file”打开config.yaml配置文件,我们给出一个例子以供参考:

CompileFlags: # 编译标志
  Add: [
    "-Wall", # 启用所有警告
    "-Wno-unused-but-set-variable", # 禁用警告存在未使用的变量
  ]
  Remove: [
    "-Werror", # 移除将所有警告作为错误的选项
  ]
Diagnostics: # 诊断设置
  UnusedIncludes: None # 禁用警告存在未使用的头文件
  Suppress: 
    pp_including_mainfile_in_preamble # 禁用警告存在头文件递归包含

配置文件根据具体需要进行修改。

现在我们已经可以愉快地使用clangd了,如果你想了解如何更好地配置clangd,可以查阅clangd官网

还可以做到更多#

VS Code可以被用来做更多的事情,你不仅可以用VS Code的Remote-SSH插件进入Linux的世界来编写C/C++、Rust等语言的大型项目,还可以用它来编写Markdown、LaTeX文档,甚至可以用它来玩远古时代的游戏!而这一切都仅仅只需要你学会合理地STFW2RTFM3,如果遇到了靠STFW与RTFM难以解决的问题,你也可以向他人请教,但在这之前请先学会提问的智慧别像弱智一样提问

Footnotes#

  1. [科普][FAQ]MinGW vs MinGW-W64及其它

  2. Search The Friendly Fucking Web

  3. Read The Friendly Fucking Manual

Visual Studio Code配置指南
https://wsfcloud.github.io/posts/how-to-configure-vscode/
Author
风烟流云
Published at
2024-10-19