GCC をソースからビルドする修行してみた

C++11 が使えない？最新の GCC 使えばいいじゃない！

sudo 権限がないからインストールできない？ビルドすればいいじゃない！

はい。C++11 が使えないのはちょっと人権がないと思うので、そのためだけに GCC の最新版をビルドしてみました。まぁ、ほぼマニュアル通りに実行しただけなので、つまずいた所とかをメモ書き程度に。

```sh:今回の環境
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](http://gcc.gnu.org/install/prerequisites.html "Prerequisites for GCC - GNU Project - Free Software Foundation (FSF)") を参考に、必要なライブラリ等を先にインストールしておきます。私の場合、GMP とかが必要でした。

次に、GCC のソースを [GCC Releases](http://gcc.gnu.org/releases.html "GCC Releases - GNU Project - Free Software Foundation (FSF)") からダウンロードしてきます。今回は ```gcc-4.7.2.tar.gz``` を使いました。SVN 版もあります。

（必要なら展開して）ソースの置いてあるディレクトリを ```srcdir``` とします。

```sh
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``` とは異なる、新たなディレクトリを作る方が良さそう(推奨)です。

```sh
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 して寝ました。

```sh
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

これはすぐに終わります。

```sh
uda@host:objdir$ make install
``` 

## パスを通す

今回は ```$HOME/local``` にインストールしたので、ここにパスを通します。

```.zshrc.local
export PATH=$HOME/local/bin:$PATH
```

元の g++ とかも使いたい人は、```PATH``` の順番に注意して、適当に ```g++47``` みたいな名前でシンボリックリンクを張っておけばよいです。

```sh
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.
```

さて、新しいコンパイラでコンパイルしたプログラムはこのままだと実行できません。

```sh
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``` とかを指定しても良いかもしれません。

\# 他にもっと良い方法があるのかしら……


```.zshrc.local
export LD_LIBRARY_PATH=$HOME/local/lib:$HOME/local/lib64
```

```sh
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)
        (略) 
```

ひとまず、今のところはこれで上手くコンパイルから実行までできていそうです。無事寝れます。

\# 色々分かってない所もあるのでツッコミ歓迎

## 参考文献/リンク一覧

- [Prerequisites for GCC](http://gcc.gnu.org/install/prerequisites.html "Prerequisites for GCC - GNU Project - Free Software Foundation (FSF)")
- [GCC Releases](http://gcc.gnu.org/releases.html "GCC Releases - GNU Project - Free Software Foundation (FSF)")
- [Installing GCC](http://gcc.gnu.org/install/ "Installing GCC - GNU Project - Free Software Foundation (FSF)")