5.5. GCC-4.8.2 - 1回め

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

概算ビルド時間: 5.5 SBU
必要ディスク容量: 1.4 GB

5.5.1. クロスコンパイル版 GCC のインストール

最近の GCC は GMP、MPFR、MPC の各パッケージを必要とします。 これらのパッケージはホストシステムに含まれていないかもしれないため、以下を実行してビルドの準備をします。 個々のパッケージを GCC ソースディレクトリの中に伸張 (解凍) し、ディレクトリ名を変更します。 これは GCC のビルド処理においてそれらを自動的に利用できるようにするためです。

[注記]

注記

本節においては誤解が多く発生しています。 ここでの手順は他のものと同様であり、手順の概要 (パッケージビルド手順) は説明済です。 まず初めに gcc の tarball を伸張 (解凍) し、生成されたソースディレクトリに移動します。 それに加えて本節では、以下の手順を行うものとなります。

tar -Jxf ../mpfr-3.1.2.tar.xz
mv -v mpfr-3.1.2 mpfr
tar -Jxf ../gmp-5.1.3.tar.xz
mv -v gmp-5.1.3 gmp
tar -zxf ../mpc-1.0.2.tar.gz
mv -v mpc-1.0.2 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.19 においてビルドする際には問題となります。 そこで以下のコマンドを実行することで解消します。

sed -i '/k prot/agcc_cv_libc_provides_ssp=yes' gcc/configure

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

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

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

../gcc-4.8.2/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-libatomic                              \
    --disable-libgomp                                \
    --disable-libitm                                 \
    --disable-libmudflap                             \
    --disable-libquadmath                            \
    --disable-libsanitizer                           \
    --disable-libssp                                 \
    --disable-libstdc++-v3                           \
    --enable-languages=c,c++                         \
    --with-mpfr-include=$(pwd)/../gcc-4.8.2/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-libatomic, --disable-libgomp, --disable-libitm, --disable-libmudflap, --disable-libquadmath, --disable-libsanitizer, --disable-libssp, --disable-libstdc++-v3

これらのオプションは順に、十進浮動小数点制御、スレッド処理、libatomic, libgomp, libitm, libmudflap, libquadmath, libsanitizer, libssp, C++ 標準ライブラリのサポートをいずれも無効にすることを指示します。 これらの機能を含めていると、クロスコンパイラーをビルドする際にはコンパイルに失敗します。 またクロスコンパイルによって一時的な libc ライブラリを構築する際には不要なものです。

--disable-multilib

x86_64 に対して LFS は まだ multilib のサポートをしていません。 このオプション指定は x86 には無関係です。

--enable-languages=c,c++

このオプションは C コンパイラーおよび C++ コンパイラーのみビルドすることを指示します。 この時点で必要なのはこの言語だけだからです。

--with-mpfr-*

これらのオプションは、MPFR のソースコピーを適切に用いてシステムビルドを行うことを指示します。

GCC をコンパイルします。

make

コンパイルが終了しました。 この時点でもテストスイートを実行することはできます。 ただ前にも述べているように、テストスイートのフレームワークがまだ準備できていません。 さらにこの時点で生成されるプログラムは、すぐに次の生成作業によって置き換えられますから、この時点でテストを実行することはあまり意味がありません。

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

make install

--disable-shared オプションを指定すると libgcc_eh.a を生成せずインストールしません。 Glibc パッケージはこのライブラリに依存しており、ビルドの際に -lgcc_eh を指定することで利用されます。 依存している点は libgcc.a へのシンボリックリンクを生成しておけば問題はありません。 libgcc_eh.a に含まれるオブジェクトが、最終的には libgcc.a の中にも含まれることになるからです。

ln -sv libgcc.a `$LFS_TGT-gcc -print-libgcc-file-name | sed 's/libgcc/&_eh/'`

本パッケージの詳細は 6.17.2.「GCC の構成」を参照してください。