Edited at

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

More than 5 years have passed since last update.

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 にインストールしたので、ここにパスを通します。


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

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


zshrc.local

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)
()

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

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


参考文献/リンク一覧