本節ではシステムをビルドする原理や技術的な詳細について説明します。 この節のすべてをすぐに理解する必要はありません。 この先、実際の作業を行っていけば、いろいろな情報が明らかになってくるはずです。 各作業を進めながら、いつでもこの節に戻って読み直してみてください。
第5章 の最終目標は一時的なシステム環境を構築することです。 この一時的なシステムには、システム構築のための十分なツール類を有し、ホストシステムとは切り離されたものです。 この環境へは chroot によって移行します。この環境は 第6章 において、クリーンでトラブルのない LFS システムの構築を行う土台となるものです。 構築手順の説明においては、初心者の方であっても失敗を最小限にとどめ、同時に最大限の学習材料となるように心がけています。
これより先に進む前に、作業するプラットフォームの 「三つの組 (target
triplet)」 で表される名称を確認してください。「三つの組」
は config.guess
スクリプトを実行することで簡単に確認できます。 そのスクリプトは多くのパッケージのソースに含まれています。 Binutils
パッケージのソースを伸張 (解凍) し ./config.guess
スクリプトを実行してその出力を確認してみてください。 例えば最近の 32 ビット Intel プロセッサでは i686-pc-linux-gnu のような出力が得られます。
利用しているプラットフォームに応じたダイナミックリンカ (dynamic linker) の名前についても確認してください。
ダイナミックローダ (dynamic loader) とも表現されるものです。 (Binutils が提供する標準的なリンカ
ld
とは異なりますので注意してください。) Glibc
が提供するこのダイナミックリンカは、プログラムが必要としている共有ライブラリを見つけ出してロードし、実行のための準備を行った上で実際に実行します。
32 ビットマシンのダイナミックリンカの名前は ld-linux.so.2
といったものになります。 確実にその名前を調べるなら、ホストシステム内のどれでも良いので実行モジュールを選んで
readelf -l <実行モジュール名> | grep
interpreter
と入力します。出力される結果を確認してください。
あらゆるプラットフォームの情報を知りたいなら Glibc のソースディレクトリのルートにある shlib-versions
ファイルに記されています。
第5章 におけるビルド手順がどのように機能するのか、その技術的な情報を以下に示します。
動作させているプラットフォームの名前を微妙に変えます。 三つの組の "ベンダー " フィールドを変更するもので、
LFS_TGT
変数に定め利用します。 こうしておいて Binutils
と GCC の初回の構築を行なえば、互換性のあるクロスコンパイラ、クロスリンカを確実に構築できるようになります。
もう一つ別のアーキテクチャに対する実行モジュールを作らなくても、そのクロスコンパイラとクロスリンカを使えば、生成される実行モジュールは現在のハードウェアに適合したものとなります。
一時的に構築するライブラリはクロスコンパイルにより生成します。 クロスコンパイラというものは元来、ホストシステムへ依存するものではないためです。 こうすることで、ホストシステムのヘッダやライブラリが、一時的なツール類を壊してしまうような危険を減らすことができ、同時に 64 ビットマシンにて 32 ビットあるいは 64 ビットの双方のライブラリを構築することができるようになります。
gcc のスペック (specs) ファイルを適切に調整することで、どのダイナミックリンカを用いるのかをコンパイラに指示します。
Binutils をまず初めにインストールします。 この後の GCC や Glibc の configure スクリプトの実行ではアセンブラやリンカに対する様々な機能テストが行われるためで、そこではどの機能が利用可能または利用不能であるかが確認されます。 ただ重要なのは Binutils を一番初めにビルドするという点だけではありません。 Gcc や Glibc の configure が正しく処理されなかったとすると、ツールチェーンがわずかながらも不完全な状態で生成されてしまいます。 この状態は、すべてのビルド作業を終えた最後になって、大きな不具合となって現れてくることになります。 テストスイートを実行することが欠かせません。 これを実行しておけば、この先に行う多くの作業に入る前に不備があることが分かるからです。
Binutils はアセンブラとリンカを二箇所にインストールします。 /tools/bin
と /tools/$LFS_TGT/bin
です。 これらは一方が他方のハードリンクとなっています。
リンカの重要なところはライブラリを検索する順番です。 ld コマンドに --verbose
オプションをつけて実行すれば詳しい情報が得られます。
例えば ld --verbose | grep
SEARCH
を実行すると、検索するライブラリのパスとその検索順を示してくれます。
ダミープログラムをコンパイルして ld に
--verbose
オプションをつけてリンクを行うと、どのファイルがリンクされたが分かります。 例えば gcc dummy.c -Wl,--verbose 2>&1 | grep
succeeded
と実行すれば、リンカの処理中にオープンに成功したファイルがすべて表示されます。
次にインストールするのは GCC です。 configure の実行時には以下のような出力が行われます。
checking what assembler to use... /tools/i686-lfs-linux-gnu/bin/as
checking what linker to use... /tools/i686-lfs-linux-gnu/bin/ld
これを示すのには重要な意味があります。 GCC の configure スクリプトは、利用するツール類を探し出す際に PATH
ディレクトリを参照していないということです。 しかし gcc
の実際の処理にあたっては、その検索パスが必ず使われるわけでもありません。 gcc が利用する標準的なリンカを確認するには
gcc
-print-prog-name=ld
を実行します。
さらに詳細な情報を知りたいときは、ダミープログラムをコンパイルする際に -v
オプションをつけて実行します。 例えば gcc -v dummy.c
と入力すると、プリプロセッサ、コンパイル、アセンブルの各処理工程が示されますが、さらに gcc がインクルードした検索パスとその読み込み順も示されます。
次のパッケージは Glibc です。 Glibc 構築の際に気にかけるべき重要なものは、コンパイラ、バイナリツール、カーネルヘッダです。
コンパイラについては、一般にはあまり問題にはなりません。 Glibc は常に configure スクリプトにて指定される
--host
パラメータに関連づけしたコンパイラを用いるからです。 我々の作業では i686-lfs-linux-gnu-gcc になります。
バイナリツールとカーネルヘッダは多少複雑です。 従って無理なことはせずに有効な configure オプションを選択することが必要です。
configure 実行の後は
glibc-build
ディレクトリにある config.make
ファイルに重要な情報が示されているので確認してみてください。 なお
CC="i686-lfs-gnu-gcc"
とすれば、どこにある実行モジュールを利用するかを制御でき -nostdinc
と -isystem
を指定すれば、コンパイラに対してインクルードファイルの検索パスを制御できます。 これらの指定は Glibc
パッケージの重要な面を示しています。 Glibc
がビルドされるメカニズムは自己完結したビルドが行われるものであり、ツールチェーンのデフォルト設定には基本的に依存しないことを示しています。
Glibc をインストールした後は、 gcc
のスペックファイルにて /tools/lib
ディレクトリにある新しいダイナミックリンカを用いるような修正を行います。 この修正により /tools
内での検索とリンクが行われるようにします。
ダイナミックリンカに対する固定的な検索パスの設定は、ここから生成されるすべての ELF (Executable and Link
Format) 形式の実行モジュールにも埋め込まれていきます。 その結果は readelf -l <実行モジュール名> | grep
interpreter
を実行すれば確認できます。 gcc
のスペック・ファイルを修正するのは、これ以降、本章の最後に至るまで、すべてのプログラムのコンパイル時に /tools/lib
にあるダイナミックリンカが利用されるよう仕向けるものです。
GCC の第2回目のビルドにおいても、スペックファイルを修正して新しいダイナミックリンカが用いられるようにします。
これをもし誤ってしまうと、ホストシステムの /lib
ディレクトリが埋め込まれたダイナミックリンカを用いるものとして GCC が生成されてしまいます。
こうしてしまうと、ホストシステムに依存しない形を目指すという目的が達成できません。
Binutils の2回めのビルドにおいては ld コマンドのライブラリ検索パスを設定するために configure
の --with-lib-path
オプションを指定します。 それ以降ツールチェーンの核となるツール類は、自分自身から作り出された (self-contained)
自分だけで処理できる (self-hosted) 形となります。 第5章 において構築する残りのパッケージは
/tools
ディレクトリの新しい Glibc を用いてビルドされます。
第6章 での chroot による環境下では、実質的なパッケージとして Glibc
を初めにビルドします。 これは上に述べているように自己完結した性質を目指すためです。 /usr
に Glibc をインストールしたら、ツールチェーンのデフォルトディレクトリの変更を行い
LFS システムを構築する残りのパッケージをビルドしていきます。