nvim + coc.nvimでC23の環境を整える
環境
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));
}
環境構築
ビルド
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にまとめる
.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
を利用するように設定。
{
"clangd.path": "/opt/homebrew/opt/llvm/bin/clangd"
}
c++のコードが置かれているディレクトリの直下に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 で入れたバイナリを優先的に利用出来る。
既存のバイナリを消したくはないが優先的に新しいバイナリを利用したい場合などに利用できる。
Discussion