Glibc 安装指南(2.6.1 → 2.9)
安装信息的来源
- 源码包内的下列文件:configure FAQ INSTALL NOTES Makeconfig README localedata/README
- http://www.gnu.org/software/libc/manual/html_node/System-Configuration.html
- http://www.gnu.org/software/libc/manual/html_node/Installation.html
- http://www.gnu.org/software/libc/manual/html_node/Name-Service-Switch.html
要点提示
编译Glibc的时候应该尽可能使用最新的内核头文件,至少要使用 2.6.16 以上版本的内核,先前的版本有一些缺陷会导致"make check"时一些与pthreads测试相关的项目失败。使用高版本内核头文件编译的Glibc二进制文件完全可以运行在较低版本的内核上,并且当你升级内核后新内核的特性仍然可以得到充分发挥而无需重新编译Glibc。但是如果编译时使用的头文件的版本较低,那么运行在更高版本的内核上时,新内核的特性就不能得到充分发挥。更多细节可以查看[八卦故事]内核头文件传奇的跟帖部分。
推荐使用GCC-4.1以上的版本编译,老版本的GCC可能会生成有缺陷的代码。
不要在运行中的系统上安装 Glibc,否则将会导致系统崩溃,至少应当将新 Glibc 安装到其他的单独目录,以保证不覆盖当前正在使用的 Glibc 。
Glibc 不能在源码目录中编译,它必须在一个额外分开的目录中编译。这样在编译发生错误的时候,就可以删除整个编译目录重新开始。
源码树下的Makeconfig文件中有许多用于特定目的的变量,你可以在编译目录下创建一个configparms文件来改写这些变量。执行make命令的时候configparms文件中的内容将会按照Makefile规则进行解析。比如可以通过在其中设置 CFLAGS LDFLAGS 环境变量来优化编译,设置 CC BUILD_CC AR RANLIB 来指定交叉编译环境。
需要注意的是有些测试项目假定是以非 root 身份执行的,因此我们强烈建议你使用非 root 身份编译和测试 Glibc 。
配置选项
下列选项皆为非默认值[特别说明的除外]
- --help
--version
--quiet
--config-cache
--no-create
--srcdir=DIR
--exec-prefix=EPREFIX
--bindir=DIR
--sbindir=DIR
--libexecdir=DIR
--sysconfdir=DIR
--sharedstatedir=DIR
--localstatedir=DIR
--libdir=DIR
--includedir=DIR
--oldincludedir=DIR
--datarootdir=DIR
--datadir=DIR
--infodir=DIR
--localedir=DIR
--mandir=DIR
--docdir=DIR
--htmldir=DIR
--dvidir=DIR
--pdfdir=DIR
--psdir=DIR
--build=BUILD
--host=HOST - 这些选项的含义基本上通用于所有软件包,这里就不特别讲解了。需要注意的是:没有--target=TARGET选项。
- --prefix=PREFIX
- 安装目录,默认为 /usr/local
Linux文件系统标准要求基本库必须位于 /lib 目录并且必须与根目录在同一个分区上,但是 /usr 可以在其他分区甚至是其他磁盘上。因此,如果在Linux平台上指定 --prefix=/usr ,那么基本库部分将自动安装到 /lib 目录下,而非基本库部分则会自动安装到 /usr/lib 目录中,同时将使用 /etc 作为配置目录,也就是等价于"slibdir=/lib sysconfdir=/etc"。但是如果保持默认值或指定其他目录,那么所有组件都间被安装到PREFIX目录下。 - --disable-sanity-checks
- 真正禁用线程(仅在特殊环境下使用该选项)。
- --enable-check-abi
- 在"make check"时执行"make check-abi"。[提示]在我的机器上始终导致check-abi-libm测试失败。
- --disable-shared
- 不编译共享库(即使平台支持)。在支持 ELF 并且使用 GNU 连接器的系统上默认为enable 。[提示] --disable-static 选项实际上是不存在的,静态库总是被无条件的编译和安装。
- --enable-profile
- 启用 profiling 信息相关的库文件编译。主要用于调试目的。
- --enable-omitfp
- 编译时忽略帧指示器(使用 -fomit-frame-pointer 编译),并采取一些其他优化措施。忽略帧指示器可以提高运行效率,但是调试将变得不可用,并且可能生成含有 bug 的代码。使用这个选项还将导致额外编译带有调试信息的非优化版本的静态库(库名称以"_g"结尾)。
- --enable-bounded
- 启用运行时边界检查(比如数组越界),这样会降低运行效率,但能防止某些溢出漏洞。
- --disable-versioning
- 不在共享库对象中包含符号的版本信息。这样可以减小库的体积,但是将不兼容依赖于老版本 C 库的二进制程序。[提示]在我的机器上使用此选项总是导致编译失败。
- --enable-oldest-abi=ABI
- 启用老版本的应用程序二进制接口支持。ABI是Glibc的版本号,只有明确指定版本号时此选项才有效。
- --enable-stackguard-randomization
- 在程序启动时使用一个随机数初始化 __stack_chk_guard ,主要用来抵抗恶意攻击。
- --enable-add-ons[=DIRS...]
- 为了减小软件包的复杂性,一些可选的libc特性被以单独的软件包发布,比如'linuxthreads'(现在已经被废弃了),他们被称为'add-ons'。要使用这些额外的包,可以将他们解压到Glibc的源码树根目录下,然后使用此选项将DIR1,DIR2,...中的附加软件包包含进来。其中的"DIR"是附加软件包的目录名。默认值"yes"表示编译所有源码树根目录下找到的附加软件包。
- --disable-hidden-plt
- 默认情况下隐藏仅供内部调用的函数,以避免这些函数被加入到过程链接表(PLT,Procedure Linkage Table)中,这样可以减小 PLT 的体积并将仅供内部使用的函数隐藏起来。而使用该选项将把这些函数暴露给外部用户。
- --enable-bind-now
- 禁用"lazy binding",也就是动态连接器在载入 DSO 时就解析所有符号(不管应用程序是否用得到),默认行为是"lazy binding",也就是仅在应用程序首次使用到的时候才对符号进行解析。因为在大多数情况下,应用程序并不需要使用动态库中的所有符号,所以默认的 "lazy binding"可以提高应用程序的加载性能并节约内存用量。然而,在两种情况下,"lazy binding"是不利的:①因为第一次调用DSO中的函数时,动态连接器要先拦截该调用来解析符号,所以初次引用DSO中的函数所花的时间比再次调用要花的时间长,但是某些应用程序不能容忍这种不可预知性。②如果一个错误发生并且动态连接器不能解析该符号,动态连接器将终止整个程序。在"lazy binding"方式下,这种情况可能发生在程序运行过程中的某个时候。某些应用程序也是不能容忍这种不可预知性的。通过关掉"lazy binding"方式,在应用程序接受控制权之前,让动态连接器在处理进程初始化期间就发现这些错误,而不要到运行时才出乱子。
- --enable-static-nss
- 编译静态版本的NSS(Name Service Switch)库。仅在/etc/nsswitch.conf中只使用dns和files的情况下,NSS才能编译成静态库,并且你还需要在静态编译应用程序的时候明确的连接所有与NSS库相关的库才行[比如:gcc -static test.c -o test -Wl,-lc,-lnss_files,-lnss_dns,-lresolv]。不推荐使用此选项,因为连接到静态NSS库的程序不能动态配置以使用不同的名字数据库。
- --disable-force-install
- 不强制安装当前新编译的版本(即使已存在的文件版本更新)。
- --enable-kernel=VERSION
- VERSION 的格式是 X.Y.Z,表示编译出来的 Glibc 支持的最低内核版本。VERSION 的值越高(不能超过内核头文件的版本),加入的兼容性代码就越少,库的运行速度就越快。
- --enable-all-warnings
- 在编译时显示所有编译器警告,也就是使用 -Wall 选项编译。
- --with-gd
--with-gd-include
--with-gd-lib - 指定libgd的安装目录(DIR/include和DIR/lib)。后两个选项分别指定包含文件和库目录。
- --without-fp
- 仅在硬件没有浮点运算单元并且操作系统没有模拟的情况下使用。x86 与 x86_64 的 CPU 都有专门的浮点运算单元。而且 Linux 有 FPU 模拟。简单的说,不要 without 这个选项!因为它会导致许多问题!
- --with-binutils=DIR
- 明确指定编译时使用的Binutils(as,ld)所在目录。
- --with-elf
- 指定使用 ELF 对象格式,默认不使用。建议在支持 ELF 的 Linux 平台上明确指定此选项。
- --with-selinux
--without-selinux - 启用/禁用 SELinux 支持,默认值自动检测。
- --with-xcoff
- 使用XCOFF对象格式(主要用于windows)。
- --without-cvs
- 不访问CVS服务器。推荐使用该选项,特别对于从CVS下载的的版本。
- --with-headers=DIR
- 指定内核头文件的所在目录,在Linux平台上默认是'/usr/include'。
- --without-tls
- 禁止编译支持线程本地存储(TLS)的库。使用这个选项将导致兼容性问题。
- --without-__thread
- 即使平台支持也不使用TSL特性。建议不要使用该选项。
- --with-cpu=CPU
- 在 gcc 命令行中加入"-mcpu=CPU"。鉴于"-mcpu"已经被反对使用,所以建议不要设置该选项,或者设为 --without-cpu 。
编译与测试
使用 make 命令编译,使用 make check 测试。如果 make check 没有完全成功,就千万不要使用这个编译结果。需要注意的是有些测试项目假定是以非 root 身份执行的,因此我们强烈建议你使用非 root 身份编译和测试。
测试中需要使用一些已经存在的文件(包括随后的安装过程),比如 /etc/passwd, /etc/nsswitch.conf 之类。请确保这些文件中包含正确的内容。
安装与配置
使用 make install 命令安装。比如:make install LC_ALL=C
如果你打算将此 Glibc 安装为主 C 库,那么我们强烈建议你关闭系统,重新引导到单用户模式下安装。这样可以将可能的损害减小到最低。
安装后需要配置 GCC 以使其使用新安装的 C 库。最简单的办法是使用恰当 GCC 的编译选项(比如 -Wl,--dynamic-linker=/lib/ld-linux.so.2 )重新编译 GCC 。然后还需要修改 specs 文件(通常位于 /usr/lib/gcc-lib/TARGET/VERSION/specs ),这个工作有点像巫术,调整实例请参考 LFS 中的两次工具链调整。
可以在 make install 命令行使用'install_root'变量指定安装实际的安装目录(不同于 --prefix 指定的值)。这个在 chroot 环境下或者制作二进制包的时候通常很有用。'install_root'必须使用绝对路径。
被'grantpt'函数调用的辅助程序'/usr/libexec/pt_chown'以 setuid 'root' 安装。这个可能成为安全隐患。如果你的 Linux 内核支持'devptsfs'或'devfs'文件系统提供的 pty slave ,那么就不需要使用 pt_chown 程序。
安装完毕之后你还需要配置时区和 locale 。使用 localedef 来配置locale 。比如使用'localedef -i de_DE -f ISO-8859-1 de_DE'将 locale 设置为'de_DE.ISO-8859-1'。可以在编译目录中使用'make localedata/install-locales'命令配置所有可用的 locale ,但是一般不需要这么做。
时区使用'TZ'环境变量设置。tzselect 脚本可以帮助你选择正确的值。设置系统全局范围内的时区可以将 /etc/localtime 文件连接到 /usr/share/zoneinfo 目录下的正确文件上。比如对于中国人可以'ln -s /usr/share/zoneinfo/PRC /etc/localtime'。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论