思索的逍遥の記。

いろいろな考え事。

SpacemacsでC++17の入力補完をする(macOSの場合)

背景

最近、C++への再入門を試みている。何年も前に一度挑戦して挫折したのだが、RustやC言語を多少勉強した上で、今なら以前よりもC++のことを理解できるのではないかと思ったからだ。そして、せっかく再入門するのだから、新しめの仕様で勉強しようと思い、C++17を勉強することにした。

環境はmacOS Catalina、homebrewでgcc(バージョン9.3.0)をインストールしている。エディタはここ2年くらいSpacemacsを使っている。C/C++ layerがあるので、これを使おうと思った。

.spacemacsの設定

SPC f e d.spacemacsを開き、dotspacemacs-configuration-layersc-c++を付け足すのだが、その際多少設定を足す。

  • c-c++-default-mode-for-headersを'c++-modeに設定する:デフォルトでは.hファイルがCのヘッダファイルとして扱われるので、C++モードに変更する
  • c-c++-enable-clang-supportをtに設定するauto-completion layerを介して自動補完するために必要な設定

該当部分だけ抜き出すと下記のようになる。

dotspacemacs-configuration-layers
'(
  ...
  auto-completion
  syntax-checking
  (c-c++ :variables
         c-c++-default-mode-for-headers 'c++-mode
         c-c++-enable-clang-support t)
  ...
  )

llvmのインストール

上記までの設定ではコード補完が動作しない。ドキュメントを読むと、このlayerはデフォルトではバックエンドにlsp-clangdというものを使っている。lsp (Language Server Protocol) はコード補完のためにエディタをクライアント、言語環境をサーバーとして専用のプロトコルでやりとりさせるというものらしく、ここではC++コード補完用の言語サーバーとしてclangdが使われている。もちろんそんなものをインストールした記憶はないから、用意する必要がある。

clangd公式サイトで説明されているインストール方法を確認すると、macOSではbrew install llvmとだけすれば良いことがわかった。かなり楽だ。ただ、インストール直後に以下のようなメッセージが表示されるので、指示にしたがってパスを通す必要がある。自分は一番上のLDFLAGSの設定は無視して、他の3つを~/.zshrcに加えてパスを通した。

To use the bundled libc++ please add the following LDFLAGS:
  LDFLAGS="-L/usr/local/opt/llvm/lib -Wl,-rpath,/usr/local/opt/llvm/lib"

llvm is keg-only, which means it was not symlinked into /usr/local,
because macOS already provides this software and installing another version in
parallel can cause all kinds of trouble.

If you need to have llvm first in your PATH run:
  echo 'export PATH="/usr/local/opt/llvm/bin:$PATH"' >> ~/.zshrc

For compilers to find llvm you may need to set:
  export LDFLAGS="-L/usr/local/opt/llvm/lib"
  export CPPFLAGS="-I/usr/local/opt/llvm/include"

これでコード補完が動作するようになった。

.clang_completeファイルを書く

初めのうちは上記の設定で問題ないように感じていたが、肝心のC++17の機能に関して入力補完も効かないし、標準ライブラリに存在しないと怒られたりもするので、どうやら-std=c++17コンパイルオプションがコードチェックのツールに渡っていないようだった。

clangdGetting startedによると、compile_flags.txtというファイルにコンパイルオプションを一行につき一つ書いてプロジェクトのディレクトリにおいておくことで、それらのコンパイルオプションをコードチェック時に適用する。しかし今回はうまくいかなかった。

半ば諦めかけていたが、C/C++ layerのREADMEの下の方に、.clang_completeファイルを置くといい、と書いてあるのをやっと発見した。使い方はcompile_flags.txtと全く同じようだったので、とりあえず以下のように書いた。

-std=c++17
-Wall
--pedantic-errors

このように書いた.clang_completeをプロジェクトディレクトリ直下に置くと、ちゃんとC++17向けのコードチェック・コード補完が走るようになった。しばらくはこれで行きたいと思う。

参考文献