5.2. ツールチェーンの技術的情報

本節ではシステムをビルドする原理や技術的な詳細について説明します。 この節のすべてをすぐに理解する必要はありません。 この先、実際の作業を行っていけば、いろいろな情報が明らかになってくるはずです。 各作業を進めながら、いつでもこの節に戻って読み直してみてください。

第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章 におけるビルド手順がどのように機能するのか、その技術的な情報を以下に示します。

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 システムを構築する残りのパッケージをビルドしていきます。