C++11サポートが必要になり、タイトルを行ったので、備忘録として残しておきます。
インストールディレクトリ
システムに入っているGCCと競合関係を起こすと非常に面倒なことになると思うので、他のソフトウェアとは異なる場所にインストールして、必要なときだけ使うという方法にします。
以下インストールディレクトリは/usr/local/src/gcc-4.9
として作業を進めていきます。
cd /usr/local/src
sudo mkdir gcc-4.9
suco chown USERNAME gcc-4.9
cd gcc-4.9
※ USERNAME
は適宜ご自身の名前に変更してください。
ダウンロードと依存関係
はじめに、ミラーサイトからソースコードをダウンロードします。
wget http://ftp.tsukuba.wide.ad.jp/software/gcc/releases/gcc-4.9.4/gcc-4.9.4.tar.gz
tar zxvf gcc-4.9.4.tar.gz
cd gcc-4.9.4
gcc4.9には以下の依存関係があります。
gcc 4.9
|- MPC 0.8.0+
|- MPFR 2.4.0+
|- GMP 4.2+
ですので、はじめに依存するライブラリをダウンロードします。
(はじめは、すべて手作業で行っていたのですが、)これを行うには./contrib/download_prerequisites
を実行するだけのようです。
./contrib/download_prerequisites
インストール
はじめに、Makefileを作ります。
./configure --prefix=/usr/local/src/gcc-4.9 --with-local-prefix=/usr/local/src/gcc-4.9 --program-suffix=4.9 --host=x86_64-redhat-linux --build=x86_64-redhat-linux --target=x86_64-redhat-linux --enable-languages=c,c++,fortran --disable-multilib
各オプションの意味は以下の通りです。
オプション | |
---|---|
--prefix |
インストール先のディレクトリ |
--with-local-prefix |
他のバージョンのGCCがいる環境でインストールするときは指定したほうが良いみたいです。(参考) |
--program-suffix |
生成されるバイナリのサフィックスです。システムのGCCと区別するために今回は4.9 としました。 |
--host |
指定しない場合は、x86_64_unknown-linux が使われました。(あえて指定する必要もないかもしれません) |
--build |
--host と同じ |
--target |
--host と同じ |
--enable-languages |
今回はJavaはいらないので、このようになりました。 |
--disable-multilib |
デフォルトだと32bitと64bit両方のバイナリが作成されてしまうので、ここでは64bitのみとしました。 |
あとは、以下のコマンドでインストールしました。
make
make install
make
には当方環境ではおよそ2時間かかりました。
また、本当は、make check
したかったのですが、autogen
コマンドが見つからないといわれてしまいできませんでした。
あれ、もしかして、案外簡単?
テスト
簡単なテストを行ってみます。
https://kaworu.jpn.org/cpp/C++11にあるC++11でないと動かないサンプルコード
#include <iostream>
using namespace std;
class C {
int i;
public:
C (int ia) : i(ia) {}
C () : C (123) {}
};
int main(int argc, char const* argv[])
{
C c;
return 0;
}
をfoo.cc
という名前で保存して、コンパイルしてみます。
/usr/local/src/gcc-4.9/bin/g++4.9 -std=c++11 foo.cc
無事、コンパイルできて、実行もエラーなくできました。
通常ですと、https://qiita.com/qiitamatumoto/items/c2de3f976b86f21ce2a6でも言われているように、LD_LIBRARY_PATHにインストールしたGCCが入っていない状態だと、リンカーがリンク先を間違えてしまう問題が発生してしまいますが、そのような現象がおきていません。
--with-local-prefix
を指定すると、上記の問題は自動的に回避されるのでしょうか。
よくわかりませんが、動いたので、ひとまず良かったということにします。
生成されたバイナリのリンクを確認すると、
$ ldd a.out
linux-vdso.so.1 => (0x00007ffcca195000)
libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00007f7228641000)
libm.so.6 => /lib64/libm.so.6 (0x00007f72283bc000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f72281a6000)
libc.so.6 => /lib64/libc.so.6 (0x00007f7227e12000)
/lib64/ld-linux-x86-64.so.2 (0x00007f7228965000)
となり、リンク先がシステム標準のGCCライブラリを指しており間違っています。
やはり、明示的にGCC4.9のライブラリを指すように指示する必要があるようです。
そこで、-Wl,-rpath
を指定してコンパイルすると、
$ /usr/local/src/gcc-4.9/bin/g++4.9 -std=c++11 -Wl,-rpath=/usr/local/src/gcc-4.9/lib64 foo.cc
$ ldd a.out
linux-vdso.so.1 => (0x00007fffe0d62000)
libstdc++.so.6 => /usr/local/src/gcc-4.9/lib64/libstdc++.so.6 (0x00007feb412ab000)
libm.so.6 => /lib64/libm.so.6 (0x00007feb41009000)
libgcc_s.so.1 => /usr/local/src/gcc-4.9/lib64/libgcc_s.so.1 (0x00007feb40df3000)
libc.so.6 => /lib64/libc.so.6 (0x00007feb40a5f000)
/lib64/ld-linux-x86-64.so.2 (0x00007feb415be000)
となり、無事正しいGCC4.9のライブラリを指すようになりました。