%%
# 纲要
> 主干纲要、Hint/线索/路标
# Q&A
#### 已明确
#### 待明确
> 当下仍存有的疑惑
**❓<font color="#c0504d"> 有什么问题?</font>**
# Buffer
## 闪念
> sudden idea
## 候选资料
> Read it later
%%
# 关于 clang 与 clangd 的说明
参见 [[05-工具/GNU 工具/clangd 工具|clangd 工具]]
# VSCode 中的 clangd 插件
VSCode 中的 **clangd 插件**是通过调用本机安装的 clangd 来**为 C/C++ 提供代码辅助功能**,包括:
- code completion
- compile errors and warnings => diagnostics and fixes(诊断与修复):
- go-to-definition and cross references => find declarations, references, and definitions
- syntex highlights
- code actions
- hover information and inlay hints
- include management
- code formatting
- simple refactorings
从提供的功能上来说,clangd 与 VSCoede 中的 C/C++ 官方插件基本相当,但**其功能效果更强大**,**CLion 中使用的就是 clangd**。
> [!quote]
> clangd 的杀手特性莫过于**clang-tidy 集成**和**全局补全功能**[^clangd_功能] [^1]。
>
> - clangd 集成了 clang-tidy 并且完成了 clang-tidy 的 quick fix 功能,可以直接在 clangd 中使用 quickfix 来完成 clang-tidy 的改动
> - 直接补全没有 include 的内容,并且会自动增加 include
<br><br>
# 配置 clangd 插件
VSCode 里使用 clangd 插件,需要配置的项包括:
1. 指定系统上的 `clangd` 工具路径;
2. 禁用 C/C++官方插件提供的 IntelliSense 引擎,该插件的功能和 clangd 插件提供的功能冲突。
3. 设置 **clangd 的运行参数**,包括**系统库文件搜索路径**等(参见 [[05-工具/GNU 工具/clangd 工具#clangd 的系统库头文件搜索路径|clangd 工具-系统库文件搜索路径]])
4. 设置 **clangd 配置**(可选:下面两种方式二选一)
- 方式一:通过 VSCode 中 clangd 插件的 `Fallback Flags` 配置项进行设置——指定当 CDB(`compile_commands.json` 文件)不存在时,所使用的**clang 编译标志**;
- 方式二(推荐):在项目根目录下创建 `.clangd` 配置文件指定配置——在该文件中指定编译标志等 clangd 配置信息。
### 具体说明
- **指定 `clangd` 工具路径**

- **设置禁用 C/C++官方插件提供的 IntelliSense 引擎**[^2]
clangd 与 C/C++官方提供插件提供的 IntelliSense 功能冲突,因此需要将后者禁用,只需设置如下选项为 `disabled` 即可, C/C++官方插件的其它功能仍然是 C++编程环境所需要的,所以不要卸载插件。
![[_attachment/05-工具/VSCode/VSCode 配置使用 Clangd 插件.assets/IMG-VSCode 配置使用 Clangd 插件-505E84B04EEA66771C0DBE0CE0570195.png|350]]


除了 IntelliSenseEngine 外还有两个选项,暂不确定是否也需要禁用:
```json
"C_Cpp. intelliSenseEngine": "disabled",
"C_Cpp. autocomplete": "Disabled",
"C_Cpp. errorSquiggles": "Disabled",
```
- **设置 `Clangd` 工具的运行参数**

- **设置 clangd 的 `Fallback Flags`**
即设置当 CDB(`compile_commands.json` 文件)不存在时,编译器所使用的**编译标志**。
工作区目录下的 `.clangd` 配置文件能够覆盖此处的设置。

示例:
```json
{
"clangd. fallbackFlags": [
// 设置 clangd 代码检查的 c++版本,目前默认是 c++14
"-std=c++17",
// 增加项目自身头文件依赖路劲,因为使用 vs2019 编译不会生成 compile_command. json 文件,项目自己的头文件就不会找到
"-I${workspaceFolder}", // 项目根目录
"-I${workspaceFolder}/third_party/include" // 第三方依赖的头文件目录
]
}
```
### 配置 clangd 的头文件引入路径
> [!caution] `.clangd` 配置文件中指定头文件包含路径时,只能是**以"具体路径"的形式给出**(绝对路径或相对于 `.clangd` 文件的相对路径)
>
>
如果要像 `c_cpp_properties.json` 中那样通过 `${file}`、`${fileDirname}` 等 VSCode 内置变量**指定==相对于当前打开文件==的路径**,
则必须**通过 VSCode 中 clangd 插件的 `Fallback Flags` 配置项**进行指定。
**指定相对于"当前打开文件"的头文件路径** 示例:
```JSON title:settings.json
{
"clangd.fallbackFlags": [
"--std=c++20",
"--target=x86_64-pc-windows-gnu",
"-I${file}/../include", // 使用相对路径, ${file}为vscode内置变量, 表示当前打开文件
"-I${file}/../../include" // 使用相对路径, ${file}为vscode内置变量, 表示当前打开文件
],
}
```
> [!error]
> `clangd.fallbackFlags` 属性中 **似乎==只能识别 VSCode 的 `${file}`、`${workspaceFolder}`变量==而不能识别 ` ${fileDirname}` 变量**,
> 所以上述头文件路径如果改成理论上等效的 `"-I${fileDirname}/include"` 以及 ` -I${fileDirname}/../include ` 会无法找到路径。
<br><br>
# 配置 clang-tidy 检查项
需要在项目文件夹下创建 `.clang-tidy ` 文件。
可参考: https://blog.csdn.net/m0_54206076/article/details/123836683
<br><br><br>
# 相关问题
### clangd 无法找到标准库头文件
###### 问题描述
现象描述:**clangd 查找头文件的路径是 Visual Studio 自带的 MSVC 里的标准库实现,并非预期的 MinGW 的标准库路径,导致==在编辑器页面下显示 MSVC 的标准库里未找到该 `<bits/stdc++.h` 头文件而报错==**


###### 问题分析
根本原因:**在 Windows 上 clang(官方发行的 windows 版 clang)==默认使用的是 MSVC 编译器==**,所以查找系统头文件时都是在 MSVC 的路径下去找。
详细原因说明及分析参见 [[05-工具/GNU 工具/clangd 工具#clang 功能及所用编译器|clangd 工具-clang 默认编译器]]。
###### 解决办法
==**解决办法**==:**为项目添加编译标志 `--target=x86_64-pc-windows-gnu`**
1. 方式一:在项目目录里创建 `.clangd` 配置文件,为 clangd 配置添加编译标志(这些编译标志将在 clangd 使用内部的 clang 前端模拟编译过程时**为 clang 前端配置**),指定 `--target=x86_64-pc-windows-gnu`,即**指定 clang 使用 MinGW 编译工具链进行编译解析**,如下图所示:

2. 方式二:在 `CMakeLists.txt` 文件里直接指定**编译标志**,添加 `--target=x86_64-pc-windows-gnu`

此外,**还可通过 `-isystem` 或 `-I` 标志指定编译器搜索头文件的目录**:
- `-isystem`:专用于**指定额外的"系统库"头文件**的搜索路径,编译器将在这些目录中搜索头文件,同时将这些目录中的代码**视为系统代码**,从而会对这些目录中的代码**应用更宽松的警告检查,降低警告的级别**,通常用于添加外部库(如 Boost、Qt 等)的头文件路径。
- **该标志可在同一命令中多次使用,以添加多个额外的系统库目录**。<br> `gcc -isystem /usr/include/boost my_program.c`
- `-I`:添加**自定义头文件的搜索路径**,使用 `-I` 添加的路径被视为项目的一部分,因此编译器将对这些目录中的代码**应用所有警告和错误检查**,通常用于添加当前项目内部或第三方库的头文件路径。
- **该标志可在同一命令中多次使用,以添加多个额外的头文件包含目录**。<br> `gcc -I/path/to/mylibrary/include my_program.c`
<br><br><br>
# 参考资料
# Footnotes
[^1]: [最终,我看向了clangd](https://zhuanlan.zhihu.com/p/364518020)
[^2]: [VSCode 使用 clangd 来实现代码提示、补全](https://zsien.cn/vscode-uses-clangd-to-provide-intellisense-and-autocomplete/)