Glibc 安装指南

Kai Schlachter

2004-03-19

修订历史
修订版 1.012004-03-19修订者:KC
首次发布,由 LDP 审核

目录
1. 前言
1.1. 版权
1.2. 修订历史
1.3. 致谢
2. 简介
2.1. 为什么?
2.2. 是什么?
3. 准备工作
3.1. 你需要的东西
3.2. 你需要做的特别的事情
4. glibc 的安装
4.1. 获取和编译源代码
4.2. 安装
4.3. 内核启动后...
5. 故障排除——如果出现问题...
5.1. 尝试编译 glibc 时,configuremake 出现错误
5.2. make install 期间出现问题

第 1 章 前言

1.1. 版权

版权所有 (c) 2004 Kai Schlachter

根据 GNU 自由文档许可证第 1.2 版或自由软件基金会发布的任何更高版本条款,允许复制、分发和/或修改本文档; 没有不变章节,没有封面文本,也没有封底文本。 许可证副本位于 https://gnu.ac.cn/licenses/fdl.html


1.2. 修订历史

  • v1.01:修复了一些错误放置的引号


1.3. 致谢

我特别要感谢 Nico Schmoigl,感谢他在我系统完全运行时运行 glibc 的 make install 后,帮助我恢复了崩溃的系统。 这是我编写此迷你指南的主要原因。

还要感谢所有其他帮助我一路走来的人; 以正确的格式获取 HOWTO、查找所有拼写错误等。


第 2 章 简介

在本指南中,我将解释如何在您的系统上安装新版本的 glibc

我编写本手册是因为我想让其他人免于我遇到的问题。

本指南是一种指导方针,由对我有用的设置和做事方式组成。 不对本文档的内容承担任何责任。 您需要自行承担使用概念、示例和其他内容的风险。 强烈建议您在进行重大安装之前备份系统,并定期备份。

如果您有任何建议,发现某些发行版中的另一个错误以及如何修复它,请通过发送电子邮件告诉我.


2.1. 为什么?

是的,这是一个好问题。 为什么你需要安装一个新的 glibc? 好吧,有几个原因

  • 您是一名开发人员,并且需要该库的新功能

  • 您想编译一个需要新库的新程序

  • 您喜欢新版本中的错误和漏洞的刺激感 ;-)


2.2. 是什么?

如果您到现在还不知道 glibc 是什么,请不要担心! 当我第一次遇到一个我想编译的新程序出现问题时,我只知道我的 glibc 版本不足以进行编译。 现在我知道更多了,我会尝试用一种非常简单的方式来解释 glibc 的作用。

glibc 软件包包含用 C 编程语言编写的库。 库在编程中非常有用; 而不是从头开始发明诸如计算数字平方根等操作的轮子,这些常用函数都存储在单独的文件中——所谓的库。 当发布新版本的库时,它通常包含一些新函数,对已经实现的函数使用更有效的算法等等。

这就是为什么有些程序会抱怨旧版本的 glibc:当前版本只是不包含程序运行所需的所有功能。

我知道这在所有细节上在技术上并不正确,但它可以让您对幕后的架构有一个基本的了解。


第 3 章 准备工作

由于 glibc 的安装并非易事。 您需要提前做很多事情,尤其是在出现问题的情况下。 (这是我第一次安装 glibc 时发生的事情,我没有做任何准备。)


3.1. 你需要的东西

基本上,你需要两件不同的东西:已经运行在你机器上的软件(例如,由你的发行版预装的)和不同程序的源代码包。


3.1.1. 你需要的软件

  • 正在运行的 gcc

  • 旧版本的 glibc ;-)

  • GNU-binutils

  • GNU-make

  • GNU-core-utils

  • GNU-tar

  • bash 或你喜欢的任何 shell

  • 非常有用但不是必须的:Midnight Commander

  • 你喜欢的编辑器 (vi, jed 等)


3.1.2. 你需要的源代码

  • bash 或你喜欢的 shell

  • GNU-tar

  • GNU-core-utils

  • GNU-make

  • 当然:glibc

  • 可能:gcc


3.2. 你需要做的特别的事情

由于您将要替换许多程序所依赖的基本库,您可以想象可能出现的问题。

对我来说,一切都很顺利,直到我输入 make install。 在安装过程进行到一半左右时,我收到了一个错误,告诉我 rm 无法运行,我发现即使所有常见的命令,如 cplsmvlntar 等,都无法工作; 所有这些都告诉我,他们无法找到他们需要的库的某些部分。

但这里有帮助。 您可以强制编译程序,并将库编译到它们中,因此程序不需要从库中查找它们。

因此,在本章中,我们将把安装所需的所有实用程序编译成静态版本。


3.2.1. 你肯定需要的东西

3.2.1.1. GNU-Binutils

  1. 从以下位置获取最新版本:ftp.gnu.org/gnu/binutils; 在撰写本文时,这是 2.14 版本

  2. 打开软件包
    tar xIvf binutils-2.14.tar.bz2

  3. 切换到目录
    cd binutils-2.14

  4. 配置 Makefiles
    ./configure

  5. 编译源代码
    make

  6. 使用以下命令安装它们
    make install

如果您在 binutils 的编译中遇到麻烦,涉及到 gettext 的问题(由类似以下的错误指示:“对 lib_intl 的未声明引用”或类似问题),请安装最新版本,可从 ftp.gnu.org/gnu/gettext 获得。

如果这没有帮助,请尝试使用以下命令禁用本机语言支持
./configure --no-nls

您不需要构建 binutils 的静态版本,尽管这样做并没有什么坏处,但我遇到了许多运行着非常旧版本的系统,并且几乎每次都遇到错误,所以我认为在这里提到它们是个好主意。


3.2.1.2. GNU make

make 命令负责编译源代码,调用 gcc 和编译所需的所有其他程序。 因为如果新的 glibc 出现问题,您可能需要编译一些东西,所以最好让它是静态的,否则在出现错误后它可能无法工作。

  1. ftp.gnu.org/gnu/make/ 下载源代码; 在撰写本文时,当前版本为 3.80

  2. 解压源代码,例如
    tar xIvf make-3.80.tar.bz2

  3. 切换到创建的目录
    cd make-3.80

  4. 确保二进制文件是静态构建的
    export CFLAGS="-static -O2 -g"

  5. 运行配置脚本
    ./configure

  6. 编译东西
    make

  7. 安装二进制文件
    make install

  8. 进行检查
    make -v
    现在您应该看到安装了新版本。 如果没有,请检查旧的二进制文件,并用指向新版本的软链接替换它们。

恭喜! 您又编译了一个静态链接的程序。


3.2.1.3. GNU core-utils

core-utils 是像:cprmlnmv 等命令。 万一安装出错,这些是帮助您恢复系统的绝对要求,所以静态二进制文件在这里真的很有必要。

  1. 同样,从以下位置下载源代码 tarball:ftp.gnu.org/gnu/coreutils/; 在撰写本文时,版本 5.0 是当前的。

  2. 解压它
    tar xIvf coreutils-5.0.tar.bz2

  3. 切换到目录
    cd coreutils-5.0

  4. 确保二进制文件是静态构建的
    export CFLAGS="-static -O2 -g"

  5. 配置软件包
    ./configure

  6. 编译二进制文件
    make

  7. 并安装它们
    make install

  8. 验证是否使用了正确的 core-utils
    cp --version
    . 您应该看到正确的版本,否则删除任何旧的二进制文件,并用指向新版本的符号链接替换它们。

现在这些非常基本的工具的二进制文件是静态的,您可以确信每次需要它们时它们都会工作。


3.2.1.4. GNU tar

您已经使用 GNU tar 来解压缩到目前为止编译和安装的所有程序。 但是在崩溃之后,您可能需要编译 glibc 所需的另一个程序,在这种情况下(我亲身经历过!),拥有一个可以解压缩缺失程序的工作 tar 非常有用。 对于 tar,我们还需要注意 bz2 压缩算法,该算法未包含在 tar 的正常源代码发行版中。

  1. ftp.gnu.org/gnu/tar 获取 GNU tar 的源代码; 在撰写本文时,版本 1.13 是最新的。

  2. 由于许多源代码 tarball 都使用 bzip2 进行压缩,我们希望内置支持,而不是使用管道,因此请从以下位置获取补丁:ftp://infogroep.be/pub/linux/lfs/lfs-packages/4.1/tar-1.13.patch

  3. 通过调用以下命令解压源代码
    tar xzvf tar-1.13.tar.gz

  4. 将补丁复制到 tar 的源代码目录
    cp tar-1.13.patch tar-1.13/

  5. 应用补丁
    patch -Np1 -i tar-1.13.patch

  6. 设置编译器标志以制作静态二进制文件
    export CFLAGS="-static -O2 -g"

  7. 现在我们准备配置
    ./configure

  8. 编译使用
    make

  9. 下一步,安装包
    make install

  10. 快速检查以确保从现在开始使用新版本
    tar --version
    您刚刚安装的版本应该显示出来,否则请检查旧的二进制文件,并将其替换为指向新位置的符号链接。

如果您在执行 make 时遇到问题,请尝试关闭本地语言支持 (nls)。您可以通过使用以下选项调用 configure 来实现此目的
--disable-nls

注意: 在这个新版本的 tar 中,您必须使用-j开关来解压 .bzip2 文件,所以取代
tar xIvf anyfile.tar.bz2
现在你必须使用
tar xjvf anyfile.tar.bz2
我不知道为什么会改变,但它运行良好。


3.2.1.5. Bash shell

我更喜欢 Bash 作为我的 shell; 如果你使用不同的 shell,请确保在安装 glibc 之前安装它的静态版本。

  1. 从这里获取 Bash: ftp.gnu.org/gnu/bash/. 下载你能找到的最新版本; 在编写本文时,版本是 2.05b。

  2. 解压源码树
    tar xzvf bash-2.05b.tar.gz
    这将创建一个名为bash-2.05b的目录,其中包含所有解压后的源码。

  3. 进入该目录
    cd bash-2.05a

  4. 设置一切以构建静态版本
    export CFLAGS="-static -O2 -g"

  5. 配置 makefiles
    ./configure
    如果您想在您的 Bash 中添加一些特殊功能,请参阅
    ./configure --help
    获取选项列表。

  6. 编译所有内容
    make

  7. 安装编译后的二进制文件
    make install
    这会将二进制文件安装到/usr/local/bin/.

  8. 确保没有其他版本存在(比如我的 Suse-Linux 中的/bin/), 通过复制文件
    cp /usr/local/bin/bash /bin/
    我们这里不使用符号链接,因为在启动时和启动 Bash 时,符号链接可能会出现问题。

现在您已经安装了一个静态版本的 Bash。 因此,该二进制文件比平常大得多,但它将在所有情况下运行。

如果您喜欢使用其他 shell,您可以自由地这样做,但请确保它是一个静态链接的版本。 欢迎您通过电子邮件告诉我构建您选择的 shell 的静态版本的方法,并且很有可能它将在本文档的下一个版本中实现。


3.2.2. 可能派上用场的软件

3.2.2.1. Midnight Commander

Midnight Commander 是一个非常有用的文件管理器,支持许多不错的功能,如透明解压缩打包文件、内置复制、移动和其他常用命令,以及集成的编辑器。

要编译这个软件,您需要安装 glib;在某些发行版中已经安装了。 如果您在 make 命令中收到错误,提示 ld 无法找到 glib,您需要先安装这个库。 您可以从以下位置获取源代码:ftp.gnome.org/pub/gnome/sources/glib/2.2/,安装过程很简单。

以下是构建 Midnight Commander 的步骤

  1. http://www.ibiblio.org/pub/Linux/utils/file/managers/mc/" 获取源码; 在编写本文时,最新版本是 4.6.0。

  2. 解压源码
    tar xzvf mc-4.6.0.tar.gz

  3. 切换到您刚刚创建的目录
    cd mc-4.6.0

  4. 设置配置文件
    ./configure

  5. 开始编译
    make

  6. 安装所有内容
    make install


第 4 章。 glibc 本身的安装

现在我们来谈谈最重要的事情:glibc 的安装。


4.1. 获取和编译源码

有几个版本的 glibc 可用,但并非在所有情况下,新版本都比旧版本更好。 您可以做的最好的事情是查看 Internet 上的不同论坛,以找出哪些版本有效,哪些版本不应使用。 如果您有可以询问的人,请与他讨论该主题。 也许他已经安装了新版本,并且可以告诉您版本 x.y.z 是个麻烦,但版本 a.b.c 效果非常好!

我决定安装 glibc-2.2.4,因为有人告诉我它运行良好,但选择哪个版本取决于您。

好的,现在开始工作

  1. ftp.gnu.org/gnu/glibc/ 获取源代码; 正如我所说,我使用了 2.2.4 版本。

  2. 解压源码
    tar -xzvf glibc-2.2.4.tar.gz

  3. 此外,您还需要一个名为 “linuxthreads” 的软件包,位于linuxthreads目录中,位于 ftp.gnu.org 上。 文件名为
    glibc-linuxthreads-2.2.4.tar.gz
    确保您获取的版本与您的 glibc 源码树相对应。

  4. 将 linuxthreads 软件包复制到您的 glibc 源码目录
    cp glibc-linuxthreads-2.2.4.tar.gz glibc-2.2.4

  5. 切换到 glibc 目录
    cd glibc-2.2.4

  6. 解压 linuxthreads
    tar xzvf linux-threads-2.2.4.tar.gz

  7. 配置软件包
    ./configure --enable-add-ons=linuxthreads
    这将以这样一种方式配置软件包,即 linuxthreads 包含在编译中;这对于与其他 Linux 系统的兼容性是必要的。 例如,如果您忘记包含此软件包,您编译的程序可能无法在另一台机器上运行。

  8. 之后,开始编译 glibc
    make
    这可能需要一些时间(在我的 Duron XP 上大约半小时,运行频率为 1.5 GHz)。

现在库已编译完成,一切都已准备好进行安装,但这次事情并没有那么容易。


4.2. 安装

要安装 glibc,您需要一个没有任何东西在其上运行的系统,因为许多进程(例如 sendmail)总是尝试使用该库,因此阻止文件被替换。 因此,我们需要一个 “裸” 系统,除了我们绝对需要的东西之外什么都不运行。 您可以通过将启动选项
init=/bin/bash
传递给您的内核来实现此目的。 根据您的引导加载程序,您可能需要做不同的事情。 在下文中,我将以两种最常见的引导加载程序 LILO (LInux-LOader) 和 GNU grub 为例进行说明。


4.2.1. LILO

要启动 “only-basics” 系统,请重新启动您的计算机,并在 LILO 提示符下输入您要加载的内核映像名称,并附加
init=/bin/bash
在按下 Return 之前。 如果您计划更频繁地替换您的 glibc,那么在您的/etc/lilo.conf中添加单独的配置可能是一个好主意。 有关详细信息,请参阅 LILO 的 man 手册。


4.2.2. Grub

Grub 是一个较新的引导加载程序,增强了对不同操作系统和文件系统类型的支持(例如,它支持从 reiserfs 分区启动)。 如果您想了解更多信息,请访问:https://gnu.ac.cn/software/grub/,您将在那里找到您需要的所有内容。

如果您已经安装了 Grub,您可能会使用基于文本的前端来选择您喜欢启动的内核。 Grub 有一个很棒的功能——与其返回手动执行所有操作,不如直接选择您的条目并键入 e,这将弹出一个选项菜单。 在此菜单中,您将看到 Grub 在启动内核之前执行的命令。 只需选择显示
kernel="/where/your-kernel-is and-options-are"
的行,然后再次按 e。 现在您可以编辑此行。 在这里您只需添加
init=/bin/bash
然后在按下 Return 使更改生效后,按下 b 开始启动。


4.3. 内核启动后...

...您将发现自己处于一个绝对最小的 bash 环境中。

甚至不会要求您输入用户名或密码! 此时您是终极超级用户; 没人能绕过你,因为系统处于单用户模式,所以请小心你的所作所为。 没有设置文件权限或任何其他内容!

您的提示符可能如下所示
init-x.y#
此时您的根目录 (/) 已被挂载为只读,因此您将无法将新库写入您的硬盘驱动器。 使其r/w,输入命令
mount -o remount,rw /
如果您的源码位于另一个分区上,您也必须挂载它,因为它没有为您完成(对我来说这意味着挂载我的 raid 系统)
mount -t reiserfs /dev/md0 /usr/src
如您所见,我定义了文件系统类型,这是必需的,因为 mount 不会在/etc/fstab.

中查找任何内容
make install

现在您可以转到包含源代码的目录并输入

如果您愿意,现在可能是祈祷一切顺利的好时机... ;-)

如果一切顺利通过,您将在安装后返回到您的提示符,而不会收到任何错误消息。 在所有其他情况下,请参阅 第 5 章
ldconfig -v
如果一切顺利,请运行

更新您的库缓存。

恭喜! 该库已成功安装。 现在输入:mount -o remount,ro / 以确保所有数据都写入硬盘驱动器。
exit
现在开始重启

这将导致一个错误消息,说明您已导致内核崩溃。 如果可能,请使用 CTRL-ALT-DEL 重新启动计算机,否则请使用硬件的重置开关。


尝试启动您的普通内核。 如果一切顺利,您就可以使用新库了。

第 5 章。 故障排除 - 如果出现问题...

如果您来到本节并且您已按照上述所有说明进行操作,您可能遇到了不同 Linux 发行版的问题,其中一些发行版不会将东西放在通常应该在的地方,而是放在其他地方。 Suse Linux 发行版以这种愚蠢的怪癖而闻名,但可能还有其他发行版有类似的问题。 如果您遇到这样的事情并且您找到了麻烦的原因——并希望找到解决方案——请告诉我,我会将其添加到我的 HOWTO 中。


我认为本节永远不会真正完整,但我将列出一些可能的错误和这些问题的解决方案。

5.1. 尝试编译 glibc 时出现 configuremake 错误有时您会收到配置错误,告诉您例如未满足要求——这对于软件或其他库包来说很典型,这些软件或其他库包太旧了。 我在使用一系列程序时遇到了这个问题,尤其是在编译所有静态软件时。 通常应该没有问题:获取所需的软件或库的最新版本,然后根据源码树中找到的描述编译它们(通常称为, 自述文件安装

但有时会遇到无法正常工作的情况。 例如,我遇到了编译新版本的 binutils 的问题(这是我在要求中提到它们的原因之一),因为我需要编译 glibc。 作为回报,binutils 的 configure 脚本告诉我,“你的 glibc 版本太旧了!” 所以我想,这里开始了蛇吞尾巴。 幸运的是,这个问题有解决方案:如果你不能一步到位,那就尝试走小步,但多走几步。

在我的发行版中,包含了一个版本号为 2.1.1 的 glibc。 为了绕过这个错误,我尝试编译 2.1.3 版本,这没有问题。 安装了这个版本的库之后,我再次尝试编译 binutils,这次所有要求都满足了。

如果你遇到这样的“循环”,尝试找出所需软件的最低版本,然后下载该版本(我认为这是为什么这么多旧版本仍然存在于 FTP 服务器上的原因之一)。 成功编译和安装后,再次尝试构建抱怨版本问题的软件; 在大多数情况下,你应该能够进行编译。 可能需要你继续使用这种方法来编译缺失或旧软件。 这就是我所说的“老鼠的长尾巴”或“多米诺骨牌效应”。 你只想做一件事,但在你想要采取行动之前,你需要做更多的事情。 这可能非常令人讨厌,但有一个好处:完成后,你可以相当肯定,在你完成安装时,许多非常旧的程序将被替换。


5.2. make install 过程中出错

最常见的错误是没有一组基本的、静态的工具; 在这种情况下,你只能使用命令 cd,而不能使用其他任何命令。 这就是为什么在本 HOWTO 中,我详细描述了如何制作那些静态工具。

唯一不是静态的工具是 mount,并且我认为有充分的理由,它包含在 linux-utils 包中,该包也包含 loginpasswd 等。 由于你无法将静态链接版本与 PAM 或其他安全相关软件结合使用,因此在所有情况下都静态编译它们是不明智的。 当然,如果你真的确定你在做什么,你可以自由地这样做。


5.2.1. 返回到正常工作的配置

如果你有静态工具,返回到正常工作的配置非常简单:进入目录/usr/local/lib/并将所有新安装的文件移动到另一个位置(例如/usr/local/lib/storedaway)。 你可以通过查看它们的版本号来识别它们,版本号应该与你的 glibc 安装的版本号相同(在我的示例中,所有文件都符合 lib*-2.2.4 的方案),当然还有创建日期和时间。 两种不同的库同时具有相同的版本号是非常罕见的——我自己从未经历过这种情况——但为了确保你不会删除对你的系统重要的东西,请检查创建的日期和时间。 在这种情况下,一个非常有用的工具是 Midnight Commander,如果你安装了它。

你可以尝试删除文件ld-2.2.4.solibc-2.2.4.so并在删除所有崩溃的文件之前运行 ldconfig -v。 这将使你至少可以使用大多数程序,并且在任何情况下你都能够运行 Midnight Commander。

在删除所有文件后,不要忘记至少执行一次 ldconfig -v


5.2.1.1. 消除安装崩溃的原因

问题的一个常见原因是你的发行版将所有库文件存储在与新安装的例程将要使用的位置不同的位置,因此经常发生两个版本同时运行,相互干扰。 在我的情况下,大量问题是由libc6.so的第二个副本引起的,它位于/lib中,从该文件到/usr/local/lib中的对应文件的符号链接可以解决这个问题。