6.9. Glibc-2.11.1

Glibc 软件包包含主要的 C 库。这个库提供了基本例程, 用于分配内存、 搜索目录、 打开关闭文件、 读写文件、 字串处理、模式匹配、数学计算等等。

预计编译时间: 16.9 SBU 包括测试
所需磁盘空间: 637 MB 包括测试

6.9.1. 安装 Glibc

[Note]

注意

一些 LFS 基本系统之外的软件包建议安装 GNU libiconv 以使得数据够能在不同编码之间进行转换。该项目的主页 (http://www.gnu.org/software/libiconv/) 说:"这个库为那些没有 iconv() 的系统或者虽然有 iconv() 却不能与 Unicode 相互转换的系统提供了一个能够与 Unicode 相互转换的实现 "。Glibc 库中有一个 iconv() ,并且能够与 Unicode 相互转换, 因此,LFS 系统不需要 GNU libiconv 。

Glibc 的编译系统是高度自给自足的,即使当前编译器 specs 文件和连接器还指向 /tools 目录,也能正确安装。我们在安装 Glibc 前不能调整 specs 文件和连接器,否则 Glibc 的 autoconf 测试会失败,从而妨碍我们创建一个干净系统的目标。

当运行 make install 时,一个叫做 test-installation.pl 的脚本会在我们新安装的 Glibc 上做一个小的完整性测试。然而,由于我们的 toolchain 仍然指向 /tools 目录, 完整性测试会导致使用错误的Glibc。安装下面的操作, 我们可以强制脚本测试我们刚安装的 Glibc:

DL=$(readelf -l /bin/sh | sed -n 's@.*interpret.*/tools\(.*\)]$@\1@p')
sed -i "s|libs -o|libs -L/usr/lib -Wl,-dynamic-linker=$DL -o|" \
        scripts/test-installation.pl
unset DL

ldd shell 脚本包含 Bash-specific 语法。 如果参照BLFS文档的 Shells章节安装了其他的 /bin/sh 的话,要把它的默认程序解释器改变为 /bin/bash

sed -i 's|@BASH@|/bin/bash|' elf/ldd.bash.in

Glibc 文档推荐在源码目录之外的一个专门的编译目录下进行编译:

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

因为在 Chapter 5 中, 为x86机器加入了需要的编译器标志 CFLAGS, 所以,在这里,我们也要设置库的优化,使gcc 编译器提高编译速度(-pipe) 和包的性能 (-O3)。

case `uname -m` in
  i?86) echo "CFLAGS += -march=i486 -mtune=native -O3 -pipe" > configparms ;;
esac

为编译 Glibc 做准备:

../glibc-2.11.1/configure --prefix=/usr \
    --disable-profile --enable-add-ons \
    --enable-kernel=2.6.18 --libexecdir=/usr/lib/glibc

新配置参数的含义:

--libexecdir=/usr/lib/glibc

该参数将 pt_chown 程序的默认位置从 /usr/libexec 改为 /usr/lib/glibc

编译这个软件包:

make
[Important]

重要

本节的 Glibc 测试很重要。在任何情况下都不要省略这一步。

执行测试程序前,为了避免测试出错,我们要从源目录中拷贝一个文件到编译目录, 然后对结果进行测试:

cp -v ../glibc-2.11.1/iconvdata/gconv-modules iconvdata
make -k check 2>&1 | tee glibc-check-log
grep Error glibc-check-log

posix/annexc 测试中,你可能会看到一个预料的错误(可以忽略)。 另外, Glibc 测试组件 多少要依赖于宿主系统。 下面是一些常见错误的列表:

  • nptl/tst-clock2, nptl/tst-attr3, 和 rt/tst-cpuclock2 的测试已知会出错。 原因现在还不是很明白, 可能是系统负载过重导致的。

  • math 测试在一些使用较老的 Intel 或 AMD 的系统上会失败。

  • 如果你带 noatime 参数挂载 LFS 分区的话, atime 测试会失败。正如在 Section 2.4, “挂载这个新分区”,中提到的,在编译LFS过程中不要使用 noatime 选项。

  • 在一些很老很慢的硬件或系统上运行时,一些测试会由于超时而失败。

在安装 Glibc 的过程中,它会警告缺少 /etc/ld.so.conf 文件。 其实这没什么关系, 不过下面的命令能修正它:

touch /etc/ld.so.conf

安装这个软件包:

make install

locales 能使系统以一种上面命令没有安装的语言处理。 locales 不是必须的,但是如果他们中的一些丢失了, 后面的测试单元会跳过重要测试。

单个的 locales可以通过使用localedef程序来安装。例如,下面的第一个 localedef命令将 /usr/share/i18n/locales/cs_CZ 字符集独立的区域设置定义和 /usr/share/i18n/charmaps/UTF-8.gz 字符表定义相结合, 并将结果添加到 /usr/lib/locale/locale-archive 文件中。 下面的说明将会安装一个通过测试所需locale的最小集合:

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_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 ja_JP -f EUC-JP ja_JP
localedef -i tr_TR -f UTF-8 tr_TR.UTF-8
localedef -i zh_CN -f GB18030 zh_CN.GB18030

另外,你可以安装你的国家、语言和字符集所对应的 locale 。

当然,利用下面的命令,你可以一次安装所有列在 glibc-2.11.1/localedata/SUPPORTED 文件 (它包括上面所列的以及更多的locale) 中的locales:

make localedata/install-locales

然后使用 localedef 命令来创建和安装没有列在glibc-2.11.1/localedata/SUPPORTED 文件中的locales(这种情况不太可能), 如果你需要他们的话。

6.9.2. 配置 Glibc

我们需要创建 /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

要想确定本地时区,可以使用下面的脚本:

tzselect

按照顺序回答脚本运行过程中提出的几个问题后,脚本就会给出所需时区文件的位置(比如 America/Edmonton)。 还有其他的一些时区列在 /usr/share/zoneinfo中,比如 Canada/EasternEST5EDT 这些虽然没有被脚本识别,但是都可以使用。

再用下列命令来创建 /etc/localtime

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

<xxx> 替换成选择的时区的名称(比如, Canada/Eastern)。

cp命令选项的含义:

--remove-destination

该选项强制删除已存在的符号链接。 我们采用拷贝文件而不是创建符号链接的原因是:有可能 /usr 在单独的分区上,如果启动进入单用户模式,就会出问题。

6.9.3. 配置动态链接库加载程序

默认情况下,动态链接库加载程序 (/lib/ld-linux.so.2) 搜索 /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

# End /etc/ld.so.conf
EOF

6.9.4. Glibc 的文件

安装的程序: catchsegv, gencat, getconf, getent, iconv, iconvconfig, ldconfig, ldd, lddlibc4, locale, localedef, mtrace, nscd, pcprofiledump, pt_chown, rpcgen, rpcinfo, sln, sprof, tzselect, xtrace, zdump, and zic
安装的库:: ld.so, libBrokenLocale.{a,so}, libSegFault.so, libanl.{a,so}, libbsd-compat.a, 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, and libutil.{a,so}

简要描述

catchsegv

当程序发生段故障的时候,用来建立一个堆栈跟踪

gencat

建立消息列表

getconf

针对文件系统的指定变量显示其系统设置值

getent

从系统管理数据库获取一个条目

iconv

字符集转换

iconvconfig

建立快速加载的iconv模块所使用的配置文件

ldconfig

配置动态链接库的实时绑定

ldd

报告每个给定程序或共享库的共享库

lddlibc4

帮助 ldd 操作目标文件

locale

打印当前locale的详细信息

localedef

编译 locale 标准

mtrace

读取并解释一个内存跟踪文件然后以人类可读的格式显示一个摘要

nscd

为最常用的名称服务请求提供缓存的守护进程

pcprofiledump

转储 PC profiling 产生的信息

pt_chown

一个辅助程序,帮助 grantpt 设置子虚拟终端的属主、 用户组、 读写权限

rpcgen

产生实现远程过程调用(RPC)协议的 C 代码

rpcinfo

对 RPC 服务器产生一个 RPC 呼叫

sln

ln 程序使用静态连接编译的版本

sprof

读取并显示共享目标的特征描述数据

tzselect

对用户提出关于当前位置的问题并输出时区信息到标准输出

xtrace

通过打印当前执行的函数跟踪程序执行情况

zdump

显示时区

zic

时区编译器

ld.so

帮助动态链接库执行的辅助程序

libBrokenLocale

当黑客破坏了程序(例如,一些有动机的应用程序) 的运行时,由 Glibc 在内部使用。更多的细节,请参考 glibc-2.11.1/locale/broken_cur_max.c

libSegFault

The segmentation fault signal handler, used by catchsegv

libanl

异步名称查询库

libbsd-compat

为了在 linux 下执行一些 BSD 程序,libbsd-compat 提供了必要的可移植性

libc

主 C 库

libcidn

被Glibc使用,在 getaddrinfo() 函数中来处理国际域名

libcrypt

用于加密的库

libdl

动态连接接口库

libg

不含功能的虚拟库。以前是g++ 运行时库

libieee

强制数学函数错误处理规则链接到电气和电子工程师协会 (IEEE)定义的模块。 默认的错误处理是 POSIX.1

libm

数学函数库

libmcheck

链接时,打开内存分配检查

libmemusage

帮助 memusage搜集程序运行时的内存占用信息

libnsl

网络服务库

libnss

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

libpcprofile

包含用于跟踪某些特定源代码的 CPU 使用时间的 profiling 函数

libpthread

POSIX 线程库

libresolv

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

librpcsvc

提供 RPC 的其他杂项服务

librt

提供了大部分的 POSIX.1b 运行时扩展接口

libthread_db

包含对多线程程序的调试很有用的函数

libutil

包含了在很多不同的 Unix 程序中使用的"标准"函数的代码