2.2.7 编译目标系统的C库

作为Linux操作系统中最底层的API,几乎运行于Linux操作系统上的任何程序都会依赖于C库。Glibc除了封装Linux内核所提供的系统服务外,也提供了C标准规定的必要功能的实现,如字符串处理、数学计算等。

在Ubuntu12.10中,系统默认安装的awk是mawk,我们需要另外安装gawk,因为mawk与Glibc中使用的awk脚本在兼容上有一些问题。

2.2.7 编译目标系统的C库 - 图1

解压源码,并打开修复编译错误的patch。

2.2.7 编译目标系统的C库 - 图2

Glibc要求在单独的目录编译,我们新建目录glibc-build用来编译Glibc。

2.2.7 编译目标系统的C库 - 图3

下面介绍各个配置参数的意义。

❑—host=$TARGET:注意这里与Binutils和GCC编译时指定的是target参数不同,Glibc指定的是host参数,但这里host的值是$TARGET,也就是说C库运行所在的host是$TARGET。换句话说,就是告诉刚刚编译的交叉编译器、汇编器、链接器等编译一个运行在$TARGET平台的C库。

❑—enable-kernel=3.7.4:除非是制作发行版,需要一个兼容更早内核的C库,否则我们没有必要向后兼容较早版本的内核,因为这样只会降低C库的效率,包括增加C库的体积,甚至影响运行速度。本书构建的系统使用的内核版本为3.7.4,因此,C库只支持3.7.4及以后版本的内核就可以了。当然,如果这个C库运行在早于3.7.4版本的内核上,将报类似于"FATAL:kernel too old"的致命错误,拒绝运行。

❑—enable-add-ons:编译C库源码目录下全部的add-on,如libidn、nptl。

❑—with-headers=$SYSROOT/usr/include:告诉编译脚本内核头文件所在的目录。

❑libc_cv_forced_unwind=yes和libc_cv_c_cleanup=yes:Glibc中的NPTL将检测C编译器对线程的支持,而freestanding的GCC是不支持线程的,因此,我们这里欺骗一下Glibc中的NPTL,告诉它编译器是支持线程的,采用的方法是设置这样两个参数。

❑libc_cv_ctors_header=yes:临时的freestanding的C编译器不支持启动代码与构造函数支持,因此,这里我们再次欺骗一下Glibc,人为地告诉Glibc编译器是支持启动代码的,也是支持构造函数的。

配置完成后,进行编译安装。我们通过指定参数install_root为$SYSROOT,将C库安装到$SYSROOT,即/vita/sysroot目录下。

2.2.7 编译目标系统的C库 - 图4

下面介绍一下Glibc安装的主要文件。

(1)C库

Glibc除了将最基本、最常用的函数封装在libc中外,又将功能相近的一些函数封装到一些子库里,比如将线程相关函数封装在libpthread中,将与加密算法相关的函数封装在libcrypt中,等等。

Glibc除了安装库文件本身外,还建立了符号链接,包括:

❑动态链接时使用的共享库符号链接。其命名格式一般为:libLIBRARY_NAME.so.MAJOR_REVISION_VERSION。

❑开发时使用的共享库的符号链接。其命名格式一般为:libLIBRARY_NAME.so。

比如数学库的共享库及其符号链接如下:

2.2.7 编译目标系统的C库 - 图5

其中,libm-2.15.so是数学库的共享库本身,libm.so.6是运行时使用的符号链接,libm.so是编译链接时使用的符号链接。Glibc将运行时使用的库安装在$SYSROOT/lib目录下,其中包括共享库文件本身及动态链接器需要的符号链接。将开发时使用的库安装在$SYSROOT/usr/lib目录下,包括开发时需要的符号链接及静态库等。

(2)动态链接器

Glibc亦提供了加载共享库的工具——动态加载器。2.15版的Glibc提供的动态加载器为ld-2.15.so,其符号链接是ld-linux.so.2,也安装在$SYSROOT/lib目录下。

(3)头文件

Glibc为应用程序的开发提供了头文件,安装在$SYSROOT/usr/include目录下。

(4)工具

Glibc也提供了一些可执行的便利工具,这类工具一般安装在sbin、usr/bin、usr/sbin目录下,比如用来转换文件字符编码的工具iconv,在usr/lib/gconv目录下安装了工具iconv使用的进行字符编码转换的各种库(如支持GB18030的GB18030.so),如果不打算在目标系统上转换文件的字符编码,完全不必安装该工具。另外还有比如查看共享库依赖的工具ldd,创建共享库缓存以提高共享库搜索效率的ldconfig程序等。

除此之外,usr目录下还有支持国际化、时区设置需要的文件等。

(5)启动文件

Glibc提供了启动文件,包括crt1.o、crti.o、crtn.o等,这类文件在编译链接时将被链接器链接到最后的可执行文件中,Glibc将其安装在$SYSROOT/usr/lib目录下。