のろのろとgcc 4.8.1を作ってみる(その6) 本編

まずは、お詫びを。「のろのろとgcc 4.8.1を作ってみる(その4)」で、環境の把握が出来ておらず、誤った情報を元に記事を書いていたことを謝罪したします。
また、そのせいで無駄な時間を過ごした方がいらっしゃいましたら、ご容赦願います。


どうにも、明確な答えが書いてある場所を見つけられませんでしたが、動作から判断すると、gcc 4.8.1をコンパイルするときにgcc 4.6.x(恐らく、これ以前のverも)を使用するとビルトイン関数(ffsなど)が無条件に使用されるため、gcc 4.8.1は先日紹介した手順でコンパイルすることが出来ます。
一方gcc 4.7.x/gcc 4.8.xを使用した場合、ビルトイン関数は明示的に__builtin_ffs()のように記述する必要があり、先頭に__builtin_を付けずに使用すると、その関数は標準ライブラリに存在するものとして動作します。ただし、MinGW環境においては、gccのビルトイン関数とされているものには、標準ライブラリに存在していないものがあり、これによってコンパイルが失敗します。今回これに該当するのは、ffs関数です。基本的には、これらの関数はlibibertyライブラリによって救済されているのですが、あまりにも標準的な関数のためか、一部モジュールで見逃されているようです。
今回、見逃しのあるモジュール群に対して、libibertyライブラリを参照するようにパッチを加えていますが、願わくばgcc開発メンバーの方々が気づかれますよう期待します。本来はポストすべきところですが、なにぶん英語はRead Onlyなもので…。


以降が、gcc 4.7.x/gcc 4.8.xでもできるgcc 4.8.1のコンパイル方法の紹介です。

開発環境

MinGW(32bit版)
mingw-get-inst-20120426.exeに内蔵されているカタログファイルで指定されたMinGW/MSYSのバージョン環境。C、C++、MSYS Basic System、MinGW Developer Toolkitを選択してインストールしてあります。また、2013/6/30時点の最新カタログで得られた環境でも、問題なくコンパイル出来ることを確認してあります。
binutils
2013/6/23にbinutilsをv2.22からv2.23.2に入れ替えていましたが、上記MinGW環境で必要要件を満たしているため、そのままで問題ありません。
Ada(GNAT)
Adaを作りたい/使いたい人だけ必要になります。MinGW Shell上から「which gnatmake」と実行し、コマンドが見つかれば、基本的にはOKです。見つからない人は、「mingw-get install gcc-ada-bin」と実行してください。
ただし、独自にgccコンパイルしており、その際にAdaをコンパイルしていない場合で、今回Adaをコンパイルしようと考えている場合、MinGWコンパイル済みパッケージ等を利用して、Adaをコンパイル・使用できる環境までロールバックしてください。gnatmake, gnatbind等のコマンドだけではなく、その環境に存在する最新のgccに対応したGNATが存在しているかどうかをconfigureがチェックしていますので、コマンドだけでは開発環境としては不十分となります。
スレッドモデル
オリジナルのgccがwin32スレッドなので、そのままwin32スレッドで行きます。他の選択肢にはPOSIXスレッドがありますが、今のところ困ってないので…。

入手物

必要要件の詳細は、gccを展開したディレクトリの下のINSTALL/prerequisites.htmlを読んでください。

gcc v4.8.1
http://ftp.gnu.org/gnu/gcc/gcc-4.8.1/gcc-4.8.1.tar.bz2
GMP v5.1.2
http://ftp.gnu.org/gnu/gmp/gmp-5.1.2.tar.xz
MPFR v3.1.2
http://ftp.gnu.org/gnu/mpfr/mpfr-3.1.2.tar.xz
MPC v1.0.1
http://ftp.gnu.org/gnu/mpc/mpc-1.0.1.tar.gz
ISL v0.11.1
ftp://gcc.gnu.org/pub/gcc/infrastructure/isl-0.11.1.tar.bz2
CLooG v0.18.0
ftp://gcc.gnu.org/pub/gcc/infrastructure/cloog-0.18.0.tar.gz
zlib v1.2.8
http://www.zlib.net/ から http://prdownloads.sourceforge.net/libpng/zlib-1.2.8.tar.xz?download
gcc v4.8.1にzlib v1.2.7が入っているので、本当は必要ないけれども、v1.2.8でバグ修正が入っているので念のため。
libiconv v1.14
http://ftp.gnu.org/gnu/libiconv/libiconv-1.14.tar.gz
必要要件に入っていないけれども必要です。

パッチ

のろのろとgcc 4.8.1を作ってみる(その6) パッチ編」に記載していますので、そちらをご参照ください。

前準備

セキュリティソフトが誤って、生成オブジェクトをウイルスだとして、自動隔離する場合があります。私の環境のESET SMART SECURITY5が、まさにそれでした。自動隔離されると正しくコンパイルされないので、自動隔離しないように設定を変えるか、PCをスタンドアローンにしてセキュリティソフトを一時的に停止させてください。

準備

/usr/local/src(C:\MinGW\msys\1.0\local\src)配下を作業ディレクトリに使用した例なので、別のディレクトリが良い人は読み替えてください。

$ mkdir -p /usr/local/src/gcc_build /usr/local/src/gcc_alt
$ cd ダウンロード物のあるディレクトリ
$ tar xf gcc-4.8.1.tar.bz2 -C /usr/local/src
$ mv /usr/local/src/gcc-4.8.1 /usr/local/src/gcc-4.8.1-1
$ tar xf gmp-5.1.2.tar.xz -C /usr/local/src/gcc-4.8.1-1
$ tar xf mpfr-3.1.2.tar.xz -C /usr/local/src/gcc-4.8.1-1
$ tar xf mpc-1.0.1.tar.gz -C /usr/local/src/gcc-4.8.1-1
$ tar xf isl-0.11.1.tar.bz2 -C /usr/local/src/gcc-4.8.1-1
$ tar xf cloog-0.18.0.tar.gz -C /usr/local/src/gcc-4.8.1-1
$ tar xf zlib-1.2.8.tar.xz -C /usr/local/src/gcc-4.8.1-1
$ tar xf libiconv-1.14.tar.gz -C /usr/local/src/gcc-4.8.1-1
$ cd /usr/local/src/gcc-4.8.1-1
$ mv gmp-5.1.2 gmp
$ mv mpfr-3.1.2 mpfr
$ mv mpc-1.0.1 mpc
$ mv isl-0.11.1 isl
$ mv cloog-0.18.0 cloog
$ cd zlib-1.2.8
$ rm Makefile* configure
$ mv ../zlib/Makefile* ../zlib/configure* .
$ cd ..
$ rm -fr zlib
$ mv zlib-1.2.8 zlib
$ mv libiconv-1.14 libiconv
$ patch -p1 <  パッチを置いたディレクトリ/diff-gcc-4.8.1-1.patch

Makefileの作成(configureの実行)

  • 「-O3 -pipe」は私の趣味ですので「-O2」とかでも構いません。ただし、「-D* -W*」は消さないでください。
  • 必要の無い言語がある場合「--enable-languages=」から消してください。例えばCとC++しか必要が無い場合は「--enable-languages=c,c++」となります。
  • 母国語ファイルが必要な(つまり日本語メッセージが欲しい)場合、「--disable-nls」を消してください。
  • Adaが必要な場合「--with-arch=i586 --with-tune=generic」は、i586以上ならば好きな値に変えても構いません。
  • Adaが必要ない場合「--with-arch=i586 --with-tune=generic」を消してください。この場合、作られたコンパイラが生成するコードはi386ベースになります。また、消さずに好きな値に変えても構いません。
  • Javaが欲しい方は「--enable-languages=」にjavaを加えてください。例えば「--enable-languages=c,c++,java」の様に変更してください。また、「--with-arch=i586 --with-tune=generic」の削除、変更も自由です。
$ cd /usr/local/src/gcc_build
$ CFLAGS='-O3 -pipe -D__USE_MINGW_ACCESS -Wno-pedantic-ms-format' \
CXXFLAGS='-O3 -pipe -D__USE_MINGW_ACCESS -Wno-pedantic-ms-format' \
../gcc-4.8.1-1/configure --enable-languages=c,c++,ada,fortran,objc,obj-c++ \
--disable-nls --disable-sjlj-exceptions --with-dwaft2 --enable-shared \
--enable-libgomp --disable-win32-registry \
--enable-libstdcxx-debug --enable-version-specific-runtime-libs \
--build=mingw32 --with-arch=i586 --with-tune=generic \
--prefix=/mingw

オブジェクトの生成(makeの実行)

  • MinGW/MSYSを最新のカタログファイルから入手している場合、「-j*」を付けないでください。makeの先頭で、いきなりハングします。原因は、まだ調査中です(ただ、右上の×ボタンを押すしかない状況になるので、原因が判明するかどうか…)。
  • 「-j*」を付けない場合、シリアルコンパイルになるため、基本的にコンパイル問題は発生しなくなります。ただし、コンパイル時間が長くなります。Core i5クラスで4時間程度(4時間とちょっと)掛かります。
  • 「-j*」を付けた場合、パラレルコンパイルになるため、mingw-get-inst-20120426.exeに内蔵されているカタログファイルで指定されたMinGW/MSYSのバージョン環境でも、希にコンパイルの途中でハングすることがあります。ただし、「-j*」を付けることによって、コンパイル時間を減らすことが可能です。
    • 「-j*」の数値は、ご使用のPCの「Core数×Core当たりのスレッド数」を基本にして指定してください。私の場合は、Core i5-2430Mなので、Core数=2、Core当たりのスレッド数=2なので、基本は4です。私の環境で「-j4」を付けてコンパイルした場合、コンパイル時間は2時間になりました。
      • 少ない値を指定する分には問題ありませんが、あまりにも大きい値を指定するとコンテキストスイッチが多発して、逆にコンパイル時間が長くなる可能性があります。また、大量にメモリを消費しますので、メモリが少ない方は要注意です。
$ cd /usr/local/src/gcc_build
$ make -j4

実行ファイルの配布

DESTDIRの付いている方は保険です。付けていない方のinstall-stripが失敗した場合、環境が直せなくなってしまうので、/usr/local/src/gcc_alt(C:\MinGW\msys\1.0\local\src\gcc_alt)にバックアップを用意しておきます。
「make install-strip」に失敗したら(と言うか、大抵失敗します。「make DESTDIR=c: install-strip」で成功する場合もあります。仕込みとしか考えられない T-T )、/usr/local/src/gcc_alt配下に「mingw/〜」として新しいgccの環境がありますので、/mingw(C:\MinGW)に上書きしてください。
gcc -vを実行し、バージョンが4.8.1になっていれば成功です。

$ cd /usr/local/src/gcc_build
$ make DESTDIR=/usr/local/src/gcc_alt install-strip
$ make install-strip

後片付け

何かあったときのため、コンパイル環境を残しておきましょう。ただ、普通はgcc_alt配下さえあれば良いかも…

$ cd /usr/local/src
$ tar --xz -cf gcc-4.8.1-1.tar.xz ./gcc-4.8.1-1 ./gcc_build
$ rm -fr gcc-4.8.1-1 gcc_alt gcc_build