本パッケージの詳細は 6.17.2.「GCC の構成」を参照してください。
GCC パッケージは C コンパイラーや C++ コンパイラーなどの GNU コンパイラーコレクションを提供します。
第1回めの GCC のビルドでは、内部的なシステムヘッダーをインストールしています。 その1つ limits.h
は、これに対応づくシステムヘッダー limits.h
を読み込みます。 そのファイルは実際には /tools/include/limits.h
となります。 しかし1回めの GCC
のビルド時には /tools/include/limits.h
は存在しません。 したがって GCC がインストールする内部ヘッダーは、部分的で自己完結した (self-contained)
もののみとなり、システムヘッダーが持つ拡張機能は含まれません。 一時的な libc
を構築するならこれは正しかったのですが、この段階での GCC のビルドでは、内部ヘッダーが完全な形のものでなければなりません。
完全な内部ヘッダーを生成するために、GCC ビルドシステムが通常行っている方法と同じようにするための、以下のコマンドを実行します。
cat gcc/limitx.h gcc/glimits.h gcc/limity.h > \ `dirname $($LFS_TGT-gcc -print-libgcc-file-name)`/include-fixed/limits.h
x86 マシンにおいてブートストラップビルドを行うと、コンパイラーフラグ -fomit-frame-pointer
が設定されます。
しかしブートストラップではないビルドの場合はデフォルトではこのフラグが無効化されてしまいます。
ここで実現したいのは、ブートストラップビルドを行った場合とまったく同じコンパイラーをビルドすることです。 そこで以下の
sed
コマンドにより、強制的に上のフラグを利用するようにします。
cp -v gcc/Makefile.in{,.tmp} sed 's/^T_CFLAGS =$/& -fomit-frame-pointer/' gcc/Makefile.in.tmp \ > gcc/Makefile.in
もう一度、GCC のデフォルトのダイナミックリンカーの配置ディレクトリを、既にインストールされている /tools
とします。
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 を初めてビルドする際には GMP、MPFR、MPC の各パッケージを必要とします。 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
専用のディレクトリを再度生成します。
mkdir -v ../gcc-build cd ../gcc-build
GCC のビルドに入る前に、デフォルトの最適化フラグを上書きするような環境変数の設定がないことを確認してください。
GCC をコンパイルするための準備をします。
CC=$LFS_TGT-gcc \ AR=$LFS_TGT-ar \ RANLIB=$LFS_TGT-ranlib \ ../gcc-4.7.1/configure \ --prefix=/tools \ --with-local-prefix=/tools \ --with-native-system-header-dir=/tools/include \ --enable-clocale=gnu \ --enable-shared \ --enable-threads=posix \ --enable-__cxa_atexit \ --enable-languages=c,c++ \ --disable-libstdcxx-pch \ --disable-multilib \ --disable-bootstrap \ --disable-libgomp \ --with-mpfr-include=$(pwd)/../gcc-4.7.1/mpfr/src \ --with-mpfr-lib=$(pwd)/mpfr/src/.libs
configure オプションの意味:
--enable-clocale=gnu
このオプションはあらゆる状況において C++ ライブラリに対するロケールモデルが正しく設定されるようにします。 configure スクリプト実行時に de_DE ロケールがインストール済みであることが分かれば、正しい GNU ロケールモデルが設定されます。 しかし de_DE ロケールがインストールされていなかったら、誤った汎用ロケールモデルが設定されてしまうため、アプリケーションバイナリインターフェース (Application Binary Interface; ABI) とは非互換の C++ ライブラリが生成されてしまう可能性があります。
--enable-threads=posix
マルチスレッドコードを扱う C++ の例外処理を有効にします。
--enable-__cxa_atexit
このオプションは atexit
を使用せず
__cxa_atexit
の使用を有効にします。
これによりローカルなスタティックオブジェクトおよびグローバルオブジェクトに対する C++ デストラクターを登録します。
このオプションは、標準に完全準拠したデストラクタ実装のために必要です。 またこれは C++ ABI に影響するものであり
C++ 共有ライブラリ、C++ プログラムを作り出し、他の Linux ディストリビューションとの互換性を実現します。
--enable-languages=c,c++
C と C++ の両コンパイラーを生成することを指示します。
--disable-libstdcxx-pch
libstdc++
に対してプリコンパイルヘッダー
(pre-compiled header; PCH) をビルドしないように指示します。
これを含めてしまうとサイズが増えることになり、そもそも利用する必要がありません。
--disable-bootstrap
GCC のネイティブビルドを行うには、デフォルトでは "ブートストラップ" ビルドを行ないます。 これは単に GCC をコンパイルするのではなく、数回のコンパイルを繰り返します。 つまり一回めにビルドされたプログラムを使って二回め、三回めのコンパイルを行うものです。 二回め、三回めとコンパイルを繰り返すのは、これによって自分自身を再生成して完璧なものを作り出すためです。 このことによってコンパイルが正確に行われたことを暗に示すことにもなります。 しかし LFS のビルドでは、何度もブートストラップを行う必要のない、手堅い(solid) コンパイラーを作り出します。
パッケージをコンパイルします。
make
パッケージをインストールします。
make install
最後にシンボリックリンクを作成します。 プログラムやスクリプトの中には gcc ではなく cc を用いるものが結構あります。 シンボリックリンクを作ることで各種のプログラムを汎用的にすることができ、通常 GNU C コンパイラーがインストールされていない多くの UNIX システムでも利用できるものになります。 cc を利用することにすれば、システム管理者がどの C コンパイラーをインストールすべきかを判断する必要がなくなります。
ln -vs gcc /tools/bin/cc
この時点で、構築したツールチェーンの基本的な (コンパイルやリンクなどの) 機能が正しく動作していることを確認する必要があります。 健全性検査 (sanity check) を行うために以下を実行してください。
echo 'main(){}' > dummy.c cc dummy.c readelf -l a.out | grep ': /tools'
問題なく動作した場合はエラーがなかったということで、最後のコマンドから出力される結果は以下のようになるはずです。
[Requesting program interpreter: /tools/lib/ld-linux.so.2]
ここでダイナミックリンカーのディレクトリが /tools/lib
であることを確認してください。 あるいは 64 ビットマシンであれば /tools/lib64
であることを確認してください。
コマンドの出力結果が上と異なっていたり、あるいは何も出力されなかった場合は、何かがおかしいことを意味します。
どこに問題があるのか調査、再試行を行って解消してください。 解決せずにこの先に進まないでください。 cc ではなく gcc を使って再度健全性検査を行ってみてください。
これで解決したなら /tools/bin/cc
のシンボリックリンクが正しくないということです。 正しく生成し直してください。 また環境変数 PATH
が正しいかどうかも確認してください。 echo $PATH を実行して、実行パスリストの先頭が
/tools/bin
であるかどうか確認します。
PATH
が間違っていたなら、実はあなたは lfs
ユーザーでログインしていないのかもしれませんし 4.4.「環境設定」での作業に間違いがあったのかもしれません。
すべてが終了したらテストファイルを削除します。
rm -v dummy.c a.out
本パッケージの詳細は 6.17.2.「GCC の構成」を参照してください。