トップ > 最小システムの構築 >
一時的な開発ツールの調整

  

一時的な開発ツールの調整

新システムの作成の前半の作業が終了しました。 後半の作業に入る前に、一時的な開発ツールの調整を行います

一時的な開発ツールの調整とは、標準Cライブラリの参照先を /tools/lib から /lib および /usr/lib に移す作業です

新システムの作成の前半の作業で、glibcをビルド・インストールしました。 それにより、標準Cライブラリは、/lib および /usr/lib に配置されています。

ただし、一時的な開発ツールのリンカは、まだ、ライブラリが /tools/lib にあるものだと思っています。 そこで、リンカおよびダイナミックリンカを調整し、/lib および /usr/lib のライブラリを利用するように変更を行います

チェンジルート

まずは、チェンジルート環境に入ります。


/root/chroot.sh

 

リンカの調整

次に、リンカを調整します。 /lib および /usr/lib のライブラリを利用するよう変更します。


rm -vf /tools/bin/ld
rm -vf /tools/$(gcc -dumpmachine)/bin/ld
mv -v /tools/bin/ld-new /tools/bin/ld
ln -vsf /tools/bin/ld   /tools/$(gcc -dumpmachine)/bin/ld

 

調整といっても、あらかじめ用意しておいた ld-new で置き換えるだけです

ダイナミックリンカの調整

続いて、ダイナミックリンカも調整します。 GCC用のスペックファイルを作成することで、ダイナミックリンカの参照先が /lib および /usr/lib となるように変更します。


gcc -dumpspecs | sed -e 's,/tools,,g' \
  -e '/\*startfile_prefix_spec:/{n;s,.*,/usr/lib/ ,}' \
  -e '/\*cpp:/{n;s,$, -isystem /usr/include,}' \
  > `dirname $(gcc --print-libgcc-file-name)`/specs

 

GCCの各ツールは、スペックと呼ばれる情報を元に、標準の振る舞いを決定します。 例えば、システムインクルードファイルを検索する場所、標準でリンクされるライブラリの一覧などです。

GCCのスペック情報は、GCCの各ツールの実行ファイル内に埋め込まれています。 利用者が何もしなければ、その内蔵のスペックが利用されます。 しかし、スペックファイルを別途用意することで、そのスペックファイルの内容でスペックを上書きすることができます

  
gcc -dumpspecsを実行することで、GCCの実行ファイルに埋め込まれている標準のスペックが表示されます。
  
gcc -dumpspecsの出力を sed で置換することで、新たなスペックファイルを生成しています。
  
"/tools" を削除し、設定項目 startfile_prefix_spec の設定値に "/usr/lib/" を記述し、設定項目 cpp の設定値に " -isystem /usr/include" を追記しています。
  
GCC 3.X系までは、標準のスペック情報はスペックファイルとして存在していました。 GCC 4.X系から、実行ファイルに内蔵されるようになりました。

調整した一時的な開発ツールのテスト

一時的な開発ツールの調整が終了しました。 ここでは、調整した一時的な開発ツールが正常に動作することを確認します

テスト用ソースファイルの作成

最初に、テスト用のソースファイルを作成します。


echo 'main(){}' > test.c

 

コンパイル・リンク

コンパイルおよびリンクを行います。


cc test.c -v -Wl,--verbose > test.log 2>&1

 
  
gcc ではなく cc でコンパイラを呼び出しています。

生成された実行ファイルのテスト

生成された実行ファイルの動作テストを行います。 共有ライブラリが、/lib から参照されていることを確認します。


readelf -l a.out | grep ': /lib'

 

以下が出力されることを確認します。

[Requesting program interpreter: /lib/ld-linux.so.2]

もし、/tools/libにある共有ライブラリが参照されていたなら、それは、標準Cライブラリの /lib および /usr/lib への切り替えが失敗しているということになります

  
正しい結果が得られなかった場合は、直前のバックアップから戻して作業をやり直してください。

crt1.o crti.o crtn.o が /usr/lib から検索されることを確認します。


grep '/usr/lib.*/crt[1in].*succeeded' test.log

 

以下が出力されることを確認します。

attempt to open /usr/lib/crt1.o succeeded
attempt to open /usr/lib/crti.o succeeded
attempt to open /usr/lib/crtn.o succeeded

/usr/lib以外のディレクトリから検索されている場合は、標準Cライブラリの /lib および /usr/lib への切り替えが失敗しているということです

  
正しい結果が得られなかった場合は、直前のバックアップから戻して作業をやり直してください。
  
crt1.o crti.o crtn.o というファイル名から、"C RunTime library"の略であり、ランタイムライブラリだと誤解している人が多いのですが、これらのファイルはランタイムライブラリではありません。
  
CRTという名称は、"C RunTime startup"の略であり、暗黙的にリンクされる関数です。 これらの関数は、main関数の前に呼び出され、内部では初期化処理を行っています。

インクルードファイルの検索パスに /usr/include が含まれていることを確認します。


grep -B1 '^ /usr/include' test.log

 

以下が出力されることを確認します。

#include <...> search starts here:
/usr/include

/usr/include がインクルードファイルの検索パスに含まれていない場合は、標準Cライブラリの /lib および /usr/lib への切り替えが失敗しているということです

  
正しい結果が得られなかった場合は、直前のバックアップから戻して作業をやり直してください。

ライブラリの検索パスに /lib および /usr/lib が含まれていることを確認します。


grep 'SEARCH.*/usr/lib' test.log | sed -e 's|; |\n|g' | sed -e '/-linux-gnu/d' | sort

 

以下が出力されることを確認します。

SEARCH_DIR("/lib");
SEARCH_DIR("/usr/lib")

/lib および /usr/lib がライブラリの検索パスに含まれていない場合は、標準Cライブラリの /lib および /usr/lib への切り替えが失敗しているということです

  
正しい結果が得られなかった場合は、直前のバックアップから戻して作業をやり直してください。

標準Cライブラリの共有ライブラリが、/lib から参照されていることを確認します。


grep "/lib.*/libc.so.6 " test.log

 

以下が出力されることを確認します。

attempt to open /lib/libc.so.6 succeeded

もし、/tools/libにあるディレクトリが参照されていたなら、それは、標準Cライブラリの /lib および /usr/lib への切り替えが失敗しているということになります

  
正しい結果が得られなかった場合は、直前のバックアップから戻して作業をやり直してください。

ダイナミックリンカの共有ライブラリが、/lib から参照されていることを確認します。


grep found test.log

 

以下が出力されることを確認します。

found ld-linux.so.2 at /lib/ld-linux.so.2

もし、/tools/libにあるディレクトリが参照されていたなら、それは、標準Cライブラリの /lib および /usr/lib への切り替えが失敗しているということになります

  
正しい結果が得られなかった場合は、直前のバックアップから戻して作業をやり直してください。

後始末

テスト用のソースファイルおよび生成された実行ファイルとログファイルを削除します。


rm -vf test.c a.out test.log

 
  

不要ファイルの削除

一時的な開発ツールの調整が終わりました。 ここで不要ファイルを削除します。

チェンジルートの終了

チェンジルートから抜けます。


exit

 

不要ファイルの削除

続いて、不要ファイルを削除します。


cd $MYLINUX/tmp
rm -fr * .[a-zA-Z0-9]*
cd $MYLINUX/var/log
mv btmp    $MYLINUX/tmp/
mv wtmp    $MYLINUX/tmp/
mv lastlog $MYLINUX/tmp/
rm -fr * .[a-zA-Z0-9]*
mv $MYLINUX/tmp/btmp    .
mv $MYLINUX/tmp/wtmp    .
mv $MYLINUX/tmp/lastlog .

 
  
$MYLINUX/tmp以下の全てのファイル、および、$MYLINUX/var/log以下の btmp, wtmp, lastlog 以外のファイルを削除しています。
  

バックアップ

1CD Linux用のパーティションをバックアップしておきます。


cd $MYLINUX
tar cvfj ./backups/mylinux.backup-06.tar.bz2 . --exclude=backups --exclude=sources --exclude=lost+found

 

一時的な開発ツールの調整直後のバックアップです。

 
メニュー