6.9. Glibc-2.19

Glibc 软件包包含主要的 C 库。这个库提供用于分配内存、搜索目录、开关读写文件、字符串处理、表达式匹配和算术等的基本途径。

预计构建时间: 17.1 SBU
磁盘空间需求: 922 MB

6.9.1. 安装 Glibc

[注意]

注意

LFS 之外的某些软件包推荐安装 GNU libiconv 用于转换文本编码。此工程的主页 (http://www.gnu.org/software/libiconv/) 表示 此库提供一个 iconv() 实现,用于没有提供此实现或无法操作 Unicode 的系统。 Glibc 提供一个 iconv() 实现并且可以操作 Unicode,所以在 LFS 系统上不必安装 libiconv。

先修复一个安装 tzselect 脚本时的小问题:

sed -i 's/\\$$(pwd)/`pwd`/' timezone/Makefile

一些 Glibc 程序使用非 FHS 兼容的 /var/db 目录来存储它们的运行时数据。使用下面的补丁让这些程序把它们的运行时数据存放在 FHS 兼容的位置:

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

Glibc 构建系统是自包含的,即使编译器的 specs 文件和链接器仍然指向 /tools 也能完美地构建。specs 和链接器不能在 Glibc 安装之前进行,因为 Glibc 的 autoconf 测试会给出不正确的结果,也就无法实现干净的构建。

Glibc 文档推荐在源代码目录外另建目录编译 Glibc:

mkdir -v ../glibc-build
cd ../glibc-build

准备编译 Glibc:

../glibc-2.19/configure    \
    --prefix=/usr          \
    --disable-profile      \
    --enable-kernel=2.6.32 \
    --enable-obsolete-rpc

配置选项的含义:

--enable-obsolete-rpc

安装默认没有安装的 NIS 和 RPC 相关的头文件;重新构建 glibc 和几个 BLFS 软件包需要它们。

编译软件包:

make
[重要]

重要

这一节中,Glibc 的测试套件是十分重要的。无论如何都不要跳过它。

通常有些测试无法通过,但你可以忽略以下列出的测试失败。现在测试结果:

make -k check 2>&1 | tee glibc-check-log
grep Error glibc-check-log

你很可能会在 posix/annexcconform/run-conformtest 测试中看到期待的 (被忽略的) 测试失败。另外,Glibc 略微依赖宿主系统。以下列出最常见的问题:

  • The nptl/tst-clock2nptl/tst-attr3tst/tst-cputimer1rt/tst-cpuclock2 已知无法通过。原因尚不完全明确,但可能是由于细微的时钟问题导致。

  • 在不太新的 Intel/AMD CPU 上数学测试有时会无法通过。

  • 在运行于较古老,较缓慢或者负荷很重的系统上时,有些测试会由于超时而无法通过。改动 make check 命令,设置一个 TIMEOUTFACTOR 已知可以减少这些错误 (例如 TIMEOUTFACTOR=16 make -k check

  • posix/tst-getaddrinfo4 总会失败,因为当 test 运行的时候没有网络连接。

  • libio/tst-ftell-partial-wide.out 会失败,因为它需要一个还没有被生成的 locale

  • 其它已知在某些架构上会失败的测试包括 Other tests known to fail on some architectures are posix/bug-regex32、misc/tst-writev、elf/check-textrel、nptl/tst-getpid2、nptl/tst-robust8 和 stdio-common/bug22。

虽然只是一个无害的消息,Glibc 的安装步骤会因为不存在 /etc/ld.so.conf 而报错。如此防止此警告:

touch /etc/ld.so.conf

安装软件包:

make install

nscd 安装配置文件和运行时目录:

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

Locale 可以使系统以不同的语言响应,但没有被以上的命令安装。这些 Locale 都不是必须的,但如果其中存在缺失,未来的软件包的测试套件可能会跳过重要的测试情况。

分立的区域数据可以使用 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

随后,安装你自己国家、语言和字符集的 Locale。

你可以用这样一条很消耗时间的命令一次性安装在 glibc-2.19/localedata/SUPPORTED 文件中列出的所有区域数据 (它包含以上所有,以及很多其他的区域数据):

make localedata/install-locales

然后使用 localedef 命令创建 glibc-2.19/localedata/SUPPORTED 文件中没有列出的区域数据。需要它们的情况并不多见。(译注:简体中文 UTF-8 的用户不需要如此)。

6.9.2. 配置 Glibc

需要创建 /etc/nsswitch.conf 这个文件,因为虽然 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

安装时区数据:

tar -xf ../tzdata2013i.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 iso3166.tab $ZONEINFO
zic -d $ZONEINFO -p America/New_York
unset ZONEINFO

zic 命令的含义:

zic -L /dev/null ...

此项创建 posix 时区,不包含闰秒。将它们置于 zoneinfozoneinfo/posix 是一种惯例。将 POSIX 时区置于 zoneinfo 中是必要的,否则有的测试套件就会报错。在嵌入式系统中,空间并不充足,你也不会想要更新时区,就可以忽略 posix 目录,能够节省 1.9MB,但是某些应用程序或者测试套件的结果可能不会很理想。

zic -L leapseconds ...

此项创建正确的时区,包括闰秒。在嵌入式系统中,空间并不充足,你也不会想要更新时区,也不在意精确的时间,就可以忽略 right 目录,能够节省 1.9MB。

zic ... -p ...

此项创建 posixrules 文件。我们使用纽约是因为 POSIX 要求有正确的、与美国规则协调的夏令时规则。

获知本地时区的一种方式是运行以下脚本:

tzselect

在回答几个有关位置的问题之后,脚本将会输出时区的名称 (例如 Asia/Shanghai)。还有一些可用的时区位于 /usr/share/zoneinfo,比如 Canada/EasternEST5EDT,它们不会被脚本识别但仍然可以使用。

接下来运行以下命令创建 /etc/localtime 文件:

cp -v /usr/share/zoneinfo/<xxx> /etc/localtime

<xxx> 替换为选中的时区 (例如 Asia/Shanghai)。

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

如果需要,动态链接器也可以搜索其他目录并包含其中的文件。通常此处的文件是一行,指定需要的库路径。要添加这种兼容性,运行以下命令:

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.4. Glibc 的内容

安装的程序: catchsegv, gencat, getconf, getent, iconv, iconvconfig, ldconfig, ldd, lddlibc4, locale, localedef, makedb, mtrace, nscd, pcprofiledump, pldd, rpcgen, sln, sotruss, sprof, tzselect, xtrace, zdump 和 zic
安装的库: ld.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, libpcprofile.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

打印出当前 locale 的信息

localedef

编译 locale 说明

makedb

由文本输入创建一个简单的数据库

mtrace

读取并且翻译内存追踪文件并以可读格式显示摘要

nscd

一个 daemon,提供最常见的名称服务请求的缓存

pcprofiledump

转储 PC 分析产生的信息

pldd

列出运行中的进程使用的动态共享对象

rpcgen

创建 C 代码实现远程过程调用 (RPC) 协议

sln

静态链接的 ln 程序

sotruss

追踪指定命令的共享库进程调用

sprof

读取并显示共享对象分析数据

tzselect

>询问用户系统的位置并报告对应的时区描述

xtrace

打印出正在执行的函数,追踪程序的执行

zdump

时区转储器

zic

时区编译器

ld.so

共享库应用程序的协助程序

libBrokenLocale

被 Glibc 内部用作一个总的修改,使得破损的程序 (如某些 Motif 应用) 能够运行。参考 glibc-2.19/locale/broken_cur_max.c 中的注释

libSegFault

段错误处理器,被 catchsegv 使用

libanl

一个异步名称查找库

libc

主要 C 库

libcidn

被 Glibc 内部 getaddrinfo() 函数用于处理国际化域名

libcrypt

加密库

libdl

动态链接接口库

libg

伪库,不包含任何函数。曾经是 g++ 的运行时库

libieee

链接进这个模块强制使数学函数的错误处理规则符合 IEEE 的定义。默认为 POSIX.1 错误处理

libm

数学库

libmcheck

在被链接的时候启动内存分配检查

libmemusage

memusage 用于协助收集有关程序内存使用的信息

libnsl

网络服务库

libnss

名称服务切换库,包含用于解析主机名、用户名、组名、对应、服务、协议等的函数

libpcprofile

包含分析函数,用于追踪指定源代码行使用的 CPU 时间数量

libpthread

POSIX 线程库

libresolv

包含用于对互联网域名服务器创建、发送、解释数据包的函数

librpcsvc

包含提供了各种 RPC 服务的函数

librt

包含提供了 POSIX.1b 试试扩展组件指定的多数接口的函数

libthread_db

包含用于构建多线程程序调试器的函数

libutil

包含很多不同的 Unix 工具使用的 标准 函数的代码