g++でfilesystem使おうとしたらそんなものはないと言われた

以下のコードのコンパイルが通らなかった(プリプロセスでつまずいた)話。

#include <iostream>
#include <filesystem>
using namespace std;
using namespace std::filesystem;

int main() {
    cout << current_path() << endl;
}
$ g++ -std=c++17 ./main.cpp -lstdc++fs
./main.cpp:2:10: fatal error: filesystem: そのようなファイルやディレクトリはありません
 #include <filesystem>
          ^~~~~~~~~~~~
compilation terminated.

なぜ

g++ コマンドの実態をたどってみると、どうやら g++-7 というものが使用されてる。

$ readlink -f $(which g++)
/usr/bin/x86_64-linux-gnu-g++-7

g++-7 では filesystem ヘッダは実験的な実装として experimental ディレクトリ内に存在し、プログラム的には std::experimenta::filesystem という名前空間になる。

以上を踏まえた g++-7 向けのソースファイル。

#include <iostream>
#include <experimenta/filesystem>
using namespace std;
using namespace std::experimenta::filesystem;

int main() {
    cout << current_path() << endl;
}

g++-8 をインストールしよう

やっぱり experimenta を使用するのはなんだか気持ち悪い。
g++-8 では experimenta が必要ないらしいのでそっちに乗り換えてみる。

インストール

一応 gcc-8 も一緒にインストールしておく。
下記コマンドを実行して待つべし。

ちなみに gcc-7 や g++-7 と共存できるらしいので、別にアンインストールする必要なし。

sudo apt install gcc-8 g++-8

gcc コマンドと g++ コマンドをそれぞれ -8 系に切り替える

gcc-8 と g++-8 をインストールしたが、 gcc コマンドや g++ コマンドの参照先はいまだに -7 系。

ubuntuではこれらの管理に update-alternatives コマンドを使うらしい。
alternativesについてはこちらを参考にした。

--slave オプションを使用することで、 gcc-7 を使用する場合は g++-7 を、gcc-8 を使用する場合は g++-8 を自動選択させる用にしている。

$ sudo update-alternatives --install $(which gcc) gcc $(which gcc-7) 7 --slave $(which g++) g++ $(which g++-7)
$ sudo update-alternatives --install $(which gcc) gcc $(which gcc-8) 8 --slave $(which g++) g++ $(which g++-8)

gcc/g++のバージョンを変更する場合は以下のコマンドを実行し、自分の使用したバージョンを指定する。

$ sudo update-alternatives --config gcc