概要
C/C++でlspを使用します。 以前、clangdを試用したのですが、あまり良くなかったのでC/C++では無効にして、gtags(GNU Global)を使っていました。 最近Cのソースを読むことが多くなったので、再度検討してみます。
下記では複数lspのフロントエンドとC/C++向けのバックエンド(サーバー)の組み合わせの比較をされており、参考になりました。
My Hakyll Blog - EmacsでのC/C++開発
確かに、clangdは重すぎて使い物にならなかった気がします。 バックエンドとしてcclsを使うのが良さそうですのでこちらにトライします。
$ sudo apt list | grep ccls ccls/jammy 0.20210330-1 amd64
Ubuntuでのビルド及びインストール
依存するパッケージをインストールします。
sudo apt install clang libclang-dev zlib1g-dev libncurses-dev rapidjson-dev
インストールされたclangのバージョンを確認します。私の環境(Ubuntu 22.04)ではllvm-14でした。
$ ls /usr/lib/ | grep llvm llvm-14
ソースをクローンします。
git clone --recursive https://github.com/MaskRay/ccls
ビルドします。前述の通り確認したバージョンを指定します。
cd ccls
cmake -S. -BRelease -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH=/usr/lib/llvm-14
cmake --build Release
生成されたバイナリの置き場を指定して使用することも可能ですが、ここでは、生成されたバイナリを ~/bin/ にコピーして使用します。
mkdir -p ~/bin cp ./Release/ccls ~/bin/
init.elの設定
(use-package ccls :ensure t :hook ((c-mode c++-mode objc-mode cuda-mode) . (lambda () (require 'ccls) (lsp)))) (setq ccls-executable "~/bin/ccls") (setq ccls-args '("--init={\"cache\": {\"directory\": \"/tmp/ccls-cache\"}}"))
プロジェクト毎の設定
lspとしてのプロジェクトのルートディレクトリに .ccls ファイルを置くことでコンパイルコマンド、インクルードパスや定義済みマクロを指定することができます。
例えば下記の様に記載します。
clang -Iinclude -D__GLIBC__
M-x lsp-workspace-restart を行うことで、設定変更内容を反映させることができます。