C/C++ で Emacs lsp-mode (ccls)

概要

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 を行うことで、設定変更内容を反映させることができます。

Copied title and URL