VSCode 的 C++ 配置: clang++ 单文件编译和 clangd 检查 (可用于 macOS)

2023-09-24
修改于 2024-01-09

更新:由于在 2023/09/24 将这个配置作为主力配置,所以大更了一波,相当于重写了,所以修改了发布日期重新发一遍。本文原写于 2023/03/09。

前情提要

因为一些作死操作,把我之前用的 Ubuntu 搞崩了,借此机会把 wsl 的发行版改成了 Arch,vscode 也打算使用 llvm 全家桶。

安装 Arch 非常方便,How to Setup | ArchWSL official documentation (wsldl-pg.github.io) 按着这个链接里的方法,10 分钟内就能搞定。

更新:换了 macOS 作为主力系统,当然得用 llvm 全家桶()

本文主要应用场景是单文件的编译,主要用来刷算法题之类。如果使用 CMake 等工具,则本文中的一部分配置并不一定兼容。

主要分为两步操作,使用 clang/lldb 编译和调试,以及使用 clangd 进行补全和检查,这两者应该是互相独立的,可以只使用其中一个,但是找到的大多数教程好像都是两个混在一起搞得。

本文的配置不使用 C/C++ 插件 和 Code Runner 插件!!请禁用或者卸载它们。由于 VSCode 和 C/C++ 插件的一些 bug,我选择绕开它们,使用 CodeLLDB 和 Clangd 来替代。

我的环境: Windows11, Arch Linux on WSL2 macOS Ventura 13.5 on Apple Silicon 我觉得应该能行的环境: 任何 M 系列芯片的 Mac,稍微修改可以兼容大部分设备。

使用 clang/lldb 进行单文件编译和调试

  1. 确保 clang++ 已经正确安装(通过 clang++ -v 可以验证)

    • 对于 macOS,运行 xcode-select --install 可以安装好本文用到的所有包
    • 对于 Linux,下载 llvm 包,大概率包含了本文用到的所有包
  2. vscode 已启用 CodeLLDB 插件(报错无法下载可以先按报错给的 url 用浏览器下载,然后手动安装)

  3. 卸载微软提供的 C/C++ 插件!!!也不要使用 Code Runner 插件。

  4. tasks.json,放入.vscode 文件夹中

    {
      "version": "2.0.0",
      "tasks": [
        {
          "type": "shell",
          "label": "C/C++: clang++ build active file",
          "command": "/usr/bin/clang++", // `which clang++` may help you find this path
          "args": [
            "--std=c++17",
            "-fcolor-diagnostics",
            "-fansi-escape-codes",
            "-g",
            "${file}",
            "-o",
            "${workspaceFolder}/.build/${fileBasenameNoExtension}"
            "-fstandalone-debug", // to enable viewing std::string etc. when using lldb on Windows or Linux 
          ],
          "options": {
            "cwd": "${fileDirname}"
          },
          "group": {
            "kind": "build",
            "isDefault": true
          },
          "detail": "Task generated by Debugger."
        }
      ]
    }
    

    我的习惯是把所有的可执行文件放到 ./build/ 文件夹下,如果不这么做的话,改变 3、4 步中的文件路径,以及忽略第五步

  5. launch.json,放入.vscode 文件夹中

    {
      "version": "0.2.0",
      "configurations": [
        {
          "name": "C/C++: clang++ build and debug active file customize",
          "type": "lldb",
          "request": "launch",
          "program": "${workspaceFolder}/.build/${fileBasenameNoExtension}",
          "args": [],
          "cwd": "${workspaceFolder}",
          "preLaunchTask": "C/C++: clang++ build active file"
        }
      ]
    }
    
  6. 在文件夹里新建一个 .build 文件夹( macOS / Linux 必做)

  7. 按 F5,就可以编译调试了

这样的配置下,右上角不会有运行的那个小按钮。由于未知问题,这个又 C/C++ 插件提供的按钮不会同步 tasks.json 和 launch.json 中的配置,所以放弃使用了那个插件。

使用 clangd 自动补全、代码检查

  1. 确保已安装 clangd(应该和 clang++ 在一个包里的,通过 clangd --version 检查)

  2. 安装 VScode 插件 clangd

  3. 在工作区根目录下新建一个 compile_flags.txt,这是用来为 clangd 指定参数的,比如使用的标准或是标准库路径之类。内容就是编译选项,一行一个。这里只写了一个标准作为例子

    --std=c++17
    

一般来说 clangd 的参数是由 compile_commands.json 指定,由 CMake 等构建工具自动生成。但是由于在我的需求中对每一个文件都是相同的编译参数,所以可以手写 compile_flags.txt 统一管理。 具体查看 JSON Compilation Database Format Specification

关于 .clang-format 文件

我的习惯是直接放在 ~ 下(如果你的代码都放在你的~和其子文件夹里的话)

生成的话,官方文档的那个网页实在是太丑了,我直接选择去 CLion 里配好,然后导出为 .clang-format,既可视化又方便

贴一下我的.clang-format

# Generated from CLion C/C++ Code Style settings
BasedOnStyle: LLVM
AccessModifierOffset: -4
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: None
AlignOperands: Align
AllowAllArgumentsOnNextLine: false
AllowAllConstructorInitializersOnNextLine: false
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortBlocksOnASingleLine: Always
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: All
AllowShortIfStatementsOnASingleLine: Always
AllowShortLambdasOnASingleLine: All
AllowShortLoopsOnASingleLine: true
AlwaysBreakAfterReturnType: None
AlwaysBreakTemplateDeclarations: Yes
BreakBeforeBraces: Custom
BraceWrapping:
  AfterCaseLabel: false
  AfterClass: false
  AfterControlStatement: Never
  AfterEnum: false
  AfterFunction: false
  AfterNamespace: false
  AfterUnion: false
  BeforeCatch: false
  BeforeElse: false
  IndentBraces: false
  SplitEmptyFunction: false
  SplitEmptyRecord: true
BreakBeforeBinaryOperators: None
BreakBeforeTernaryOperators: true
BreakConstructorInitializers: BeforeColon
BreakInheritanceList: BeforeColon
ColumnLimit: 0
CompactNamespaces: false
ContinuationIndentWidth: 8
IndentCaseLabels: true
IndentPPDirectives: None
IndentWidth: 4
KeepEmptyLinesAtTheStartOfBlocks: true
MaxEmptyLinesToKeep: 2
NamespaceIndentation: All
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PointerAlignment: Right
ReflowComments: false
SpaceAfterCStyleCast: true
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: false
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 0
SpacesInAngles: false
SpacesInCStyleCastParentheses: false
SpacesInContainerLiterals: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
TabWidth: 4
UseTab: Never

故障排除

macOS 无法使用集成终端调试

  • 具体表现为在 enternalConsole 为 false 的时候并不会像在 Windows 中一样出现一个新的集成终端用来输入,导致没有地方输入从而无法调试。
  • 这种情况出现于使用了微软提供的 C/C++ 插件,并且 launch.json 中 type 为 “cppdbg” 时。这是 VSCode 的 bug,微软文档提供了一种解决方案,但是实测没效果()
  • 解决方案一是将 enternalConsole 设为 true,如果接受使用外部终端进行调试的话;
  • 解决方案二是不用微软提供的插件,而是使用 CodeLLDB 插件提供的调试选项。也就是按照本文进行操作。

吐槽:VSCode 的 bug 还真不少,在 Windows 上外部终端用不了,Mac 上却又只能用外部终端()

VSCode 在 WSL 中无法正确联网

  • 主要原因是 vscode 会在 wsl 中使用在 Windows 下的代理 ip+ 端口(一般是 127.0.0.1:端口 ),
  • 解决方案一:给 WSL 设置 http_proxy 和 https_proxy,把 127.0.0.1 改成局域网下 windows 的 ip
  • 解决方案二:关闭系统代理,直接使用 TUN /增强模式。
Comments
  • Latest
  • Oldest
  • Hottest
Powered by Waline v3.1.3