clangd配置

clangd

安装clangd

x86-64平台直接下载二进制

clangd的源码地址

1
https://github.com/clangd/clangd/tags

选最新的下载即可

可以直接下载zip包,然后解压,将bin目录中的clangd放在/usr/bin/下面,将lib目录下面的放在/usr/lib/下面

其他平台需要自己编译

llvm-project编译方法:

  1. git地址
1
git clone https://github.com/llvm/llvm-project.git
  1. 新建一个目录build,用来存放编译的文件,并进入该目录
  2. 使用cmake进行编译

这里的$LLVM_ROOT是该项目的安装目录

1
cmake $LLVM_ROOT/llvm/ -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_PROJECTS="clang;clang-tools-extra"
  1. 可以使用ninja来编译,会比make快n倍!!!
1
#在cmake中增加 -G Ninja
  1. 编译clangd
1
cmake --build $LLVM_ROOT/build --target clangd
  1. 检查是否编译成功
1
check-clangd
  1. build/bin中即可发现clangd的二进制

安装llvm全家桶(仅限debian系)

添加llvm的官方源,可以从中安装最新的llvm和clang

1
2
3
wget https://apt.llvm.org/llvm.sh
chmod +x llvm.sh
sudo ./llvm.sh

添加了新的软件源后,自由安装

1
2
3
sudo apt update
sudo apt install clang-18 libclang-18-dev
sudo apt install clang-format #按你想要安装的版本来,不加版本号的话,看你的发行版默认版本,Ubuntu20.04默认是10,22.04默认是14

vscode安装clangd插件

直接在插件中搜索clangd,安装即可

还可以安装clang-format,也是直接插件安装即可

配置clangd

vscode的settings.json

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
{
"files.exclude": {
"**/.git": true,
"**/.svn": true,
"**/.hg": true,
"**/CVS": true,
"**/.DS_Store": true,
"**/Thumbs.db": true,
"**/*.a":true,
"**/*.o":true,
"**/*.cmd":true,
"**/*.order":true,
"**/arch/alpha": true,
"**/arch/arc": true,
"**/arch/arm": true,
"**/arch/arm64": true,
"**/arch/csky": true,
"**/arch/h8300": true,
"**/arch/hexagon": true,
"**/arch/ia64": true,
"**/arch/m68k": true,
"**/arch/microblaze": true,
"**/arch/mips": true,
"**/arch/nds32": true,
"**/arch/nios2": true,
"**/arch/openrisc": true,
"**/arch/parisc": true,
"**/arch/powerpc": true,
"**/arch/riscv": true,
"**/arch/s390": true,
"**/arch/sh": true,
"**/arch/sparc": true,
"**/arch/um": true,
"**/arch/x86": true,
"**/arch/xtensa": true,
},
"search.exclude": {
"**/node_modules": true,
"**/bower_components": true,
"**/*.code-search": true,
"**/arch/alpha": true,
"**/arch/arc": true,
"**/arch/arm": true,
"**/arch/arm64": true,
"**/arch/csky": true,
"**/arch/h8300": true,
"**/arch/hexagon": true,
"**/arch/ia64": true,
"**/arch/m68k": true,
"**/arch/microblaze": true,
"**/arch/mips": true,
"**/arch/nds32": true,
"**/arch/nios2": true,
"**/arch/openrisc": true,
"**/arch/parisc": true,
"**/arch/powerpc": true,
"**/arch/riscv": true,
"**/arch/s390": true,
"**/arch/sh": true,
"**/arch/sparc": true,
"**/arch/um": true,
"**/arch/x86": true,
"**/arch/xtensa": true,
},
"C_Cpp.intelliSenseEngine": "disabled",
"clangd.path": "clangd",
"clangd.arguments": [
"--pretty",// 输出的 JSON 文件更美观
"--compile-commands-dir=${workspaceFolder}/",
"--query-driver=${workspaceFolder}/../toolchains/gcc-chushi-12.2.0-2023.06-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-",//指定编译器路径
"--log=verbose",// 让 Clangd 生成更详细的日志
"--background-index",//后台分析并保存索引
"--all-scopes-completion", // 全局补全(补全建议会给出在当前作用域不可见的索引,插入后自动补充作用域标识符),例如在main()中直接写cout,即使没有`#include <iostream>`,也会给出`std::cout`的建议,配合"--header-insertion=iwyu",还可自动插入缺失的头文件
"--clang-tidy", // 启用 Clang-Tidy 以提供「静态检查」
"--clang-tidy-checks=performance-*, bugprone-*, misc-*, google-*, modernize-*, readability-*, portability-*",
"--completion-parse=auto", // 当 clangd 准备就绪时,用它来分析建议
"--completion-style=detailed", // 建议风格:打包(重载函数只会给出一个建议);还可以设置为 detailed
// 启用配置文件(YAML格式)
"--enable-config",
"--fallback-style=Webkit", // 默认格式化风格: 在没找到 .clang-format 文件时采用,可用的有 LLVM, Google, Chromium, Mozilla, Webkit, Microsoft, GNU
"--function-arg-placeholders=true", // 补全函数时,将会给参数提供占位符,键入后按 Tab 可以切换到下一占位符,乃至函数末
"--header-insertion-decorators", // 输入建议中,已包含头文件的项与还未包含头文件的项会以圆点加以区分
"--header-insertion=iwyu", // 插入建议时自动引入头文件 iwyu
"--include-cleaner-stdlib", // 为标准库头文件启用清理功能(不成熟!!!)
"--pch-storage=memory", // pch 优化的位置(Memory 或 Disk,前者会增加内存开销,但会提升性能)
"--ranking-model=decision_forest", // 建议的排序方案:hueristics (启发式), decision_forest (决策树)
"-j=12", // 同时开启的任务数量
],
// 找不到编译数据库(compile_flags.json 文件)时使用的编译器选项,这样的缺陷是不能直接索引同一项目的不同文件,只能分析系统头文件、当前文件和被include的文件
"clangd.fallbackFlags": [
"-pedantic",
"-Wall",
"-Wextra",
"-Wcast-align",
"-Wdouble-promotion",
"-Wformat=2",
"-Wimplicit-fallthrough",
"-Wmisleading-indentation",
"-Wnon-virtual-dtor",
"-Wnull-dereference",
"-Wold-style-cast",
"-Woverloaded-virtual",
"-Wpedantic",
"-Wshadow",
"-Wunused",
"-pthread",
"-fuse-ld=lld",
"-fsanitize=address",
"-fsanitize=undefined",
"-stdlib=libc++"
//这里可以包含额外的头文件路径
],
"clangd.checkUpdates": true, // 自动检测 clangd 更新
"clangd.onConfigChanged": "restart", // 重启 clangd 时重载配置,具体方法: F1 + Fn 打开命令面板,然后搜索“clangd: restart"
"clangd.serverCompletionRanking": true, // 借助网上的信息排序建议
"clangd.detectExtensionConflicts": true, // 当其它拓展与 clangd 冲突时警告并建议禁用
"editor.suggest.snippetsPreventQuickSuggestions": false, // clangd的snippets有很多的跳转点,不用这个就必须手动触发Intellisense了
"editor.formatOnSave": true,
"editor.formatOnType": true,
"editor.formatOnPaste": true,
"clang-format.executable": "/usr/bin/clang-format",
"files.associations": {
"*.h":"c",
}
}

注意的要点:

  1. 编译时使用bear产生compile_commands.json文件,放在--compile-commands-dir指定的目录中。
  2. 使用cmake时,可以指定cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=1来产生compile_commands.json。
  3. 将vscode中的c/c++的智能补全禁用掉(或者就不要安装微软的c/cpp扩展),即"C_Cpp.intelliSenseEngine": "disabled"

clangd的config.yaml

clangd的配置采用YAML格式,包括用户配置(全局)和项目配置

其中,用户配置在~/.config/clangd/config.yaml里面,项目配置在项目根目录的.clangd

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Diagnostics: #诊断
ClangTidy:
Add: ["*"]
Remove:
[
abseil*,
fuchsia*,
llvmlib*,
zircon*,
altera*,
google-readability-todo,
readability-braces-around-statements,
hicpp-braces-around-statements,
modernize-use-trailing-return-type, # 不要每个都加上尾返回值类型
readability-identifier-length, # 不检查变量名长度
cppcoreguidelines-avoid-magic-numbers, # 不检查魔法数字
readability-magic-numbers, #同上
]
Index: #索引
Background: Build
CompileFlags: # 编译选项
Add: [-std=c++20, -Wall, -xc++]
# Add里面也可以增加你想要包含的头文件路径
Compiler: clang++

clang-format

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
#基于那个配置文件
BasedOnStyle: Google
Language: Cpp
# 标准: Cpp03, Cpp11, Auto
Standard: c++20
ColumnLimit: 120
BraceWrapping:
# case标签后面
AfterCaseLabel: false
# class定义后面
AfterClass: false
# 控制语句后面
AfterControlStatement: Never
# enum定义后面
AfterEnum: false
# 函数定义后面
AfterFunction: false
# 命名空间定义后面
AfterNamespace: false
# ObjC定义后面
AfterObjCDeclaration: false
# struct定义后面
AfterStruct: false
# union定义后面
AfterUnion: false
#ExternBlock定义后面
AfterExternBlock: false
# catch之前
BeforeCatch: false
# else之前
BeforeElse: false
# lambda块之前
BeforeLambdaBody: false
# while之前
BeforeWhile: false
# 缩进大括号
IndentBraces: false
# 分割空函数
SplitEmptyFunction: true
# 分割空记录
SplitEmptyRecord: true
# 分割空命名空间
SplitEmptyNamespace: true

# 在 @property 后面添加空格, \@property (readonly) 而不是 \@property(readonly).
ObjCSpaceAfterProperty: true
# 访问说明符(public、private等)的偏移
AccessModifierOffset: -4

# 开括号(开圆括号、开尖括号、开方括号)后的对齐: Align, DontAlign, AlwaysBreak(总是在开括号后换行)
AlignAfterOpenBracket: Align
# 连续赋值时,对齐所有等号
AlignConsecutiveAssignments: Consecutive
# 连续声明时,对齐所有声明的变量名
AlignConsecutiveDeclarations: Consecutive
# 连续宏声明时,对齐空格 #clang-format-10 可用
AlignConsecutiveMacros: Consecutive
# 对齐连接符: DontAlign(不对齐), Left(左对齐), Right(右对齐)
AlignEscapedNewlines: Left
# 水平对齐二元和三元表达式的操作数
AlignOperands: Align
# 对齐连续的尾随的注释
AlignTrailingComments: true
# 允许函数调用的所有参数在放在下一行
AllowAllArgumentsOnNextLine: true
# 允许函数声明的所有参数在放在下一行
AllowAllParametersOfDeclarationOnNextLine: true
# 允许短的块放在同一行
AllowShortBlocksOnASingleLine: Never
# 允许短的case标签放在同一行
AllowShortCaseLabelsOnASingleLine: false
# 允许短的枚举放在同一行
AllowShortEnumsOnASingleLine: false
# 允许短的函数放在同一行: None, InlineOnly(定义在类中), Empty(空函数), Inline(定义在类中,空函数), All
AllowShortFunctionsOnASingleLine: None
# 允许短的if语句保持在同一行
AllowShortIfStatementsOnASingleLine: Never
# 允许短的Lambdas语句保持在同一行
AllowShortLambdasOnASingleLine: None
# 允许短的循环保持在同一行
AllowShortLoopsOnASingleLine: false
# 总是在定义返回类型后换行(deprecated)
AlwaysBreakAfterDefinitionReturnType: None
# 总是在返回类型后换行: None, All, TopLevel(顶级函数,不包括在类中的函数),
# AllDefinitions(所有的定义,不包括声明), TopLevelDefinitions(所有的顶级函数的定义)
AlwaysBreakAfterReturnType: None
# 总是在多行string字面量前换行
AlwaysBreakBeforeMultilineStrings: false
# 总是在template声明后换行
AlwaysBreakTemplateDeclarations: Yes
# false表示函数实参要么都在同一行,要么都各自一行
BinPackArguments: true
# false表示所有形参要么都在同一行,要么都各自一行
BinPackParameters: true
# 大括号换行,只有当BreakBeforeBraces设置为Custom时才有效
# 在二元运算符前换行: None(在操作符后换行), NonAssignment(在非赋值的操作符前换行), All(在操作符前换行)
BreakBeforeBinaryOperators: NonAssignment
# 在大括号前换行: Attach(始终将大括号附加到周围的上下文), Linux(除函数、命名空间和类定义,与Attach类似),
# Mozilla(除枚举、函数、记录定义,与Attach类似), Stroustrup(除函数定义、catch、else,与Attach类似),
# Allman(总是在大括号前换行), GNU(总是在大括号前换行,并对于控制语句的大括号增加额外的缩进), WebKit(在函数前换行), Custom
# 注:这里认为语句块也属于函数
BreakBeforeBraces: Custom
# 在三元运算符前换行
BreakBeforeTernaryOperators: true
# 在构造函数的初始化列表的逗号前换行
BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: BeforeColon
# 在类声明继承列表的逗号前换行
BreakInheritanceList: BeforeColon
BreakAfterJavaFieldAnnotations: false
# 允许中断长字符串
BreakStringLiterals: true
# 描述具有特殊意义的注释的正则表达式,它不应该被分割为多行或以其它方式改变
CommentPragmas: '^ IWYU pragma:'
# 允许连续的名称空间声明将在同一行
CompactNamespaces: false
# 构造函数的初始化列表的缩进宽度
ConstructorInitializerIndentWidth: 4
# 延续的行的缩进宽度
ContinuationIndentWidth: 4
# 去除C++11的列表初始化的大括号{后和}前的空格
Cpp11BracedListStyle: true
# 继承最常用的指针和引用的对齐方式
DerivePointerAlignment: true
# 关闭格式化
DisableFormat: false
# 修饰符后放置空行
EmptyLineAfterAccessModifier: Never
# 修饰符前放置空行
EmptyLineBeforeAccessModifier: LogicalBlock
# 自动检测函数的调用和定义是否被格式为每行一个参数(Experimental)
ExperimentalAutoDetectBinPacking: false
# 修正命名空间注释
FixNamespaceComments: true
# 需要被解读为foreach循环而不是函数调用的宏
ForEachMacros:
- foreach
- Q_FOREACH
- BOOST_FOREACH
# 需要解读为if的函数
IfMacros:
- KJ_IF_MAYBE
IncludeBlocks: Regroup
# 对#include进行排序,匹配了某正则表达式的#include拥有对应的优先级,匹配不到的则默认优先级为INT_MAX(优先级越小排序越靠前),
# 可以定义负数优先级从而保证某些#include永远在最前面
IncludeCategories:
- Regex: '^<ext/.*\.h>'
Priority: 2
SortPriority: 0
CaseSensitive: false
- Regex: '^<.*\.h>'
Priority: 1
SortPriority: 0
CaseSensitive: false
- Regex: '^<.*'
Priority: 2
SortPriority: 0
CaseSensitive: false
- Regex: '.*'
Priority: 3
SortPriority: 0
CaseSensitive: false
# include块排序
IncludeIsMainRegex: '([-_](test|unittest))?$'
# 缩进修饰符
IndentAccessModifiers: false
# 缩进case块
IndentCaseBlocks: false
# 缩进case标签
IndentCaseLabels: true
# 缩进goto标签
IndentGotoLabels: true
# 预处理缩进
IndentPPDirectives: None
# 缩进extern块
IndentExternBlock: AfterExternBlock
# 缩进宽度
IndentWidth: 4
# 函数返回类型换行时,缩进函数声明或函数定义的函数名
IndentWrappedFunctionNames: false
# 添加尾部注释
InsertTrailingCommas: None
# 保留在块开始处的空行
KeepEmptyLinesAtTheStartOfBlocks: true
# Lambda块缩进
LambdaBodyIndentation: Signature
# 开始一个块的宏的正则表达式
MacroBlockBegin: ''
# 结束一个块的宏的正则表达式
MacroBlockEnd: ''
# 连续空行的最大数量
MaxEmptyLinesToKeep: 1
# 命名空间的缩进: None, Inner(缩进嵌套的命名空间中的内容), All
NamespaceIndentation: None
# 使用ObjC块时缩进宽度
ObjCBlockIndentWidth: 4
# 在ObjC的protocol列表前添加一个空格
ObjCSpaceBeforeProtocolList: false
# 使用的包构造函数初始化式样式
PackConstructorInitializers: NextLine
# 在call(后对函数调用换行的penalty
PenaltyBreakBeforeFirstCallParameter: 19
# 在一个注释中引入换行的penalty
PenaltyBreakComment: 300
# 第一次在<<前换行的penalty
PenaltyBreakFirstLessLess: 120
# 在一个字符串字面量中引入换行的penalty
PenaltyBreakString: 1000
# 对于每个在行字符数限制之外的字符的penalty
PenaltyExcessCharacter: 1000000
# 将函数的返回类型放到它自己的行的penalty
PenaltyReturnTypeOnItsOwnLine: 200
# 指针和引用的对齐: Left, Right, Middle
PointerAlignment: Left
PPIndentWidth: -1
RawStringFormats:
- Language: Cpp
Delimiters:
- cc
- CC
- cpp
- Cpp
- CPP
- 'c++'
- 'C++'
CanonicalDelimiter: ''
BasedOnStyle: google
- Language: TextProto
Delimiters:
- pb
- PB
- proto
- PROTO
EnclosingFunctions:
- EqualsProto
- EquivToProto
- PARSE_PARTIAL_TEXT_PROTO
- PARSE_TEST_PROTO
- PARSE_TEXT_PROTO
- ParseTextOrDie
- ParseTextProtoOrDie
- ParseTestProto
- ParsePartialTestProto
CanonicalDelimiter: pb
BasedOnStyle: google
# 引用对齐
ReferenceAlignment: Pointer
# 允许重新排版注释
ReflowComments: true
# 允许排序#include
SortIncludes: CaseSensitive
# 允许排序声明
SortUsingDeclarations: true
# 单独的定义块
SeparateDefinitionBlocks: Always
# 在C风格类型转换后添加空格
SpaceAfterCStyleCast: false
# 在赋值运算符之前添加空格
SpaceBeforeAssignmentOperators: true
# 在逻辑非操作符之后插入一个空格
SpaceAfterLogicalNot: false
# 在' template '关键字之后会插入一个空格
SpaceAfterTemplateKeyword: true
# 在用于初始化对象的c++ 11带括号的列表之前(在前面的标识符或类型之后)将插入一个空格
SpaceBeforeCpp11BracedList: false
# 构造函数初始化式冒号前的空格将被删除
SpaceBeforeCtorInitializerColon: true
# 在继承冒号前添加空格
SpaceBeforeInheritanceColon: true
# 控制括号前的单独空格。
SpaceBeforeParens: ControlStatements
# 开圆括号之前添加一个空格
SpaceBeforeParensOptions:
AfterControlStatements: true
AfterForeachMacros: true
AfterFunctionDefinitionName: false
AfterFunctionDeclarationName: false
AfterIfMacros: true
AfterOverloadedOperator: false
BeforeNonEmptyParentheses: false
# 在空的圆括号中添加空格
SpaceInEmptyParentheses: false
# 在基于冒号的范围循环之前 添加空格
SpaceBeforeRangeBasedForLoopColon: true
# 在尾随的评论前添加的空格数(只适用于//)
SpacesBeforeTrailingComments: 2
# 在尖括号的<后和>前添加空格
SpacesInAngles: Never
# 在容器(ObjC和JavaScript的数组和字典等)字面量中添加空格
SpacesInContainerLiterals: true
# 在C风格类型转换的括号中添加空格
SpacesInCStyleCastParentheses: false
# 在圆括号的(后和)前添加空格
SpacesInParentheses: false
# 在方括号的[后和]前添加空格,lamda表达式和未指明大小的数组的声明不受影响
SpacesInSquareBrackets: false
# tab宽度
TabWidth: 4
# 使用tab字符: Never, ForIndentation, ForContinuationAndIndentation, Always
UseTab: Always
DeriveLineEnding: false
UseCRLF: false
WhitespaceSensitiveMacros:
- STRINGIZE
- PP_STRINGIZE
- BOOST_PP_STRINGIZE
- NS_SWIFT_NAME
- CF_SWIFT_NAME

使用Clang编译linux内核

直接编译

1
2
make CC=clang defconfig
make CC=clang

交叉编译

1
make CC=clang ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-

使用LLVM编译

直接编译

编译时指定llvm为编译工具链

1
make CC=clang LD=ld.lld AR=llvm-ar NM=llvm-nm STRIP=llvm-strip \ OBJCOPY=llvm-objcopy OBJDUMP=llvm-objdump READELF=llvm-readelf HOSTCC=clang HOSTCXX=clang++ HOSTAR=llvm-ar HOSTLD=ld.lld

或者直接使用kbuild的简单编译法

1
make LLVM=1

如果你的LLVM工具链不在系统路径里面

1
make LLVM=/path/to/llvm/

如果你想直接使用某个版本的LLVM,这将直接使用clang-18等

1
make LLVM=-18

交叉编译

CROSS_COMPILE用来指定交叉编译器,如果在LLVM中没有指定CROSS_COMPILE,那么会使用ARCH来寻找,即,如果你仅使用LLVM工具,CROSS_COMPILE是不必要的。

1
make ARCH=arm64 LLVM=1

如果需要禁止clang自身的汇编器,可以使用LLVM_IAS=0,此时的CROSS_COMPILE是不可缺少的

1
make ARCH=arm64 LLVM=1 LLVM_IAS=0 CROSS_COMPILE=arm64-linux-gnu-

维护符号链接

由于使用llvm.sh安装的llvm全家桶只有具体的版本,而不是一个通用的符号链接,因此需要自己维护这个关系

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#!/bin/bash

# 定义要管理的LLVM工具
llvm_tools=(
"clang" "clang++" "clangd" "clang-format" "clang-tidy"
"llvm-ar" "llvm-as" "llvm-bcanalyzer" "llvm-cat" "llvm-config"
"llvm-cov" "llvm-cxxfilt" "llvm-diff" "llvm-dis" "llvm-dwarfdump"
"llvm-extract" "llvm-link" "llvm-lto" "llvm-mc" "llvm-nm"
"llvm-objcopy" "llvm-objdump" "llvm-opt-report" "llvm-profdata"
"llvm-ranlib" "llvm-readelf" "llvm-readobj" "llvm-rtdyld"
"llvm-size" "llvm-strings" "llvm-strip" "llvm-symbolizer"
"llvm-tblgen" "lld" "ld.lld"
)

# 查找最新的LLVM工具
find_latest_llvm() {
local tool_name=$1
# 使用find命令查找所有的可执行文件
local versions=$(find /usr/bin -name "${tool_name}-*" | grep -oE "${tool_name}-[0-9\.]+" | sort -V | tail -1)
echo "/usr/bin/${versions}"
}

# 更新update-alternatives
update_alternatives() {
local tool_name=$1
local latest_tool_path=$(find_latest_llvm ${tool_name})
if [ -z "$latest_tool_path" ]; then
echo "未找到${tool_name}的版本,跳过。"
return
fi

# 使用update-alternatives进行更新
sudo update-alternatives --install /usr/bin/${tool_name} ${tool_name} ${latest_tool_path} 100
sudo update-alternatives --set ${tool_name} ${latest_tool_path}
echo "${tool_name}已更新为${latest_tool_path}"
}

# 遍历所有的LLVM工具并更新
for tool in "${llvm_tools[@]}"; do
update_alternatives ${tool}
done

echo "所有LLVM工具均已更新完毕。"


clangd配置
https://yill-z.github.io/2025/01/01/clangd/
作者
Yill Zhang
发布于
2025年1月1日
许可协议