NeoVim 環境で C++ & CMake 環境を整えたい… for HDK

# はじめに

今回はゴリゴリの開発環境設定ネタ。

最近は特に Houdini のノードビルド環境を整えてきていて、CMake ツールも [NeoVim](https://neovim.io) + [LazyVim](https://www.lazyvim.org) 構成でサクッとインストールできるし、ｲｲｶﾝｼﾞ～～と思っていた。

しかしながら、実際にコーディングに移ってみると、C++ 側のコードリンクがうまく認識くれてなかったりして、これはどうしたものか…という混乱があった。

今回はそれを調査したのをまとめたい。

# どういう状況？

## インストール済み

* Visual Studio 2019
* CMake 3.27.0
* Houdini 20.5.410
    * 今回の環境故のもので、気にしなくてもいいです。

## 導入済みのプラグイン

* CMake
    * cmakelint
        * リンタ
    * cmakelang
        * ハイライトやフォーマッタ
    * neocmakelsp
        * LSP
* Clangd
    * C/C++ 用の LSP / インテリセンス / フォーマッタ

### 上記の導入方法

基本的にに NeoVim + LazyVim 構成であれば LazyExtras の `lang.cmake` と `lang.clangd` を有効にするだけで CMake/Clangd 関連のツールや LSP はインストールできる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51857/5ace6db0-0e72-620a-5e64-0efb7f49b384.png)

コンフィグだと、`lazy.lua` に次のように追加するだけ。

```diff_lua:lazy.lua
require("lazy").setup({
  spec = {
    -- 省略
+   { import = "lazyvim.plugins.extras.lang.clangd" },
+   { import = "lazyvim.plugins.extras.lang.cmake" },
    -- 省略
  },
}
```

## エラー状況

CMake Tools は正常に動いていて、CMakeLists.txt を編集していて保存してエラーがあれば警告してくるし、CMake コマンドでのビルド処理も問題なく実行できる。

NeoVim で CMake でビルド前提のプロジェクトを開いているが、次の様になっている。
リンクが通っておらず、かなりの数のエラーが出ている。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51857/76d4f62f-c395-5a66-ec4e-f023e945f8a2.png)

ヘッダファイルもこんな感じでエラーがでる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51857/4db1ddff-3c63-87f5-10d9-8df0d2a2a079.png)

### VSCode や Visual Studio の場合

これが、VSCode や Visual Studio で同じ環境状態から立ち上げるとちゃんとリンクも通っている。
ソース参照先もたどれる。もちろんビルドも通る。

ただ、違う点としてはこちらの場合は Clangd ではなく、Microsoft の CMake Tools と C/C++ 拡張がサポートしている様子のため。

| VSCode | Visual Studio |
|:-:|:-:|
|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51857/86f3e838-bee3-b366-470f-3ae7e1bf8221.png)|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51857/e6421a07-db58-bde4-8a23-af192c3389d1.png)|

# 原因を探る

考えうる原因としては　Clangd 側の扱いと CMake 側の扱いにミスマッチが起きていると想定。
Clangd 側が CMake 環境を想定しているわけでもないので、環境が CMake 側の生成したソリューションファイルにアクセスできていない？

ということで調べてみる。
なんかそれっぽいものがヒットした。

https://stackoverflow.com/questions/75694157/making-clangd-work-with-conan-cmake-clangd-cant-find-headers-outside-project

https://uchan.hateblo.jp/entry/2018/12/29/104132

どうやら、直接のコンパイルとは違い、CMake 環境の間接コンパイルだと clangd が認識してくれないっぽいという予想は当たっている様子。
で、対応としては、コンパイルオプションを `compile_commands.json` というコンフィグファイルを作ることで対応できるらしい。
また、ソリューション全体としては `compile_flags.txt` でも対応できるらしい。

ということで試してみる。

## `compile_commands.json` の生成

とりあえず、以下のコマンドを試してみる。

```powershell
mkdir build
cd build
cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON ..
```

あれ？？
`compile_commands.json` が生成生成されないぞ…？？？

ん～なんでだ。
他の環境でも同様の挙動なのかを試してみる。

### VSCode が行っている側のコマンドを見てみる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51857/98bacb41-0d3d-ccec-4802-d00d39097580.png)

```powershell
C:\Program Files\CMake\bin\cmake.EXE" -DCMAKE_EXPORT_COMPILE_COMMANDS:BOOL=TRUE --no-warn-unused-cli -SE:/Develop/Houdini/houdini-sop-volume-center-points -Be:/Develop/Houdini/houdini-sop-volume-center-points/build -G "Visual Studio 16 2019" -T host=x64 -A x64
```

ん～。やはり `-DCMAKE_EXPORT_COMPILE_COMMANDS:BOOL=TRUE` という事で有効にはしている様だ。
よくよく、生成された内部の構造を見てみると、やはりこちらも `compile_commands.json` は作成されていない様だ。

困った…。。

## 別のジェネレーターで試してみる

どうやら、Visual Studio をジェネレーター対象にすると動作しない様子？

なので、[Ninja](https://ninja-build.org) で試してみる。

```powershell
cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -G "Ninja" -B "build"
```

すると…でた！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51857/1900dcb2-ccce-16b0-3ce4-f08f1dbf57b8.png)

中身もなんかちゃんと書いてある！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51857/50224ff8-75b8-e32a-ff51-6b342b9d1ac5.png)


では、インテリセンスは効いているか？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51857/0cc1632f-79c2-3ab4-01c1-afc89e5711c2.png)

もともとのエラーとは打って変わって、認識は一応しているみたいだが、うまく効いていない様子… :thinking: 

## `compile_flags.txt` を試してみる

この方法はマニュアル記載になるので、なんだかなぁというのもあったが、背に腹は代えられぬという事で、試してみる。

```text:compile_flags.txt
-std=c++17
-I.
-IC:/Program Files/Side Effects Software/Houdini 20.5.410/toolkit/include
```

確認してみる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51857/29a06492-0656-a56c-5890-5e18f2ed97c4.png)

またエラーが変わった。どうやらこっちの方が `toolkit/include`  周りをちゃんと認識してくれている様子…。だが、多分、その `toolkit/include` から先が読みに行けていない様子。



# 現状の結論

なぜかうまくいってない！！
でもなんかあとちょっとな気がする…。。
今月中にはなんとかしたいw