C++11 が使えない?最新の GCC 使えばいいじゃない!
sudo 権限がないからインストールできない?ビルドすればいいじゃない!
はい。C++11 が使えないのはちょっと人権がないと思うので、そのためだけに GCC の最新版をビルドしてみました。まぁ、ほぼマニュアル通りに実行しただけなので、つまずいた所とかをメモ書き程度に。
uda@host:~$ uname -srmo
Linux 2.6.32-5-amd64 x86_64 GNU/Linux
uda@host:~$ cat /etc/debian_version
6.0.6
uda@host:~$ /usr/bin/gcc --version
gcc (Debian 4.4.5-8) 4.4.5
Copyright (C) 2010 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.
準備
まず、Prerequisites for GCC を参考に、必要なライブラリ等を先にインストールしておきます。私の場合、GMP とかが必要でした。
次に、GCC のソースを GCC Releases からダウンロードしてきます。今回は gcc-4.7.2.tar.gz
を使いました。SVN 版もあります。
(必要なら展開して)ソースの置いてあるディレクトリを srcdir
とします。
uda@host:srcdir$ ls
ABOUT-NLS Makefile.tpl fixincludes libiberty ltsugar.m4
(略)
ChangeLog.tree-ssa config.guess libcpp libstdc++-v3 move-if-change
INSTALL
configure
ビルド作業用のディレクトリ objdir
を作ります。srcdir
とは異なる、新たなディレクトリを作る方が良さそう(推奨)です。
uda@host:~$ mkdir objdir
uda@host:~$ cd objdir
uda@host:objdir$ srcdir/configure --prefix=$HOME/local --disable-bootstrap
-
--prefix=PREFIX
オプションで、インストール先を指定します。- 今回はデフォルトの
/usr/local
ではなく、ホームディレクトリ以下にインストールしました。
- 今回はデフォルトの
- デフォルトでは、3-stage bootstrap build が有効になっていて、3 回同じビルドが走ります。
- build した GCC で GCC 自身を build できるか検証するためのようです。
- やたら時間食って面倒だったので、
--disable-bootstrap
オプションをつけました。
- もし必要なライブラリがなかったりするとここで怒られます。
- GMP ライブラリのインストール場所なども、オプションで指定できます。
成功すれば、Makefile
などが objdir
に出来上がります。
make
make します。やたら時間がかかるので、間違ってもカフェに行ってドヤ顔で make (ッターン
とかしないように。私は SSH して screen を立ち上げて make して寝ました。
uda@host:objdir$ make
# make 途中で、version script の syntax error が出て止まりました。<del> GNU grep 2.6.3 では suffix が .tmp のファイルを上手く扱えないのか、</del> 必要な version script が正しく生成されていませんでした。……ホンマかいな。しょうがないので、cat libstdc++-symbols.ver.tmp | grep -E -v ...
という風に、パイプで .tmp ファイルの中身を受け渡すようにしました。流石に GNU grep のバグとも思えないので、何か他の原因があるのではないかと思い色々検証中です。何か分かれば後日追記します。
## 2013-01-11 02:30 追記: 私の環境設定に起因する不具合でした。詳細はコメント参照。
make install
これはすぐに終わります。
uda@host:objdir$ make install
パスを通す
今回は $HOME/local
にインストールしたので、ここにパスを通します。
export PATH=$HOME/local/bin:$PATH
元の g++ とかも使いたい人は、PATH
の順番に注意して、適当に g++47
みたいな名前でシンボリックリンクを張っておけばよいです。
uda@host$ g++47 --version
g++ (GCC) 4.7.2
Copyright (C) 2012 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.
さて、新しいコンパイラでコンパイルしたプログラムはこのままだと実行できません。
uda@host:~/workdir$ echo $LD_LIBRARY_PATH
uda@host:~/workdir$ g++47 -std=c++11 -o test.out test.cpp
uda@host:~/workdir$ ./test.out
./test.out: /usr/lib/libstdc++.so.6: version `GLIBCXX_3.4.15' not found (required by ./test.out)
uda@host:~/workdir$ ldd ./test.out
./test.out: /usr/lib/libstdc++.so.6: version `GLIBCXX_3.4.15' not found (required by ./test.out)
(略)
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x00007fc9d549b000)
(略)
実行時にリンカに分かるように、環境変数 LD_LIBRARY_PATH
に今回インストールした共有ライブラリの場所を書いてあげます。あるいは、コンパイル時にリンカに渡すオプションで -rpath=$HOME/local/lib64
とかを指定しても良いかもしれません。
# 他にもっと良い方法があるのかしら……
export LD_LIBRARY_PATH=$HOME/local/lib:$HOME/local/lib64
uda@host:~/workdir$ echo $LD_LIBRARY_PATH
/home/uda/local/lib:/home/uda/local/lib64
uda@host:~/workdir$ ldd ./test.out
(略)
libstdc++.so.6 => /home/uda/local/lib64/libstdc++.so.6 (0x00007ffafbe49000)
(略)
ひとまず、今のところはこれで上手くコンパイルから実行までできていそうです。無事寝れます。
# 色々分かってない所もあるのでツッコミ歓迎