2023 更新。
clang16
+ vc
の環境で試した。
clangd の起動設定
"--enable-config" // .clangd 設定を有効化する
"--header-insertion=never" // 好みで
"--clang-tidy" // 好みで
"--compile-commands-dir=builddir" // 👈 compile_commands.json の場所を示す
vscode
{
"clangd.arguments": [
"--compile-commands-dir=${workspaceFolder}/build",
"--header-insertion=never",
"--clang-tidy",
"--enable-config",
],
}
これは clangd の設定ではないので利きません。
"C_Cpp.default.compileCommands": "builddir\\compile_commands.json",
project local で clangd.arguments 上書きすると右下にメッセージが出てくる。
Yes, use this setting
する。
nvim
lspconfig.clangd.setup {
cmd = {
"path_to_clangd",
"--compile-commands-dir=FULLPATH_TO_DIR", -- 👈 fullpath が必要かもしれない
"--header-insertion=never",
"--clang-tidy",
"--enable-config",
},
}
compilation database (compile_commands.json)
clangdの起動オプション --compile-commands-dir=
必要
cmake や meson や bear で compile_commands.json を生成して、
それにより clangd のコンパイルフラグを決めることができる。
clangd では compilation database (compile_commands.json) を使う場合と
使わない場合で一部の設定が排他になっている感じ。
compile_flags.txt
, fallbackFlags
が compilation database と共存できない。
compile_commands.json に記述の無い header ファイルは適当に infer してくれる。
# header を check したときの verbose log
Compile command inferred
できるが header
に対するコンパイルフラグの決定に問題を抱えている、
ような気がする。特に Windows MSVC で使う場合。
具体的には -std=c++14
になってしまって、快適でない。
cmake
- CMake を使うときに
compile_commands.json
を出力させるには-
-DCMAKE_EXPORT_COMPILE_COMMANDS=1
出力設定 -
-G Ninja
を指定。(Windowsデフォルトの MSBuild にその機能が無い。Makefile か Ninja ならば Ninja であろう)
-
meson
自動生成
make
bear で生成する?。やったことない
compilation database を使わないときに有効になる設定
諦めてこっちで設定するのもありかも。特に msvc 環境。
--compile-commands-dir=
起動オプションを削除。
compile_flags.txt
fallbackFlags
vscode
"clangd.fallbackFlags": [
"-std=c++20"
],
nvim
init_options
トラブル
cl.exe
と clang-cl.exe
で受け付けるオプションが微妙に違う。
要するに -std=c++17
が通らずに /std:c++17
にする必要がある(clangd16)。
meson で cpp_std=c++latest
形式で設定していた。
直接コマンドラインを指定していないので、ビルド設定から修正できない。
cmake でも同様の問題が起きそう。
この現象は、 header
のコマンドラインを推論したときだけに発生するらしく
ヘッダーで c++17
以降の string_view
などを include するとエラー表示になって使いづらくなる。
これを prject_root/.clangd
設定で修正できる。
clangd の起動オプション --enable-config
必要。
CompileFlags:
Remove: [-std=c++latest]
Add: ["/std:c++latest"] # 👈 ダブルクォートしないと yaml のシンタックス違反になるぽい
header を直接開いたときは効くのだが、
goto definition 移動したときは効かないなど、経路によって効いたり効かなかったり・・・。
unknown type name ‘namespace’
デバッグ
以下のようなコマンドラインで動作を確認できる。
"C:/Program Files/LLVM/bin/clangd.exe" --compile-commands-dir=builddir --check=source_or_header --enable-config
見るべきポイントは、
- 設定が読まれているか
- エラーメッセージ全般
-
internal (cc1) args are
で-std=c++14
になっているか
など。
I[03:33:32.829] argv[0]: C:/Program Files/LLVM/bin/clangd.exe
I[03:33:32.829] argv[1]: --compile-commands-dir=builddir
I[03:33:32.829] argv[2]: --check=source_or_header
I[03:33:32.830] argv[3]: --enable-config
I[03:33:32.830] argv[4]: --log=verbose
V[03:33:32.834] User config file is %LOCALAPPDATA%\clangd\config.yaml
V[03:33:32.835] config note at .clangd:1:0: Parsing config fragment
E[03:33:33.193] [typename_nested_not_found] Line 18: no type named 'string_view' in namespace 'std'
E[03:33:33.193] [no_member_template] Line 24: no template named 'span' in namespace 'std'
さらに --log=verbose
をつけることでヒントが見つかる場合がある。
Ignored diagnostic. unknown argument ignored in clang-cl: '-std=c++latest'
clangd 設定
- ユーザー設定
%LOCALAPPDATA%/clangd/config.yaml
- コマンドライン(Editorのclangd起動設定)
- compilation database(compile_commands.json)
--compile-commands-dir=
- プロジェクト設定(
PROJECT_ROOT/.clangd
)--enable-config