VSCode Clangd配置
Dionysen
image

使用clangd作为语法检查工具,跨平台,简单易用,方便更换环境。

VSCode配置clangd

下载安装llvm,并将bin文件夹添加到环境变量中。

VSCode中安装clangd插件,如果路径中找不到clangd,会提示安装clangd,点击是就可以。

image

打开设置,打开json文件:

{
"workbench.tree.indent": 10,
"workbench.colorTheme": "GitHub Dark",
"workbench.iconTheme": "material-icon-theme",
"workbench.tree.renderIndentGuides": "always",
"workbench.activityBar.location": "hidden",
// Editor
"editor.fontFamily": "'Fira Code','Courier New', Monaco, Menlo, 'Droid Sans Mono', Hack, Consolas, monospace, Monaco",
"editor.fontWeight": "400",
"editor.lineHeight": 1.7,
"editor.wordWrap": "on",
"editor.smoothScrolling": true,
"editor.mouseWheelZoom": true,
"editor.guides.indentation": true,
"editor.fontSize": 16,
"editor.links": false,
"editor.inlayHints.enabled": "off",
"editor.stickyScroll.enabled": true,
"editor.minimap.enabled": true,
"editor.minimap.showSlider": "always",
"editor.scrollbar.vertical": "hidden",
"files.autoSave": "onFocusChange",
// Termial
"terminal.integrated.fontSize": 15,
"terminal.integrated.fontFamily": "'Courier New', Monaco",
"terminal.integrated.fontWeight": "normal",
"terminal.integrated.enableMultiLinePasteWarning": false,
// Miscellaneous
"git.enabled": false,
"git.ignoreMissingGitWarning": true,
"git.openRepositoryInParentFolders": "never",
"explorer.confirmDelete": false,
"extensions.ignoreRecommendations": true,
// Custom
"command-runner.commands": {
"run": "cls; xmake; .\\build\\windows\\x64\\debug\\opengl.exe",
},
// Compiler
"clangd.path": "c:\\Users\\dionysen\\AppData\\Roaming\\Code\\User\\globalStorage\\llvm-vs-code-extensions.vscode-clangd\\install\\17.0.3\\clangd_17.0.3\\bin\\clangd.exe",
"window.commandCenter": false,
"workbench.layoutControl.enabled": false,
"clangd.arguments": [
// 让 Clangd 生成更详细的日志
"--log=verbose",
// 输出的 JSON 文件更美观
"--pretty",
// compelie_commands.json 文件的目录位置(相对于工作区,由于 CMake 生成的该文件默认在 build 文件夹中,故设置为 build)
"--compile-commands-dir=.",
// 允许补充头文件
"--header-insertion=iwyu",
],
}

此时就可以正常使用了,可以使用不同的构建工具来生成compile_commands.json来让clangd识别你的头文件和源文件。如使用xmake创建一个工程:

PS C:\Users\dionysen\test> xmake create -P ./hello
create hello ...
[+]: src\main.cpp
[+]: xmake.lua
[+]: .gitignore
create ok!

在工程目录下创建文件夹headers,并在其下创建文件func.h,可以看到已经可以自动补全了并提示错误或警告了:

image

此时在main.cpp中包含头文件func.h会提示找不到:

image

因为clangd不知道要去哪里搜索你的头文件,compile_commands.json文件用以记录文件目录、编译指令等,故名编译数据库

xmake.lua中添加add_includedirs("./headers")

add_rules("mode.debug", "mode.release")

target("hello")
set_kind("binary")
add_files("src/*.cpp")
add_includedirs("./headers")

headers文件夹下的所有.h文件都会被添加到编译数据库中。然后使用xmake生成compile_commands.json,终端中输入:

PS C:\Users\dionysen\test\hello> xmake project -k compile_commands
checking for platform ... windows
checking for architecture ... x64
checking for Microsoft Visual Studio (x64) version ... 2022
checking for Microsoft C/C++ Compiler (x64) version ... 19.37.32825
create ok!

image

目录中会出现compile_commands.json文件,在voscode的设置json文件中设置compile_commands.json文件的路径.即与xmake.lua同一个文件夹。

"clangd.arguments": [
"--compile_commands_dir=.",
"--clang-tidy", // 开启clang-tidy
"--all-scopes-completion", // 全代码库补全
"--completion-style=detailed", // 详细补全
"--background-index"
],

此时发现错误提示都不见了:

image

编译运行也没有问题:

image

使用clang-format格式化代码

设置中找到image

开启之后会在保存文件时自动格式化代码,很是方便。

ctri+shift+p开发命令面板,输入format,找到选项

image

选择image

将默认格式化工具设置为clangd,然后clangd就会根据工作目录下的.clang-format进行格式化了,以下是.clang-format的备份:

--- 

BasedOnStyle: Microsoft

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

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

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

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

# 左对齐逃脱换行(使用反斜杠换行)的反斜杠
AlignEscapedNewlinesLeft: true

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

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

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

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

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

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

# 允许短(只有一行时)的if语句保持在同一行
AllowShortIfStatementsOnASingleLine: false

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

# 总是在定义返回类型后换行(deprecated)
AlwaysBreakAfterDefinitionReturnType: None

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

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

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

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

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

# 使用Microsoft风格,故不再配置
# # 在二元运算符前换行: None(在操作符后换行), NonAssignment(在非赋值的操作符前换行), All(在操作符前换行)
# BreakBeforeBinaryOperators: NonAssignment

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

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

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

# 在构造函数的初始化列表的逗号前换行
BreakConstructorInitializersBeforeComma: true

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

# 描述具有特殊意义的注释的正则表达式,它不应该被分割为多行或以其它方式改变
CommentPragmas: '^ IWYU pragma:'

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

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

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

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

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

# 关闭格式化
DisableFormat: false

# 自动检测函数的调用和定义是否被格式为每行一个参数(Experimental)
ExperimentalAutoDetectBinPacking: false

# 需要被解读为foreach循环而不是函数调用的宏
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]

# 缩进case标签
IndentCaseLabels: false

# 缩进宽度
IndentWidth: 4

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

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

# 开始一个块的宏的正则表达式
MacroBlockBegin: ''

# 结束一个块的宏的正则表达式
MacroBlockEnd: ''

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

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

# 在call(后对函数调用换行的penalty
PenaltyBreakBeforeFirstCallParameter: 19

# 在一个注释中引入换行的penalty
PenaltyBreakComment: 300

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

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

# 允许排序#include
SortIncludes: true

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

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

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

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

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

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

Debug

参考VS code 安装插件 lldb 调试 CPP 程序

注意使用xmake时要配置为debug模式:

xmake f --mode=debug
显示评论