6.9. Glibc-2.26

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

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

6.9.1. Glibc のインストール

[注記]

注記

Glibc ビルドシステムは自らによってビルドされるものであり、コンパイラースペックファイルがたとえ /tools を指し示していたままであっても完璧にビルドされます。 スペックやリンカーは Glibc のインストール後でないと調整できません。 これは Glibc の autoconf テストが失敗するからであり、クリーンビルドを成功させるという目標が達成できないためです。

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

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

最終の glibc において /tools への参照をなくすためにシンボリックリンクを生成します。

ln -sfv /tools/lib/gcc /usr/lib

GCC のインクルードディレクトリを明示して LSB コンプライアンスに従ったシンボリックリンクを作成します。 さらに x86_64 向けにダイナミックローダーが正しく機能するために必要なシンボリックリンクを作成します。

case $(uname -m) in
    i?86)    GCC_INCDIR=/usr/lib/gcc/$(uname -m)-pc-linux-gnu/7.2.0/include
            ln -sfv ld-linux.so.2 /lib/ld-lsb.so.3
    ;;
    x86_64) GCC_INCDIR=/usr/lib/gcc/x86_64-pc-linux-gnu/7.2.0/include
            ln -sfv ../lib/ld-linux-x86-64.so.2 /lib64
            ln -sfv ../lib/ld-linux-x86-64.so.2 /lib64/ld-lsb-x86-64.so.3
    ;;
esac

直前にビルドをやりかけていた場合に、残ってしまうファイルを削除します。

rm -f /usr/include/limits.h

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

mkdir -v build
cd       build

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

CC="gcc -isystem $GCC_INCDIR -isystem /usr/include" \
../configure --prefix=/usr                          \
             --disable-werror                       \
             --enable-kernel=3.2                    \
             --enable-stack-protector=strong        \
             libc_cv_slibdir=/lib
unset GCC_INCDIR

configure オプションおよびパラメーターの意味:

CC="gcc -isystem $GCC_INCDIR -isystem /usr/include"

gcc とシステムのインクルードディレクトリを指定します。 これによりデバッグシンボル内に誤ったパスが含まれないようにします。

--disable-werror

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

--enable-stack-protector=strong

このオプション指定によりスタックに積まれる関数プリアンブル内に、ランダムな整数であるカナリア (canary) 値を付与し、システムセキュリティを向上させます。 関数から戻る際にこの値がチェックされるため、値が変わっていればスタックオーバーフローがあったということでプログラムが異常終了します。

libc_cv_slibdir=/lib

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

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

make
[重要項目]

重要項目

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

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

make check

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

  • posix/tst-getaddrinfo4posix/tst-getaddrinfo5 は特定の CPU アーキテクチャーでは失敗します。

  • rt/tst-cputimer1rt/tst-cpuclock2 のテストは失敗することが知られています。 失敗の理由は明確ではありません。 ただ処理速度が原因してそれらが発生すると思われます。

  • math テストは、Intel プロセッサーや AMD プロセッサーが最新のものではない場合に失敗することがあります。

  • nptl/tst-thread-affinity-{pthread,pthread2,sched} テストは失敗しますが、その理由は不明です。

  • 上記以外に特定のアーキテクチャーにてテストが失敗することが分かっています。 失敗するのは malloc/tst-malloc-usable, nptl/tst-cleanupx4 です。

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

touch /etc/ld.so.conf

Makefile に生成された不要な健全性チェックを無効にします。 これは、この段階での LFS 環境では失敗するためです。

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

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

make install

nscd コマンドに対する設定ファイルや実行ディレクトリをインストールします。

cp -v ../nscd/nscd.conf /etc/nscd.conf
mkdir -pv /var/cache/nscd

nscd コマンドに対しての systemd サポートファイルをインストールします。

install -v -Dm644 ../nscd/nscd.tmpfiles /usr/lib/tmpfiles.d/nscd.conf
install -v -Dm644 ../nscd/nscd.service /lib/systemd/system/nscd.service

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

各ロケールは localedef プログラムを使ってインストールします。 例えば以下に示す一つめの 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 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 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_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 it_IT -f ISO-8859-1 it_IT
localedef -i it_IT -f UTF-8 it_IT.UTF-8
localedef -i ja_JP -f EUC-JP ja_JP
localedef -i ru_RU -f KOI8-R ru_RU.KOI8-R
localedef -i ru_RU -f UTF-8 ru_RU.UTF-8
localedef -i tr_TR -f UTF-8 tr_TR.UTF-8
localedef -i zh_CN -f GB18030 zh_CN.GB18030

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

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

make localedata/install-locales

さらに必要なら glibc-2.26/localedata/SUPPORTED ファイルに示されていない特殊なロケールは localedef コマンドを使って生成、インストールを行ってください。

6.9.2. Glibc の設定

6.9.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

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

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

tar -xf ../../tzdata2017b.tar.gz

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

for tz in etcetera southamerica northamerica europe africa antarctica  \
          asia australasia backward pacificnew systemv; do
    zic -L /dev/null   -d $ZONEINFO       -y "sh yearistype.sh" ${tz}
    zic -L /dev/null   -d $ZONEINFO/posix -y "sh yearistype.sh" ${tz}
    zic -L leapseconds -d $ZONEINFO/right -y "sh yearistype.sh" ${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 など) に置き換えてください。

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

ダイナミックリンカー (/lib/ld-linux.so.2) がダイナミックライブラリを検索するデフォルトのディレクトリが /lib ディレクトリと /usr/lib ディレクトリです。 各種プログラムが実行される際にはここから検索されたダイナミックライブラリがリンクされます。 もし /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

6.9.3. Glibc の構成

インストールプログラム: catchsegv, gencat, getconf, getent, iconv, iconvconfig, ldconfig, ldd, lddlibc4, locale, localedef, makedb, mtrace, nscd, pldd, sln, sotruss, sprof, tzselect, xtrace, zdump, zic
インストールライブラリ: ld-2.26.so, libBrokenLocale.{a,so}, libSegFault.so, libanl.{a,so}, libc.{a,so}, libc_nonshared.a, libcidn.so, libcrypt.{a,so}, libdl.{a,so}, libg.a, libieee.a, libm.{a,so}, libmcheck.a, libmemusage.so, libnsl.{a,so}, libnss_compat.so, libnss_dns.so, libnss_files.so, libnss_hesiod.so, libnss_nis.so, libnss_nisplus.so, libpthread.{a,so}, libpthread_nonshared.a, libresolv.{a,so}, librpcsvc.a, librt.{a,so}, libthread_db.so, libutil.{a,so}
インストールディレクトリ: /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/rpcsvc, /usr/include/sys, /usr/lib/audit, /usr/lib/gconv, /usr/lib/locale, /usr/libexec/getconf, /usr/share/i18n, /usr/share/zoneinfo, /var/cache/nscd, /var/lib/nss_db

概略説明

catchsegv

プログラムがセグメンテーションフォールトにより停止した時に、スタックトレースを生成するために利用します。

gencat

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

getconf

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

getent

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

iconv

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

iconvconfig

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

ldconfig

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

ldd

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

lddlibc4

オブジェクトファイルを使って ldd コマンドを補助します。[訳註:意味不明]

locale

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

localedef

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

makedb

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

mtrace

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

nscd

一般的なネームサービスへの変更要求のキャッシュを提供するデーモン。

pldd

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

sln

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

sotruss

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

sprof

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

tzselect

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

xtrace

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

zdump

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

zic

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

ld-2.26.so

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

libBrokenLocale

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

libSegFault

セグメンテーションフォールトのシグナルハンドラー。 catchsegv が利用します。

libanl

非同期の名前解決 (asynchronous name lookup) ライブラリ。

libc

主要な C ライブラリ。

libcidn

Glibc が内部的に利用するもので getaddrinfo() 関数によって国際化ドメイン名 (internationalized domain names) を取り扱います。

libcrypt

暗号化ライブラリ。

libdl

ダイナミックリンクのインターフェースライブラリ。

libg

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

libieee

このモジュールをリンクすると、数学関数におけるエラー制御方法を IEEE (the Institute of Electrical and Electronic Engineers) が定義するものに従うようになります。 デフォルトは POSIX.1 エラー制御方法です。

libm

数学ライブラリ。

libmcheck

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

libmemusage

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

libnsl

ネットワークサービスライブラリ。

libnss

NSS (Name Service Switch) ライブラリ。 ホスト、ユーザー名、エイリアス、サービス、プロトコルなどの名前解決を行う関数を提供します。

libpthread

POSIX スレッドライブラリ。

libresolv

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

librpcsvc

さまざまな RPC サービスを実現する関数を提供します。

librt

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

libthread_db

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

libutil

数多くの Unix ユーティリティにて利用される標準関数を提供します。