LoginSignup
1
1

More than 5 years have passed since last update.

C++17 を試そう(最新の GCC を使うための環境構築方法(GCC 6.1 版))

Posted at

本稿について

Linux ディストリビューションで C++17(C++1z) に対応し始めた GCC 6.1 を野良ビルドしてインストールするための手順です.
「std::invoke 使わせろ」とか「もういちいち -std=gnu++14 するの面倒なんだけど」とか,新しいコンパイラを使いたいんだけど root のパスワード知らないし...という人もどうぞ.

インストール先ディレクトリ

今回ビルドするファイル全てを /opt/gcc/6.1 にまとめて入れることとします.
よって,ビルド後のライブラリ一式は /opt/gcc/6.1/lib に,GCC の実行ファイルは /opt/gcc/6.1/bin に入ります.
root になれない人は適当なディレクトリで構いませんが,ldconfig が使えないので環境変数 LD_LIBRARY_PATH などで liblib64 ディレクトリを指定する必要があります.~/.zshrc などに書いておきましょう.(具体的な設定は後述)

準備するもの

Prerequisites for GCC を見てもらえれば良いのですが,一般的な Linux のシステムでは大半がすでに入っています.

追加で必要なモノは大体以下のものでしょう.

  • C++98 が使えるビルドチェイン
  • GNU Multiple Precision Library(GMP) 4.3.2+
  • MPFR Library 2.4.2+
  • MPC Library 0.8.1+
  • isl Library 0.14+(0.15+ が良い)

必要なアーカイブ

インストールの流れ

  1. ldconfig の設定
  2. ライブラリのビルド&インストール
  3. GCC のビルド&インストール

今回は 16 個の論理プロセッサを積んだマシンを使っているので -j16 していますが,ここは環境に合わせてください.

ldconfig の設定

各種ライブラリをインストールするにあたり,ldconfig から共有ライブラリを見つけてもらえるようにする必要があります.
/etc/ld.so.conf.d/ 内にディレクトリエントリを作り,これからインストールするライブラリ一式を入れるディレクトリが ldconfig から見えるようにしましょう.

root になれない方は ldconfig の設定ができないので,本手順の代わりにこれから configure で指定する --prefix に指定するディレクトリ内の liblib64 ディレクトリを環境変数 LD_LIBRARY_PATH に設定してください.

$ sudo vi /etc/ld.so.conf.d/gcc61.conf
/etc/ld.so.conf.d/gcc61.conf
/opt/gcc/6.1/lib
/opt/gcc/6.1/lib64
LD_LIBRARY_PATHの設定(rootになれない人向け)
GCC61_HOME=/path/to/prefix
export LD_LIBRARY_PATH=${GCC61_HOME}/lib:${GCC61_HOME}/lib64

まだ ldconfig しなくても良いです.

各種ライブラリのビルドとインストール

依存関係があるので順番を守りましょう.
また,各ライブラリのインストール後には ldconfig を実行しましょう.
root 持っていない方は --prefix に自分が書き込めるディレクトリを指定してください.この場合はもちろん sudo は不要です.

GMP

$ tar --lzip -xf gmp-6.1.1.tar.lz
$ cd gmp-6.1.1
$ ./configure --prefix=/opt/gcc/6.1
$ make -j16
$ sudo make install
$ sudo ldconfig
$ make clean

MPFR

$ tar Jxf mpfr-3.1.4.tar.xz
$ cd mpfr-3.1.4
$ ./configure --prefix=/opt/gcc/6.1 --with-gmp=/opt/gcc/6.1
$ make -j16
$ sudo make install
$ sudo ldconfig
$ make clean

MPC

$ tar zxf mpc-1.0.3.tar.gz
$ cd mpc-1.0.3
$ ./configure --prefix=/opt/gcc/6.1 --with-gmp=/opt/gcc/6.1 --with-mpfr=/opt/gcc/6.1
$ make -j16
$ sudo make install
$ sudo ldconfig
$ make clean

isl

$ tar Jxf isl-0.17.tar.xz
$ cd isl-0.17
$ ./configure --prefix=/opt/gcc/6.1 --with-gmp-prefix=/opt/gcc/6.1
$ make -j16
$ sudo make install
$ sudo ldconfig
$ make clean

isl のインストール後に ldconfig で下記のようなメッセージが出ますが,無視して良いです.

/sbin/ldconfig.real: /opt/gcc/6.1/lib/libisl.so.15.2.0-gdb.py is not an ELF file - it has the wrong magic bytes at the start.

GCC のビルドとインストール

C++17 を使うためには C++ があれば良いのですが,僕は C と Fortran,ついでに LTO サポートも欲しいので --enable-languages でこれらを指定します.

$ tar jxf gcc-6.1.0.tar.bz2
$ cd gcc-6.1.0
$ ./configure --prefix=/opt/gcc/6.1 --with-gmp=/opt/gcc/6.1 --with-mpc=/opt/gcc/6.1 --with-mpfr=/opt/gcc/6.1 --with-isl=/opt/gcc/6.1 --disable-multilib --enable-languages=c,c++,fortran,lto
$ make -j16
$ sudo make install
$ sudo ldconfig
$ make clean

ここでも ldconfig 時に下記のようなメッセージが出ますが,無視して良いです.

/sbin/ldconfig.real: /opt/gcc/6.1/lib64/libstdc++.so.6.0.22-gdb.py is not an ELF file - it has the wrong magic bytes at the start.

【参考】GCC のビルドって時間がかかるんだけど...

ビルド時間を短縮するとかいう理由のためだけに --disable-bootstrap を付けることを勧める記事をよく見ますが,メジャーバージョン(4.x → 4.y など)が上がるときは bootstrap ビルドをしておいた方が安全です.ABI の変更など致命的な問題が影響することがあります.
マイナバージョンを上げるとき(4.6.x → 4.6.y など)はまぁ bootstrap による確認は不要でしょう.

さぁできた

サンプルコードを書いて,std::invoke できるか確認してみましょう.
std::invoke を叩きたいだけなので,色々手抜きしています)

sample.cpp
#include <iostream>
#include <functional>

class Hoge
{
private:
  int base;

public:
  Hoge(int x)
  {
    this->base = x;
  }

  int count_up()
  {
    return ++this->base;
  }

  void change_base(int x)
  {
      this->base = x;
  }
};

int count_up()
{
  int base = 100;
  return ++base;
}


int main(int argc, char **argv)
{
  Hoge h(0);
  std::cout << h.count_up() << std::endl;

  std::cout << std::invoke(&count_up) << std::endl;

  Hoge h1(100);
  std::cout << std::invoke(&Hoge::count_up, h1) << std::endl;

  Hoge h2(200);
  std::cout << std::invoke(&Hoge::count_up, h2) << std::endl;

  auto &h3 = h1;
  h3.change_base(300);
  std::cout << std::invoke(&Hoge::count_up, h1) << std::endl;
  std::cout << std::invoke(&Hoge::count_up, h3) << std::endl;

  auto h4 = h1;
  h4.change_base(400);
  std::cout << std::invoke(&Hoge::count_up, h1) << std::endl;
  std::cout << std::invoke(&Hoge::count_up, h4) << std::endl;


  return 0;
}
ビルド
$ /opt/gcc/6.1/bin/g++ sample.cpp --std=gnu++17
実行結果
$ ./a.out
1
101
101
201
301
302
303
401

まとめ

新しいコンパイラや実行環境は気軽に試すことができるので,どんどん使って筋トレしましょう.

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1