🔥

nvim + coc.nvimでC23の環境を整える

2024/01/23に公開

環境

CPU : Apple M1 Max
メモリ : 64GB
OS : macOS 13.2.1

現状確認

デフォルト(?)ではApple clangという独自のものが入っていてこれは c++23 のオプションが使えない

$ g++ -v
Apple clang version 14.0.0 (clang-1400.0.29.202)
Target: arm64-apple-darwin22.3.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
$ g++ -o main -std=c++23 main.cpp
error: invalid value 'c++23' in '-std=c++23'
note: use 'c++98' or 'c++03' for 'ISO C++ 1998 with amendments' standard
note: use 'gnu++98' or 'gnu++03' for 'ISO C++ 1998 with amendments and GNU extensions' standard
note: use 'c++11' for 'ISO C++ 2011 with amendments' standard
note: use 'gnu++11' for 'ISO C++ 2011 with amendments and GNU extensions' standard
note: use 'c++14' for 'ISO C++ 2014 with amendments' standard
note: use 'gnu++14' for 'ISO C++ 2014 with amendments and GNU extensions' standard
note: use 'c++17' for 'ISO C++ 2017 with amendments' standard
note: use 'gnu++17' for 'ISO C++ 2017 with amendments and GNU extensions' standard
note: use 'c++20' for 'ISO C++ 2020 DIS' standard
note: use 'gnu++20' for 'ISO C++ 2020 DIS with GNU extensions' standard
note: use 'c++2b' for 'Working draft for ISO C++ 2023 DIS' standard
note: use 'gnu++2b' for 'Working draft for ISO C++ 2023 DIS with GNU extensions' standard

インストールされているPATHからしてhomebrewで入れたものでは無さそうなので出来るだけ削除はしたくない[1]

$ whereis g++
g++: /usr/bin/g++

c++の Language Server である clangd も同様

$ clangd --version
Apple clangd version 14.0.0 (clang-1400.0.29.202)
Features: mac+xpc
Platform: x86_64-apple-darwin22.3.0; target=arm64-apple-darwin22.3.0

この状態を改善して c++23 のビルドが出来、Language server の恩恵を受けられるような状態を目指す

$ whereis clangd
clangd: /usr/bin/clangd

サンプルコード

c++23の動作確認用コード

#include <expected>
#include <iomanip>
#include <iostream>
#include <string>

// 整数除算
std::expected<int, std::string> idiv(int a, int b)
{
  if (b == 0) {
    return std::unexpected{"divide by zero"};
  }
  if (a % b != 0) {
    return std::unexpected{"out of domain"};        
  }
  return a / b;
}

void dump_result(const std::expected<int, std::string>& v)
{
  if (v) {
    std::cout << *v << std::endl;
  } else {
    std::cout << std::quoted(v.error()) << std::endl;        
  }
}

int main()
{
  dump_result(idiv(10, 2));
  dump_result(idiv(10, 3));
  dump_result(idiv(10, 0));
}

[2]

環境構築

ビルド

homebrewを使ってgccをインストール

brew install gcc

/opt/homebrew/bin 下にg++-13という名前でg++が入る

$ whereis g++-13
g++-13: /opt/homebrew/bin/g++-13

version 確認

$ g++-13 --version
g++-13 (Homebrew GCC 13.2.0) 13.2.0
Copyright (C) 2023 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

この時点で下記コマンドでビルドは出来る

g++-13 -o main -std=c++23 main.cpp

面倒なのでMakefileにまとめる

Makefile
.DEFAULT_GOAL := help

build: ## build binary
    g++-13 -std=c++23 -o main main.cpp

help: ## Show options
    @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | \
            awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-20s\033[0m %s\n", $$1, $$2}'

これにより

make build

でビルド出来るようになる

Language Server

language serverのホストとしてcoc-nvimを利用しているためこちらからclangdを呼び出したい
最もてっとり早い方法としてはcoc-clangdという拡張機能をインストールする

CocInstall coc-clangd

しかし、これはデフォルトだと既にPATHが通っている古いclangdを呼びだしてしまうため、c++23の機能は使えない。
まずは新しいclangdをインストール
おそらく最もてっとり早い方法はhomebrewでインストール出来るllvmに付属しているg++を使う方法。

brew install llvm

これにより/opt/homebrew/opt/llvm/bin/ 下にclangdもインストールされる。
coc-settings.jsonに下記を追加してllvmに付属したclangdを利用するように設定。

coc-settings.json
{
  "clangd.path": "/opt/homebrew/opt/llvm/bin/clangd"
}

c++のコードが置かれているディレクトリの直下にcompile_flags.txtを置いて完成

compile_flags.txt
-std=c++23

cppのファイルを開いた時点で補完等のLanguage Serverの機能が働いていればOK

Tips

今回は採用しなかったがPATH は先に読み込んだものから順に検索を行い、指定したバイナリが見つかった時点でそれを利用するので.bashrcなどで PATH を設定する際に

export PATH=/opt/homebrew/bin:/opt/homebrew/opt/llvm/bin:$PATH:

のようにしてデフォルトの PATH より前に homebrew や llvm の bin を指定しておけばデフォルトの g++や clangd も残したまま homebrew で入れたバイナリを優先的に利用出来る。
既存のバイナリを消したくはないが優先的に新しいバイナリを利用したい場合などに利用できる。

脚注
  1. もしかしたらxcode周りの環境を整えた時についでに入ってきたものかも。それであれば削除しても再インストールも簡単そうなので大丈夫かも。要確認。 ↩︎

  2. 参考 ↩︎

GitHubで編集を提案

Discussion