8.5. Glibc-2.39

Glibc パッケージは主要な C ライブラリを提供します。 このライブラリは基本的な処理ルーチンを含むもので、メモリ割り当て、ディレクトリ走査、ファイルのオープン、クローズや入出力、文字列操作、パターンマッチング、算術処理、等々があります。

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

8.5.1. Glibc のインストール

Glibc のプログラムの中には /var/db ディレクトリに実行データを収容するものがあり、これは FHS に準拠していません。 以下のパッチを適用することで、実行データの収容先を FHS 準拠のディレクトリとします。

patch -Np1 -i ../glibc-2.39-fhs-1.patch

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

mkdir -v build
cd       build

ldconfigsln ユーティリティーを /usr/sbin にインストールするようにします。

echo "rootsbindir=/usr/sbin" > configparms

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

../configure --prefix=/usr                            \
             --disable-werror                         \
             --enable-kernel=4.19                     \
             --enable-stack-protector=strong          \
             --disable-nscd                           \
             libc_cv_slibdir=/usr/lib

configure オプションの意味

--disable-werror

GCC に対して -werror オプションを利用しないようにします。 テストスイートを実行するために必要となります。

--enable-kernel=4.19

本オプションはビルドシステムに対して、カーネルバージョンが 4.19 のように古くても、 Glibc が利用されるように指示します。 これより古いバージョンにおけるシステムコールが用いられないようにするため、その回避策をとるものです。

--enable-stack-protector=strong

このオプション指定によりスタックに積まれる関数プリアンブル内に、追加のコードを付与することにより、システムセキュリティを向上させます。 その追加コードは、スタック破壊攻撃(stack smashing attacks)のようなバッファーオーバーフローをチェックします。 なお Glibc に対して明示的に指定されたオプションは、常に GCC のデフォルトを上書きします。 したがってこのオプションは、GCC に対して --enable-default-ssp の設定を行っているからこそ、ここでも指定が必要になります。

--disable-nscd

nscd (name service cache daemon) は使われることがないのでビルドしないようにします。

libc_cv_slibdir=/usr/lib

この変数によって、あらゆるシステムにおけるライブラリを正しく設定します。 lib64 は利用しません。

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

make
[重要]

重要

本節における Glibc のテストスイートは極めて重要なものです。 したがってどのような場合であっても必ず実行してください。

全般にテストの中には失敗するものがありますが、以下に示すものであれば無視しても構いません。

make check

テストに失敗する場合があります。 これは Glibc のテストスイートがホストシステムにある程度依存しているためです。 5000 を超えるテストの中で、ほんの少数のテストは失敗しますが、無視できるものです。 LFS の当バージョンにおいて発生しがちな問題を以下に示します。

  • io/tst-lchmod は LFS の chroot 環境においては失敗します。

  • nss/tst-nss-files-hosts-multinptl/tst-thread-affinity* のようなテストでは、タイムアウトを原因として (特に比較的処理性能の低いシステムの利用や平行ビルドを使ったテストスイート実行において) そのテストが失敗します。 このようなテストは以下を実行すれば一覧として得られます。

    grep "Timed out" -l $(find -name \*.out)

    TIMEOUTFACTOR=<factor> make test t=<test name> というコマンド実行により、テスト 1 つずつに対してタイムアウト時間を拡張して再実行することができます。 たとえば TIMEOUTFACTOR=10 make test t=nss/tst-nss-files-hosts-multi とすれば nss/tst-nss-files-hosts-multi のテストが、元々のタイムアウトの 10 倍としながら再実行できます。

  • さらに CPU モデルが古い場合に (たとえば elf/tst-cpu-features-cpuinfo が)、またホストのカーネルバージョンが古い場合に (たとえば stdlib/tst-arc4random-thread が)、それぞれ失敗することがあります。

支障が出る話ではありませんが Glibc のインストール時には /etc/ld.so.conf ファイルが存在していないとして警告メッセージが出力されます。 これをなくすために以下を実行します。

touch /etc/ld.so.conf

Makefile を修正して、古くなった健全性チェックをスキップするようにします。 これは、この段階での LFS 環境では失敗するためです。

sed '/test-installation/s@$(PERL)@echo not running@' -i ../Makefile
[重要]

重要

稼働中の LFS システムにおいて Glibc のマイナーバージョンを最新のものにアップグレードする場合 (たとえば Glibc-2.36 を Glibc-2.39 にあげる場合)、いくつか追加の措置を講じることで、システムが壊れないようにすることが必要です。

  • 11.0 未満の Glibc をアップグレードすることは LFS システムにおいてはサポートしていません。 そのような古い LFS システムにおいて最新の Glibc が必要になる場合は、LFS を再構築してください。

  • 12.0 未満の Glibc をアップグレードする場合は 「Libxcrypt-4.4.36.」 に従って Libxcrypt をインストールしてください。 さらにその Libxcrypt の通常インストール手順に加えて、Libxcrypt の注記の節に示されている手順に従って libcrypt.so.1* のインストールを必ず行ってください (それ以前に行っている Glibc のビルドにおいてインストールした libcrypt.so.1 を置き換えてください)。.

  • 12.1 未満の Glibc をアップグレードする場合は nscd プログラムを削除してください。

    rm -f /usr/sbin/nscd
  • (現時点のカーネルバージョンは uname -r により確認することができますが) 4.19 よりも古いカーネルをアップグレードして再起動する場合には 「Linux-6.7.4」 の説明に従ってください。

  • (現時点の API ヘッダーバージョンは cat /usr/include/linux/version.h により確認することができますが) 4.19 よりも古い API ヘッダーをアップグレードする場合は、「Linux-6.7.4 API ヘッダー」 の説明に従ってください (ただし cp コマンドからは $LFS を取り除いてください)。

  • DESTDIR を利用したインストール方法により Glibc の共有ライブラリをアップグレードする場合には、以下のように一つの install コマンドにより行ってください。

    make DESTDIR=$PWD/dest install
    install -vm755 dest/usr/lib/*.so.* /usr/lib

自分が何をしているのかを完全に理解できていないのであれば、この手順に忠実に従ってください。 不用意にこの手順を見逃して進めてしまうと、システムが完全に利用不能になりかねません。ここに警告しておきます。

make install コマンド、/usr/bin/ldd に対する sed コマンド、ロケールをインストールするコマンドを順に実行します。 ここまで行ったら即座にシステムを再起動してください。

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

make install

ldd スクリプト内にある実行可能なローダーへのパスがハードコーディングされているので、これを修正します。

sed '/RTLDLIST=/s@/usr@@g' -i /usr/bin/ldd

システムを各種の言語に対応させるためのロケールをインストールします。 テストスイートにおいてロケールは必要ではありませんが、ロケールが不足していることによって、重要なテストが実施されずに見逃してしまうパッケージがあるかもしれません。

各ロケールは localedef プログラムを使ってインストールします。 例えば以下に示す 2 つめの localedef では、キャラクターセットには依存しないロケール定義 /usr/share/i18n/locales/cs_CZ とキャラクターマップ定義 /usr/share/i18n/charmaps/UTF-8.gz とを結合させて /usr/lib/locale/locale-archive ファイルにその情報を付け加えます。 以下のコマンドは、テストを成功させるために必要となる最低限のロケールをインストールするものです。

mkdir -pv /usr/lib/locale
localedef -i C -f UTF-8 C.UTF-8
localedef -i cs_CZ -f UTF-8 cs_CZ.UTF-8
localedef -i de_DE -f ISO-8859-1 de_DE
localedef -i de_DE@euro -f ISO-8859-15 de_DE@euro
localedef -i de_DE -f UTF-8 de_DE.UTF-8
localedef -i el_GR -f ISO-8859-7 el_GR
localedef -i en_GB -f ISO-8859-1 en_GB
localedef -i en_GB -f UTF-8 en_GB.UTF-8
localedef -i en_HK -f ISO-8859-1 en_HK
localedef -i en_PH -f ISO-8859-1 en_PH
localedef -i en_US -f ISO-8859-1 en_US
localedef -i en_US -f UTF-8 en_US.UTF-8
localedef -i es_ES -f ISO-8859-15 es_ES@euro
localedef -i es_MX -f ISO-8859-1 es_MX
localedef -i fa_IR -f UTF-8 fa_IR
localedef -i fr_FR -f ISO-8859-1 fr_FR
localedef -i fr_FR@euro -f ISO-8859-15 fr_FR@euro
localedef -i fr_FR -f UTF-8 fr_FR.UTF-8
localedef -i is_IS -f ISO-8859-1 is_IS
localedef -i is_IS -f UTF-8 is_IS.UTF-8
localedef -i it_IT -f ISO-8859-1 it_IT
localedef -i it_IT -f ISO-8859-15 it_IT@euro
localedef -i it_IT -f UTF-8 it_IT.UTF-8
localedef -i ja_JP -f EUC-JP ja_JP
localedef -i ja_JP -f SHIFT_JIS ja_JP.SJIS 2> /dev/null || true
localedef -i ja_JP -f UTF-8 ja_JP.UTF-8
localedef -i nl_NL@euro -f ISO-8859-15 nl_NL@euro
localedef -i ru_RU -f KOI8-R ru_RU.KOI8-R
localedef -i ru_RU -f UTF-8 ru_RU.UTF-8
localedef -i se_NO -f UTF-8 se_NO.UTF-8
localedef -i ta_IN -f UTF-8 ta_IN.UTF-8
localedef -i tr_TR -f UTF-8 tr_TR.UTF-8
localedef -i zh_CN -f GB18030 zh_CN.GB18030
localedef -i zh_HK -f BIG5-HKSCS zh_HK.BIG5-HKSCS
localedef -i zh_TW -f UTF-8 zh_TW.UTF-8

上に加えて、あなたの国、言語、キャラクターセットを定めるためのロケールをインストールしてください。

必要に応じて glibc-2.39/localedata/SUPPORTED に示されるすべてのロケールを同時にインストールしてください。(そこには上のロケールも含め、すべてのロケールが列記されています。) 以下のコマンドによりそれを実現します。 ただしこれには相当な処理時間を要します。

make localedata/install-locales

さらに必要なら glibc-2.39/localedata/SUPPORTED ファイルに示されていないロケールは localedef コマンドを使って生成、インストールを行ってください。 たとえば以下の 2 つのロケールは、本章で後に実施するテストにおいて必要になります。

localedef -i C -f UTF-8 C.UTF-8
localedef -i ja_JP -f SHIFT_JIS ja_JP.SJIS 2> /dev/null || true
[注記]

注記

現状の Glibc は、国際ドメイン名の解決に libidn2 を利用します。 これは実行時に依存するパッケージです。 この機能が必要である場合は、BLFS にある libidn2 ページに示されているインストール手順を参照してください。

8.5.2. Glibc の設定

8.5.2.1. nsswitch.conf の追加

/etc/nsswitch.conf ファイルを作成しておく必要があります。 このファイルが無い場合、Glibc のデフォルト値ではネットワーク環境下にて Glibc が正しく動作しません。

以下のコマンドを実行して /etc/nsswitch.conf ファイルを生成します。

cat > /etc/nsswitch.conf << "EOF"
# Begin /etc/nsswitch.conf

passwd: files
group: files
shadow: files

hosts: files dns
networks: files

protocols: files
services: files
ethers: files
rpc: files

# End /etc/nsswitch.conf
EOF

8.5.2.2. タイムゾーンデータの追加

以下によりタイムゾーンデータをインストールし設定します。

tar -xf ../../tzdata2024a.tar.gz

ZONEINFO=/usr/share/zoneinfo
mkdir -pv $ZONEINFO/{posix,right}

for tz in etcetera southamerica northamerica europe africa antarctica  \
          asia australasia backward; do
    zic -L /dev/null   -d $ZONEINFO       ${tz}
    zic -L /dev/null   -d $ZONEINFO/posix ${tz}
    zic -L leapseconds -d $ZONEINFO/right ${tz}
done

cp -v zone.tab zone1970.tab iso3166.tab $ZONEINFO
zic -d $ZONEINFO -p America/New_York
unset ZONEINFO

zic コマンドの意味

zic -L /dev/null ...

うるう秒を含まない posix タイムゾーンデータを生成します。 これらは zoneinfozoneinfo/posix に収容するものとして適切なものです。 zoneinfo へは POSIX 準拠のタイムゾーンデータを含めることが必要であり、こうしておかないと数々のテストスイートにてエラーが発生してしまいます。 組み込みシステムなどでは容量の制約が厳しいため、タイムゾーンデータはあまり更新したくない場合があり、posix ディレクトリを設けなければ 1.9 MB もの容量を節約できます。 ただしアプリケーションやテストスイートによっては、エラーが発生するかもしれません。

zic -L leapseconds ...

うるう秒を含んだ正しいタイムゾーンデータを生成します。 組み込みシステムなどでは容量の制約が厳しいため、タイムゾーンデータはあまり更新したくない場合や、さほど気にかけない場合もあります。 right ディレクトリを省略することにすれば 1.9MB の容量を節約することができます。

zic ... -p ...

posixrules ファイルを生成します。 ここでは New York を用います。 POSIX では、日中の保存時刻として US ルールに従うことを規程しているためです。

ローカルなタイムゾーンの設定を行う1つの方法として、ここでは以下のスクリプトを実行します。

tzselect

地域情報を設定するためにいくつか尋ねられるのでそれに答えます。 このスクリプトはタイムゾーン名を表示します。(例えば America/Edmonton などです。) /usr/share/zoneinfo ディレクトリにはさらに Canada/EasternEST5EDT のようなタイムゾーンもあります。 これらはこのスクリプトでは認識されませんが、利用することは可能です。

以下のコマンドにより /etc/localtime ファイルを生成します。

ln -sfv /usr/share/zoneinfo/<xxx> /etc/localtime

<xxx> の部分は設定するタイムゾーンの名前 (例えば Canada/Eastern など) に置き換えてください。

8.5.2.3. ダイナミックローダー の設定

ダイナミックリンカー (/lib/ld-linux.so.2) がダイナミックライブラリを検索するデフォルトのディレクトリが /usr/lib ディレクトリです。 各種プログラムが実行される際にはここから検索されたダイナミックライブラリがリンクされます。 もし /usr/lib 以外のディレクトリにライブラリファイルがあるなら /etc/ld.so.conf ファイルに記述を追加して、ダイナミックローダーがそれらを探し出せるようにしておくことが必要です。 追加のライブラリが配置されるディレクトリとしては /usr/local/lib ディレクトリと /opt/lib ディレクトリという二つがよく利用されます。 ダイナミックローダーの検索パスとして、それらのディレクトリを追加します。

以下のコマンドを実行して /etc/ld.so.conf ファイルを新たに生成します。

cat > /etc/ld.so.conf << "EOF"
# Begin /etc/ld.so.conf
/usr/local/lib
/opt/lib

EOF

必要がある場合には、ダイナミックローダーに対する設定として、他ディレクトリにて指定されるファイルをインクルードするようにもできます。 通常は、そのファイル内の1行に、必要となるライブラリパスを記述します。 このような設定を利用する場合には以下のようなコマンドを実行します。

cat >> /etc/ld.so.conf << "EOF"
# Add an include directory
include /etc/ld.so.conf.d/*.conf

EOF
mkdir -pv /etc/ld.so.conf.d

8.5.3. Glibc の構成

インストールプログラム: gencat, getconf, getent, iconv, iconvconfig, ldconfig, ldd, lddlibc4, ld.so (ld-linux-x86-64.so.2 または ld-linux.so.2 へのリンク), locale, localedef, makedb, mtrace, pcprofiledump, pldd, sln, sotruss, sprof, tzselect, xtrace, zdump, zic
インストールライブラリ: ld-linux-x86-64.so.2, ld-linux.so.2, libBrokenLocale.{a,so}, libanl.{a,so}, libc.{a,so}, libc_nonshared.a, libc_malloc_debug.so, libdl.{a,so.2}, libg.a, libm.{a,so}, libmcheck.a, libmemusage.so, libmvec.{a,so}, libnsl.so.1, libnss_compat.so, libnss_dns.so, libnss_files.so, libnss_hesiod.so, libpcprofile.so, libpthread.{a,so.0}, libresolv.{a,so}, librt.{a,so.1}, libthread_db.so, and libutil.{a,so.1}
インストールディレクトリ: /usr/include/arpa, /usr/include/bits, /usr/include/gnu, /usr/include/net, /usr/include/netash, /usr/include/netatalk, /usr/include/netax25, /usr/include/neteconet, /usr/include/netinet, /usr/include/netipx, /usr/include/netiucv, /usr/include/netpacket, /usr/include/netrom, /usr/include/netrose, /usr/include/nfs, /usr/include/protocols, /usr/include/rpc, /usr/include/sys, /usr/lib/audit, /usr/lib/gconv, /usr/lib/locale, /usr/libexec/getconf, /usr/share/i18n, /usr/share/zoneinfo, /var/lib/nss_db

概略説明

gencat

メッセージカタログを生成します。

getconf

ファイルシステムに固有の変数に設定された値を表示します。

getent

管理データベースから設定項目を取得します。

iconv

キャラクターセットを変換します。

iconvconfig

高速ロードができる iconv モジュール設定ファイルを生成します。

ldconfig

ダイナミックリンカーの実行時バインディングを設定します。

ldd

指定したプログラムまたは共有ライブラリが必要としている共有ライブラリを表示します。

lddlibc4

オブジェクトファイルを使って ldd コマンドを補助します。 これは x86_64 のような最新アーキテクチャーには存在しません。

locale

現在のロケールに対するさまざまな情報を表示します。

localedef

ロケールの設定をコンパイルします。

makedb

テキストを入力として単純なデータベースを生成します。

mtrace

メモリトレースファイル (memory trace file) を読み込んで解釈します。 そして可読可能な書式で出力します。

pcprofiledump

PC プロファイリングによって生成された情報をダンプします。

pldd

稼動中のプロセスにて利用されている動的共有オブジェクト (dynamic shared objects) を一覧出力します。

sln

スタティックなリンクを行う ln プログラム。

sotruss

指定されたコマンドの共有ライブラリ内のプロシジャーコールをトレースします。

sprof

共有オブジェクトのプロファイリングデータを読み込んで表示します。

tzselect

ユーザーに対してシステムの設置地域を問合せ、対応するタイムゾーンの記述を表示します。

xtrace

プログラム内にて現在実行されている関数を表示することで、そのプログラムの実行状況を追跡します。

zdump

タイムゾーンをダンプします。

zic

タイムゾーンコンパイラー。

ld-*.so

共有ライブラリのためのヘルパープログラム。

libBrokenLocale

Glibc が内部で利用するもので、異常が発生しているプログラムを見つけ出します。(例えば Motif アプリケーションなど) 詳しくは glibc-2.39/locale/broken_cur_max.c に書かれたコメントを参照してください。

libanl

関数を何も含まないダミーライブラリ。 かつては非同期の名前解決 (asynchronous name lookup) ライブラリでしたが、今その関数は libc に含まれます。

libc

主要な C ライブラリ。

libc_malloc_debug

プリロード時のメモリ割り当てチェックをオンにします。

libdl

何の関数も含まないダミーライブラリ。 以前はダイナミックリンクインターフェースライブラリでしたが、現在その関数は libc に含まれるようになりました。

libg

何の関数も含まないダミーのライブラリ。 かつては g++ のランタイムライブラリであったものです。

libm

数学ライブラリ。

libmvec

ベクトル数学ライブラリ。 libm が用いられる際に必要となるためリンクされます。

libmcheck

このライブラリにリンクした場合、メモリ割り当てのチェック機能を有効にします。

libmemusage

memusage コマンドが利用するもので、プログラムのメモリ使用に関する情報を収集します。

libnsl

ネットワークサービスライブラリ。 現在は非推奨。

libnss_*

NSS (Name Service Switch) モジュール。 ホスト、ユーザー名、エイリアス、サービス、プロトコルなどの名前解決を行う関数を提供します。 /etc/nsswitch.conf での設定に従って libc によりロードされます。

libpcprofile

PC プロファイルにたいして実行モジュールをプリロードするために用いられます。

libpthread

関数を全く含まないダミーのライブラリ。 かつては POSIX.1c Threads Extensions によって規定されているインターフェースと、POSIX.1b Real-time Extensions によって規定されるセマフォーインターフェースをほとんど含めた関数を提供していました。 現在その関数は libc に含まれるようになりました。

libresolv

インターネットドメインネームサーバーに対しての、パケットの生成、送信、解析を行う関数を提供します。

librt

POSIX.1b リアルタイム拡張 (Realtime Extension) にて既定されているインターフェースをほぼ網羅した関数を提供します。

libthread_db

マルチスレッドプログラム用のデバッガーを構築するための有用な関数を提供します。

libutil

何の関数も含まないダミーライブラリ。 以前は、 さまざまな Unix ユーティリティーに用いられる標準的な関数のコードを含んでいました。 現在その関数は libc に含まれるようになりました。