6.17.1. GCC のインストール
sed による置換を行って
libiberty.a
をインストールしないようにします。
libiberty.a
は Binutils
が提供するものを利用することにします。
sed -i 's/install_to_$(INSTALL_DEST) //' libiberty/Makefile.in
5.9.「GCC-4.7.1 - 2回め」にて行ったように
sed
を使って以下のようにコンパイラーフラグ -fomit-frame-pointer
を強制的に指定し、一貫したコンパイルを実現します。
case `uname -m` in
i?86) sed -i 's/^T_CFLAGS =$/& -fomit-frame-pointer/' gcc/Makefile.in ;;
esac
また Makefile のチェックにおける誤りを修正します。
sed -i -e /autogen/d -e /check.sh/d fixincludes/Makefile.in
GCC のドキュメントによると GCC
のビルドにあたっては、ソースディレクトリ以外の専用のビルドディレクトリを作成することが推奨されています。
mkdir -v ../gcc-build
cd ../gcc-build
GCC をコンパイルするための準備をします。
../gcc-4.7.1/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 \
--with-system-zlib
他のプログラミング言語は、また別の依存パッケージなどを要しますが、現時点では準備できていません。 GCC
がサポートする他のプログラム言語の構築方法については BLFS ブックの説明を参照してください。
Configure オプションの意味:
-
--with-system-zlib
-
このオプションはシステムに既にインストールされている Zlib
ライブラリをリンクすることを指示するものであり、内部にて作成されるライブラリを用いないようにします。
パッケージをコンパイルします。
make
重要項目
本節における GCC のテストスイートは極めて重要なものです。 したがってどのような場合であっても必ず実行してください。
GCC テストスイートの中で、スタックを使い果たすものがあります。 そこでテスト実施にあたり、スタックサイズを増やします。
ulimit -s 32768
コンパイル結果をテストします。 エラーが発生しても停止しないようにします。
make -k check
テスト結果を確認するために以下を実行します。
../gcc-4.7.1/contrib/test_summary
テスト結果の概略のみ確認したい場合は、出力結果をパイプ出力して grep -A7 Summ
を実行してください。
テスト結果については //www.linuxfromscratch.org/lfs/build-logs/7.2/
と //gcc.gnu.org/ml/gcc-testresults/
にある情報と比較することができます。
テストに失敗することがありますが、これを回避することはできません。 GCC
の開発者はこの問題を認識していますが、まだ解決していない状況です。 特に libmudflap
のテストは大いに問題があり GCC のバグとして知られています。
(//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.7.1/../../../crt1.o succeeded
/usr/lib/gcc/i686-pc-linux-gnu/4.7.1/../../../crti.o succeeded
/usr/lib/gcc/i686-pc-linux-gnu/4.7.1/../../../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/i686-pc-linux-gnu/4.7.1/include
/usr/lib/gcc/i686-pc-linux-gnu/4.7.1/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
最後に誤ったディレクトリにあるファイルを移動します。
mkdir -pv /usr/share/gdb/auto-load/usr/lib
mv -v /usr/lib/*gdb.py /usr/share/gdb/auto-load/usr/lib