6.16. GCC-4.4.3

GCC パッケージは C コンパイラや C++ コンパイラなどの GNU コンパイラコレクションを提供します。

概算ビルド時間: 44 SBU テストスイート込み
必要ディスク容量: 1.1 GB テストスイート込み

6.16.1. GCC のインストール

sed による置換を行って libiberty.a をインストールしないようにします。 libiberty.a は Binutils が提供するものを利用することにします。

sed -i 's/install_to_$(INSTALL_DEST) //' libiberty/Makefile.in

5.10. 「GCC-4.4.3 - 2回め」 にて行ったように sed を使って以下のようにコンパイラフラグ -fomit-frame-pointer を強制的に指定し、一貫したコンパイルを実現します。

case `uname -m` in
  i?86) sed -i 's/^T_CFLAGS =$/& -fomit-frame-pointer/' \
        gcc/Makefile.in ;;
esac

fixincludes スクリプトは、たまにエラーを引き起こし、それまでにインストールされているシステムヘッダーファイルを修正してしまうことがあります。 ここまでにインストールしてきたヘッダファイルは修正する必要がないので、以下のコマンドを実行して fixincludes スクリプトを実行しないようにします。

sed -i 's@\./fixinc\.sh@-c true@' gcc/Makefile.in

sed による置換を実行して、テストスイートのエラーを回避します。

sed -i 's/getline/get_line/' libiberty/testsuite/test-demangle.c

GCC のドキュメントによると GCC のビルドにあたっては、ソースディレクトリ以外の専用のビルドディレクトリを作成することが推奨されています。

mkdir -v ../gcc-build
cd ../gcc-build

GCC をコンパイルするための準備をします。

../gcc-4.4.3/configure --prefix=/usr \
    --libexecdir=/usr/lib --enable-shared \
    --enable-threads=posix --enable-__cxa_atexit \
    --enable-clocale=gnu --enable-languages=c,c++ \
    --disable-multilib --disable-bootstrap

他のプログラミング言語は、また別の依存パッケージなどを要しますが、現時点では準備できていません。 GCC がサポートする他のプログラム言語の構築方法については BLFS ブックの説明を参照してください。

パッケージをコンパイルします。

make
[重要項目]

重要項目

本節における GCC のテストスイートは極めて重要なものです。 したがってどのような場合であっても必ず実行してください。

コンパイル結果をテストします。 エラーが発生しても停止しないようにします。

make -k check

テスト結果を確認するために以下を実行します。

../gcc-4.4.3/contrib/test_summary

テスト結果の概略のみ確認したい場合は、 出力結果をパイプ出力して grep -A7 Summ を実行してください。

テスト結果については http://www.linuxfromscratch.org/lfs/build-logs/6.6/http://gcc.gnu.org/ml/gcc-testresults/ にある情報と比較することができます。

テストに失敗することがありますが、これを回避することはできません。 GCC の開発者はこの問題を認識していますが、まだ解決していない状況です。 特に libmudflap のテストは大いに問題があり GCC のバグとして知られています。 (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20003) この URL に示されている結果と大きく異なっていなかったら、 問題はありませんので先に進んでください。

パッケージをインストールします。

make install

パッケージの中には C プリプロセッサが /lib ディレクトリにあることを前提にしているものがあります。 そのようなものに対応するため、以下のシンボリックリンクを作成します。

ln -sv ../usr/bin/cpp /lib

パッケージの多くは C コンパイラとして cc を呼び出しています。 これに対応するため、以下のシンボリックリンクを作成します。

ln -sv gcc /usr/bin/cc

最終的なツールチェーンが出来上がりました。 ここで再びコンパイルとリンクが正しく動作することを確認することが必要です。 そこで本節の初めの方で実施した健全性テストをここでも実施します。

echo 'main(){}' > dummy.c
cc dummy.c -v -Wl,--verbose &> dummy.log
readelf -l a.out | grep ': /lib'

問題なく動作した場合はエラーがなかったということで、最後のコマンドから出力される結果は以下のようになるはずです。 (ダイナミックリンカの名前はプラットフォームによって違っているかもしれません。)

[Requesting program interpreter: /lib/ld-linux.so.2]

ここで起動ファイルが正しく用いられていることを確認します。

grep -o '/usr/lib.*/crt[1in].*succeeded' dummy.log

問題なく動作した場合はエラーがなかったということで、上のコマンドの出力は以下のようになるはずです。

/usr/lib/gcc/i686-pc-linux-gnu/4.4.3/../../../crt1.o succeeded
/usr/lib/gcc/i686-pc-linux-gnu/4.4.3/../../../crti.o succeeded
/usr/lib/gcc/i686-pc-linux-gnu/4.4.3/../../../crtn.o succeeded

作業しているマシンアーキテクチャによっては、上の結果が微妙に異なるかもしれません。 その違いは、たいていは /usr/lib/gcc の次のディレクトリ名にあります。 作業マシンが 64 ビット機である場合、ディレクトリ名の後ろの方に lib64 という名が出てくることになります。 ここで確認すべき重要なポイントは gcc/usr/lib ディレクトリ配下に三つのファイル crt*.o を見つけ出しているかどうかです。

コンパイラが正しいヘッダファイルを読み取っているかどうかを検査します。

grep -B4 '^ /usr/include' dummy.log

上のコマンドは正常に終了すると、以下の出力を返します。

#include <...> search starts here:
 /usr/local/include
 /usr/lib/gcc/x86_64-unknown-linux-gnu/4.4.3/include
 /usr/lib/gcc/i686-pc-linux-gnu/4.4.3/include-fixed
 /usr/include

もう一度触れておきますが、プラットフォームの 「三つの組 (target triplet)」 の次にくるディレクトリ名は CPU アーキテクチャにより異なる点に注意してください。

[注記]

注記

GCC のバージョン 4.3.0 では limits.h ファイルを無条件に include-fixed ディレクトリにインストールします。 したがってそのディレクトリは存在していなければなりません。

次に、新たなリンカが正しいパスを検索して用いられているかどうかを検査します。

grep 'SEARCH.*/usr/lib' dummy.log |sed 's|; |\n|g'

問題なく動作した場合はエラーがなかったということで、最後のコマンドの出力は以下のようになるはずです。 (作業するプラットフォームに応じて「三つの組 (target triplet)」の表記は異なります。)

SEARCH_DIR("/usr/i686-pc-linux-gnu/lib")
SEARCH_DIR("/usr/local/lib")
SEARCH_DIR("/lib")
SEARCH_DIR("/usr/lib");

64 ビットシステムではさらにいくつかのディレクトリが出力されます。 例えば x86_64 マシンであれば、その出力は以下のようになります。

SEARCH_DIR("/usr/x86_64-unknown-linux-gnu/lib64")
SEARCH_DIR("/usr/local/lib64")
SEARCH_DIR("/lib64")
SEARCH_DIR("/usr/lib64")
SEARCH_DIR("/usr/x86_64-unknown-linux-gnu/lib")
SEARCH_DIR("/usr/local/lib")
SEARCH_DIR("/lib")
SEARCH_DIR("/usr/lib");

次に libc が正しく用いられていることを確認します。

grep "/lib.*/libc.so.6 " dummy.log

問題なく動作した場合はエラーがなかったということで、最後のコマンドの出力は以下のようになるはずです。 (64 ビットマシンであれば lib64 ディレクトリとなるはずです。)

attempt to open /lib/libc.so.6 succeeded

最後に GCC が正しくダイナミックリンカを用いているかを確認します。

grep found dummy.log

問題なく動作した場合はエラーがなかったということで、上のコマンドの出力は以下のようになるはずです。 (ダイナミックリンカの名前はプラットフォームによって違っているかもしれません。 また 64 ビットマシンであれば lib64 ディレクトリとなるはずです。)

found ld-linux.so.2 at /lib/ld-linux.so.2

出力結果が上と異なっていたり、出力が全く得られなかったりした場合は、何かが根本的に間違っているということです。 どこに問題があるのか調査・再試行を行って解消してください。 最もありがちな理由は、スペックファイルの修正を誤っていることです。 問題を残したままこの先には進まないでください。

すべてが正しく動作したら、テストに用いたファイルを削除します。

rm -v dummy.c a.out dummy.log

6.16.2. GCC の構成

インストールプログラム: c++, cc (gcc へのリンク), cpp, g++, gcc, gccbug, gcov
インストールライブラリ: libgcc.a, libgcc_eh.a, libgcc_s.so, libgcov.a, libgomp.{a,so}, libmudflap.{a,so}, libmudflapth.{a,so}, libssp.{a,so}, libssp_nonshared.a, libstdc++.{a,so} libsupc++.a

概略説明

c++

C++ コンパイラ

cc

C コンパイラ

cpp

C プリプロセッサ。 コンパイラがこれを利用して、ソース内に記述された #include、#define や同じようなステートメントを展開します。

g++

C++ コンパイラ

gcc

C コンパイラ

gccbug

有用なバグ報告の生成を手助けするスクリプト。

gcov

カバレッジテストツール。 プログラムを解析して、最適化が最も効果的となるのはどこかを特定します。

libgcc

gcc のランタイムサポートを提供します。

libgcov

GCC のプロファイリングを有効にした場合にこのライブラリがリンクされます。

libgomp

C/C++ や Fortran において、マルチプラットフォームでの共有メモリ並行プログラミング (multi-platform shared-memory parallel programming) を行うための、GNU による OpenMP API インプリメンテーションです。

libmudflap

GCC の配列境界チェック (bounds checking) 機能をサポートするルーチンを提供します。

libssp

GCC のスタック破壊を防止する (stack-smashing protection) 機能をサポートするルーチンを提供します。

libstdc++

標準 C++ ライブラリ

libsupc++

C++ プログラミング言語のためのサポートルーチンを提供します。