Glibc 软件包包含了主要的 C 函数库。这个库提供了分配内存、搜索目录、打开关闭文件、读写文件、操作字符串、模式匹配、基础算法等基本程序。
6.9.1. 安装 Glibc
注意
有些 LFS 之外的软件包会建议安装 GNU libiconv 来转换不同编码的文字。根据项目主页(http://www.gnu.org/software/libiconv/)上的说法“这个库会提供函数 iconv()
的实现,应用于那些没有这个函数的系统,或者函数实现中不支持 Unicode 转换的系统。” Glibc 提供了函数 iconv()
的实现而且支持 Unicode 转换,所以对于 LFS 系统来说并不需要 libiconv 库。
有些 Glibc 程序会用到和 FHS 不兼容的 /var/db
目录来存储它们的运行时数据。打上如下的补丁让这些程序在 FHS 兼容的位置存储它们的运行时数据。
patch -Np1 -i ../glibc-2.21-fhs-1.patch
Glibc 的编译系统是自包含的,可以完美安装,尽管编译器的配置文件和链接器仍然指向 /tools
。这在 Glibc 安装前没法调整,因为如果调整的话 Glibc 的 autoconf 测试将会提示错误,不符合我们实现一个干净构建的目标。
修正软件包里的一个会影响到 32 位架构系统的正则表达式:
sed -e '/ia32/s/^/1:/' \ -e '/SSE2/s/^1://' \ -i sysdeps/i386/i686/multiarch/mempcpy_chk.S
Glibc 文档里建议在 Glibc 源代码目录之外的特定编译目录下编译:
mkdir -v ../glibc-build cd ../glibc-build
配置 Glibc 准备编译:
../glibc-2.21/configure \ --prefix=/usr \ --disable-profile \ --enable-kernel=2.6.32 \ --enable-obsolete-rpc
新出现的 configure 选项参数的含义:
-
安装 NIS 和 RPC 相关的头文件,默认是不安装的;重新编译 Glibc 时以及一些 BLFS 软件包需要这些头文件。
--enable-obsolete-rpc
编译软件包:
make
重要
在本小节里,运行 Glibc 的测试套件是很关键的。在任何情况下都不要跳过这个测试。
通常会有一些测试不能通过,但是一般你可以忽略任何下面列出来的失败项。现在开始测试编译结果:
make check
你可能会看到一些失败的测试项。Glibc 的测试套件对宿主系统有一定的依赖。下面是当前版本 LFS 里最常见的问题:
-
测试项 tst/tst-cputimer1 和 rt/tst-cpuclock2 已知是通不过的。具体原因还不清楚,不过一些细微的时间问题可能导致这些测试失败。
-
如果你系统的 CPU 不是相对较新的 Genuine Intel 或 Authentic AMD 处理器,数学运算测试有时候会失败。
-
因为测试的时候还没有网络,测试项 posix/tst-getaddrinfo4 和 posix/tst-getaddrinfo5 将总是失败。
-
其它已知的在某些架构平台上会失败的测试项是 malloc/tst-malloc-usable 和 nptl/tst-cleanupx4。
在安装 Glibc 时会抱怨找不到 /etc/ld.so.conf
文件,这只是无关紧要的输出信息。下面的方式可以避免这个警告:
touch /etc/ld.so.conf
安装软件包:
make install
为 nscd 安装配置文件并创建运行时目录:
cp -v ../glibc-2.21/nscd/nscd.conf /etc/nscd.conf mkdir -pv /var/cache/nscd
为 nscd 安装系统支持文件:
install -v -Dm644 ../glibc-2.21/nscd/nscd.tmpfiles /usr/lib/tmpfiles.d/nscd.conf install -v -Dm644 ../glibc-2.21/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.21/localedata/SUPPORTED
文件里列出的所有语言环境(包括以上列出的所有语言环境以及其它更多),执行下面这个非常耗时的命令:
make localedata/install-locales
你需要的语言环境几乎不大可能没列在 glibc-2.21/localedata/SUPPORTED
文件中,但如果真的没有可以使用 localedef 命令创建和安装。
6.9.2. 配置 Glibc
尽管 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 myhostname
networks: files
protocols: files
services: files
ethers: files
rpc: files
# End /etc/nsswitch.conf
EOF
安装时区数据:
tar -xf ../tzdata2015a.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 命令的含义:
-
这会创建没有时间补偿的 posix 时区数据。一般将它们同时放在
zoneinfo
和zoneinfo/posix
目录下。另外需要将 POSIX 时区数据放到zoneinfo
目录下,否则很多测试套件会报错。在嵌入式平台,如果存储空间紧张而且你也不准备更新时区,也可以不用posix
目录从而节省 1.9MB,但是一些应用程序或测试套件也许会出错。 -
这会创建包含时间补偿的 right 时区数据。在嵌入式平台,空间比较紧张而且你也不打算更新时区或者不需要准确时间,你可以忽略
right
目录从而节省 1.9MB。 -
这会创建
posixrules
文件。我们使用纽约是因为 POSIX 要求夏令时规则与 US 标准一致。
zic -L /dev/null ...
zic -L leapseconds ...
zic ... -p ...
一种确定本地时区的方式是运行下面的脚本:
tzselect
在询问了几个关于位置的问题后,脚本会输出所在时区的名字(比如 America/Edmonton)。在 /usr/share/zoneinfo
文件中也有其它一些可用时区,比如 Canada/Eastern 或 EST5EDT,这些时区并没有被脚本列出来但也是可以使用的。
然后运行下面的命令创建 /etc/localtime
文件:
ln -sfv /usr/share/zoneinfo/<xxx>
/etc/localtime
将命令中的 <xxx>
替换成你所在实际时区的名字(比如 Canada/Eastern)。
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 软件包内容
简要介绍
可以在程序因为段错误终止的时候创建栈调用历史 | |
生成消息条目 | |
显示文件系统相关的系统配置变量的值 | |
获取系统数据库的内容 | |
字符集转换 | |
创建 iconv 快速加载模块配置文件 | |
配置动态链接器的运行时环境 | |
报告某个程序或动态库所依赖的动态库。 | |
协助 ldd 处理某些目标文件。 | |
输出当前语言环境的大量信息 | |
编译语言环境规格 | |
根据输入的文本创建简单数据库 | |
读取并解析内存跟踪文件,然后用方便人阅读的格式显示一个摘要 | |
一个后台服务程序,提供最常用名字服务请求的缓存 | |
输出个人电脑分析时生成的信息 | |
列出运行中进程正在使用的动态共享目标 | |
生成实现远端进程调用(RPC)协议的 C 语言代码 | |
一个静态链接的 ln 程序 | |
跟踪指定命令里的动态库函数调用 | |
读取并显示共享目标分析数据 | |
询问用户该系统的地理位置并给出相应的时区描述 | |
跟踪程序执行过程并打印当前执行的函数 | |
时区数据输出工具 | |
时区数据编译工具 | |
用于动态库执行的辅助程序 | |
Glibc 内部的一个粗暴破解用来修复损坏程序(比如,一些 Motif 应用)。查看文件 | |
段错误信号处理函数,catchsegv会用到 | |
一个异步名字查找库 | |
主要的 C 库 | |
Glibc 内部用于在函数 | |
密码学函数库 | |
动态链接接口函数库 | |
不包含函数的一个空库。以前是 g++ 的运行时库 | |
链接该模块会强制使用电气与电子工程师协会(IEEE) 定义的数学函数错误处理规则。默认的是 POSIX.1 错误处理。 | |
数学运算函数库 | |
链接这个库后会打开内存分配检查 | |
memusage 命令用它来协助收集应用程序里内存使用信息 | |
网络服务函数库 | |
名称服务切换函数库,包含了解析主机名、用户名、组名、别称、服务、协议等等的函数。 | |
包含一些分析函数,用于跟踪特定源代码里的 CPU 时间占用情况 | |
POSIX 线程函数库 | |
包含了创建、发送和解析互联网域名服务器封包的函数 | |
包含了提供杂项 RPC 服务的函数 | |
包含了实现 POSIX.1b 实时扩展里规定的大部分接口的函数 | |
包含了方便构建多线程程序调试工具的函数 | |
包含各种 Unix 应用程序中用到的“标准” 函数的代码 |