本パッケージの詳細は 6.17.2.「GCC の構成」を参照してください。
GCC パッケージは C コンパイラーや C++ コンパイラーなどの GNU コンパイラーコレクションを提供します。
最近の GCC は GMP、MPFR、MPC の各パッケージを必要とします。 これらのパッケージはホストシステムに含まれていないかもしれないため、以下を実行してビルドの準備をします。 個々のパッケージを GCC ソースディレクトリの中に伸張 (解凍) し、ディレクトリ名を変更します。 これは GCC のビルド処理においてそれらを自動的に利用できるようにするためです。
本節においては誤解が多く発生しています。 ここでの手順は他のものと同様であり、手順の概要 (パッケージビルド手順) は説明済です。 まず初めに gcc の tarball を伸張 (解凍) し、生成されたソースディレクトリに移動します。 それに加えて本節では、以下の手順を行うものとなります。
tar -Jxf ../mpfr-3.1.1.tar.xz mv -v mpfr-3.1.1 mpfr tar -Jxf ../gmp-5.0.5.tar.xz mv -v gmp-5.0.5 gmp tar -zxf ../mpc-1.0.tar.gz mv -v mpc-1.0 mpc
以下のコマンドは GCC のデフォルトのダイナミックリンカーの配置ディレクトリを、既にインストールされている /tools とします。 また GCC のインクルードパスから /usr/include を除きます。
for file in \
$(find gcc/config -name linux64.h -o -name linux.h -o -name sysv4.h)
do
cp -uv $file{,.orig}
sed -e 's@/lib\(64\)\?\(32\)\?/ld@/tools&@g' \
-e 's@/usr@/tools@g' $file.orig > $file
echo '
#undef STANDARD_STARTFILE_PREFIX_1
#undef STANDARD_STARTFILE_PREFIX_2
#define STANDARD_STARTFILE_PREFIX_1 "/tools/lib/"
#define STANDARD_STARTFILE_PREFIX_2 ""' >> $file
touch $file.orig
done
上のコマンドがよく分からない場合は一つ一つ読み下していってください。 まず gcc/config ディレクトリには linux.h, linux64.h,
sysv4.h といったファイルのいずれかがあります。
それらが存在したら、ファイル名称の末尾に「.orig」をつけたファイルとしてコピーします。 そして一つめの sed
コマンドでは、そのファイル内にある「/lib/ld」,
「/lib64/ld」, 「/lib32/ld」という記述部分の頭に「/tools」を付与します。 また二つめの sed
コマンドによってハードコーディングされている「/usr」という部分を書き換えます。 そしてここで加えるべき定義文をファイルの末尾に追加し、検索パスと
startfile プリフィックスを変更します。 この際に「/tools/lib/」の終わりには「/」が必要となります。 最後に touch
によってコピーしたファイルのタイムスタンプを更新します。 cp
-u
を用いるのは、誤ってコマンドを二度起動したとしてもオリジナルファイルを壊さないようにするためです。
GCC はスタックプロテクション (stack protection) を正しく検出しません。 このことは Glibc-2.16.0 においてビルドする際には問題となります。 そこで以下のコマンドを実行することで解消します。
sed -i '/k prot/agcc_cv_libc_provides_ssp=yes' gcc/configure
GCC のドキュメントでは、ソースディレクトリ以外の専用のビルドディレクトリを作成することが推奨されています。
mkdir -v ../gcc-build cd ../gcc-build
GCC をコンパイルするための準備をします。
../gcc-4.7.1/configure \
--target=$LFS_TGT \
--prefix=/tools \
--with-sysroot=$LFS \
--with-newlib \
--without-headers \
--with-local-prefix=/tools \
--with-native-system-header-dir=/tools/include \
--disable-nls \
--disable-shared \
--disable-multilib \
--disable-decimal-float \
--disable-threads \
--disable-libmudflap \
--disable-libssp \
--disable-libgomp \
--disable-libquadmath \
--enable-languages=c \
--with-mpfr-include=$(pwd)/../gcc-4.7.1/mpfr/src \
--with-mpfr-lib=$(pwd)/mpfr/src/.libs
configure オプションの意味:
--with-newlib
この時点では利用可能な C ライブラリがまだ存在しません。 したがって libgcc のビルド時に inhibit_libc 定数を定義します。 これを行うことで、libc サポートを必要とするコード部分をコンパイルしないようにします。
--without-headers
完璧なクロスコンパイラーを構築するなら、GCC はターゲットシステムに互換性を持つ標準ヘッダーを必要とします。 本手順においては標準ヘッダーは必要ありません。 このスイッチは GCC がそういったヘッダーを探しにいかないようにします。
--with-local-prefix=/tools
ローカルプリフックス (local prefix) は、GCC
がローカルにインストールされているインクルードファイルを探しにいくディレクトリを意味します。 そのデフォルトは
/usr/local です。 この設定を
/tools とすることで、GCC が探し出すパスから
/usr/local を除外します。
--with-native-system-header-dir=/tools/include
GCC がシステムヘッダーを探し出すデフォルトのパスは /usr/include です。 後に root を変更する際には、このディレクトリは
$LFS/usr/include となります。
しかしこの直後の2つの作業を通じて、ヘッダーをインストールする先は $LFS/tools/include としています。 つまり本スイッチは GCC
がヘッダーを正しく見つけ出せるようにするものです。 GCC
の2回めのビルドでは、同じスイッチを用いて、ホストシステムのヘッダーは一切見つけ出さないようにします。
--disable-shared
このオプションは内部ライブラリをスタティックライブラリとしてリンクすることを指示します。 ホストシステムに関係しそうな問題を回避するためです。
--disable-decimal-float, --disable-threads,
--disable-libmudflap, --disable-libssp, --disable-libgomp,
--disable-libquadmath
これらのオプションは順に、十進浮動小数点制御、スレッド処理、libmudflap、libssp、libgomp, libquadmath, libiberty, zlib のサポートをいずれも無効にすることを指示します。 これらの機能を含めていると、クロスコンパイラーをビルドする際にはコンパイルに失敗します。 またクロスコンパイルによって一時的な libc ライブラリを構築する際には不要なものです。
--disable-multilib
x86_64 に対して LFS は まだ multilib のサポートをしていません。 このオプション指定は x86 には無関係です。
--enable-languages=c
このオプションは C コンパイラーのみビルドすることを指示します。 この時点で必要なのはこの言語だけだからです。
GCC をコンパイルします。
make
コンパイルが終了しました。 この時点でもテストスイートを実行することはできます。 ただ前にも述べているように、テストスイートのフレームワークがまだ準備できていません。 さらにこの時点で生成されるプログラムは、すぐに次の生成作業によって置き換えられますから、この時点でテストを実行することはあまり意味がありません。
パッケージをインストールします。
make install
--disable-shared
オプションを指定すると libgcc_eh.a
を生成せずインストールしません。 Glibc パッケージはこのライブラリに依存しており、ビルドの際に -lgcc_eh を指定することで利用されます。 依存している点は
libgcc.a へのシンボリックリンクを生成しておけば問題はありません。
libgcc_eh.a に含まれるオブジェクトが、最終的には
libgcc.a の中にも含まれることになるからです。
ln -vs libgcc.a `$LFS_TGT-gcc -print-libgcc-file-name | sed 's/libgcc/&_eh/'`
本パッケージの詳細は 6.17.2.「GCC の構成」を参照してください。