Ubuntu 18.04にc++20のために最新のg++, Cmake, Boostを導入
まだ正式規格が出てないc++20だが,既に一部の機能はコンパイラに実装されている.
ここでは,正式規格が出てきても問題なくアップデートできる,ストレスフリーに環境を更新できるc++20開発環境の導入手順を示します.
目標
- すべてのソフトウェアは「継続的に更新」できること: 例
git repository
を用いて最新のものを追う - いつでももとの環境に戻せる状態であること: 既存の環境を覆い隠すが,そのまま残す(/usr/localを用いる)
- g++を最新版に置き換えはしない: コンパイラは環境変数
CXX
,CC
あるいはcmake
実行時に渡してもらう - CmakeLists.txtで
CXX_STANDARD 20
の指定でc++20
を有効にする. - CmakeLists.txtで単に
find_package(Boost)
と指定することで導入した(最新の)Boostを探し当てる. - システムインストールなのでソースコードのディレクトリ位置には依存しない.
gcc 最新版を入手
最新のgccは単一のppaで追いかけることができます。
ちなみに依存関係で自動的にc++20用標準ライブラリも手に入ります。
sudo add-apt-repository ppa:ubuntu-toolchain-r/test
sudo apt update
sudo apt install -y g++-9
ここでインストールするg++のバージョンはその時の最新にするのが良いです。g++-9の前提でこれから先書いていますが、適宜読み替えてください
gcc 環境設定
環境変数CXXとCCを定義して、g++-9をデフォルトで使ってもらいやすくしておきます。
echo "export CXX='g++-9'" >> ~/.bashrc
echo "export CC='gcc-9'" >> ~/.bashrc
ここまでできたら一度端末をすべて閉じて開きなおし、CXXとCCを定義させます。
gcc インストール確認方法
g++-9 --version
で何か表示される。失敗しているとコマンドが見つからないと言われます。
Cmake 最新版をインストール
CMakeのGit repositoryについて、githubはミラーで、https://gitlab.kitware.com/cmake/cmake
が真の本体となっています
せっかくなのでオリジナルを利用しましょう
git clone https://gitlab.kitware.com/cmake/cmake.git
cd cmake
./bootstrap
make -j5
sudo make install
CXXとCCを判別するので、環境変数が適切にセットされていれば最新のコンパイラでコンパイルできます
Cmake インストールチェック
cmake --version
上のコマンドが正しく動作することを確認してください。
CMakeのバージョンは適切か確認します。 cmake version 3.16.20191223-g20e0d3c
のような形式をしているので、数日以内の更新のバージョンを使っていればOKです
CMakeが対応しているBoostのインストール
CMakeが対応しているバージョンを調べる
先程ダウンロードしたCMakeのFindBoostModuleのコードを調査します
# cd cmake
grep -n -A 2 _Boost_KNOWN_VERSIONS Modules/FindBoost.cmake
その結果、例えば以下のような結果が帰ってくる
> grep -n -A 2 _Boost_KNOWN_VERSIONS Modules/FindBoost.cmake
1431: set(_Boost_KNOWN_VERSIONS ${Boost_ADDITIONAL_VERSIONS}
1432- "1.72.0" "1.72" "1.71.0" "1.71" "1.70.0" "1.70" "1.69.0" "1.69"
1433- "1.68.0" "1.68" "1.67.0" "1.67" "1.66.0" "1.66" "1.65.1" "1.65.0" "1.65"
--
1447: foreach(version ${_Boost_KNOWN_VERSIONS})
1448- if(NOT "${version}" VERSION_LESS "${Boost_FIND_VERSION}")
1449- # This version is high enough.
--
1459: set(_boost_TEST_VERSIONS "${_Boost_KNOWN_VERSIONS}")
1460- endif()
1461-endif()
通常は一番先頭のバージョンが対応する最も高いバージョンとなっています。ここでは1.72.0
となるため、以後の説明ではこのバージョンを用いますが、適宜読み替えてください。
Boostのダウンロードとインストール
BoostはGit repositoryからコンパイルして用います
先に言っておくとダウンロードにもコンパイルにも相当時間がかかります
git clone https://github.com/boostorg/boost.git
他のソフトウェアと違ってBoostのバージョンは常に最新とは行きません、先程調査したCMake対応の最新バージョンに切り替えます
cd boost
git checkout boost-1.72.0 # Please replace with your latest version
git submodule update --init
./bootstrap.sh
./b2 toolset=gcc-9 --prefix=/usr/local -j5
sudo ./b2 install toolset=gcc-9 --prefix=/usr/local -j5
コンパイル時にはtoolset=gcc-9
を指定して、最新のコンパイラで処理します
CXXやCCは適用されないので明示的に適用する必要があります
途中warningが大量に出ますが、std::auto_ptrやunused valueが騒いでいるだけです。Boostはあらゆるバージョン向けのコードが入っているので気にしないでください
j オプションの引数5は並列処理数です。CPUの論理コア数+1にして全く他の仕事をしなければ全力でコンパイルしてくれます。速度が段違いなので論理コア数をきちんと調べて指定すると良いです。
途中に入っているgit submodule
は必須です。もしアップデートするならgit submoduleを適切に使ってアップデートするか、boostのディレクトリを削除してこの手順をやり直してください。
動作確認
適当なディレクトリを作って、コンパイルを試します。
まずはディレクトリにCMakeLists.txtとmain.cppを作成します。
- CMakeLists.txt
- main.cpp
cmake_minimum_required(VERSION 3.16)
project(test)
find_package(Boost REQUIRED COMPONENTS system)
find_package(Threads REQUIRED)
include_directories(Boost::boost)
add_executable(main main.cpp)
target_link_libraries(main Boost::system Threads::Threads)
set(TARGETS main)
set_property(TARGET ${TARGETS} PROPERTY CXX_STANDARD 20)
set_property(TARGET ${TARGETS} PROPERTY CXX_STANDARD_REQUIRED ON)
set_property(TARGET ${TARGETS} PROPERTY CXX_EXTENSION OFF)
#include <iostream>
#include <string_view>
#include <boost/asio.hpp>
int main(int argc, char** argv)
{
namespace asio = boost::asio;
using asio::ip::tcp;
asio::io_service io_service;
tcp::socket socket(io_service);
boost::system::error_code error;
socket.connect(tcp::endpoint(asio::ip::address::from_string("127.0.0.1"), 31400), error);
if (error)
std::cout << "connect failed : " << error.message() << std::endl;
else
std::cout << "connected" << std::endl;
}
ファイルを準備したらcmakeでコンパイルします。
cmake .
make
無事コンパイルできれば全てのインストールと設定は終了です。
#include <string_view>
がエラーを吐いた場合はg++-9の設定がおかしいです。
Cmakeがboostライブラリを見つけたが、warnを吐いている場合はお使いのCMakeが最新のBoostに対応していません。Boostのバージョンを下げて再インストールすることで対応しましょう
また、使用したCMakeが最新のものでは無かった可能性もあります。cmake --version
で確認してください
以上で全てのインストール作業は終わりです。
Uninstall method
アンインストールするには、次のようにrmで削除してしまいます。
cd /usr/local
sudo rm -f bin/cmake bin/cpack bin/ctest
sudo rm -rf share/cmake-3.16 # fix with your version
sudo rm -f lib/libboost*
sudo rm -rf include/boost
sudo apt remove g++-9
また、 .bashrc に設定が2つあるので、テキストファイルで開いて最後の方を見て
export CXX='g++-9'
export CC='gcc-9'
この2行をまるまる削除すればアンインストール完了です
元の環境に戻っています
Update method
gcc
sudo apt update
sudo apt upgrade
あるいは新しいgccが出た場合は、インストールメソッドに従って最新版をインストールする
CMake
cd cmake
git clean -fdx
git pull
./bootstrap --prefix=/usr/local
make -j5
sudo make install
Boost
まずは更新したCMakeに対応するBoostのバージョンを調べ直す
# cd cmake
grep -n -A 2 _Boost_KNOWN_VERSIONS Modules/FindBoost.cmake
続いて、submoduleの扱いに十分に慎重になりながら作業をする
cd boost
git submodule deinit . # IMPORTANT this line at FIRST
git clean -fdx
git fetch # not pull. you need fetch
git checkout boost-1.72.0 # Please replace with your latest version
git submodule update --init # IMPORTANT --init option. must use.
./bootstrap.sh
./b2 toolset=gcc-9 --prefix=/usr/local -j5
sudo ./b2 install toolset=gcc-9 --prefix=/usr/local -j5
コツは、何かをする前にgit submodule deinit .
を実行することです。忘れて移動してしまうと面倒なことになります。その場合は(わかっているなら.git
以外をすべて消して復元してもいいが)インストール手順をやり直すほうが早いと思います
最後に
この手順はc++20等関係なく、これから先gccかCMakeかBoostが滅びるまでそのまま適用できるはずなので、継続的に環境を更新していってくださいませ。