如何正确升级 Centos7 的 Glibc
本文撰写于 2020年 7 月 3 日,写这篇文章的时候还比较年轻,可能含有错误。
标题中的正确是相对与我参考的错误文章 [某文章教我用 fedora29 的 rpm 包去升级 centos7 的 glibc,于是我的系统挂了]。
不代表这是最佳操作方式,请知悉。
也可以参考在非标准位置安装 Glibc:https://serverfault.com/a/894689
请确保您有能力在系统损坏后救援您的系统!
不到万不得已,你不应该使用不支持的方式升级系统底层包。
Glibc 不可用会导致:bash 无法使用、yum/rpm 无法使用、无法解析名称空间、无法切换用户等,基本相当于系统不可用。
不应该在生产环境做此类操作。特别是升级这种系统底层组件。
不要安装不属于你系统的 RPM 包。
更新完必定会有某些东西有错误。
glibc 是 GNU 发布的 libc 库,即 c 运行库。glibc 是 linux 系统中最底层的 api,几乎其它任何运行库都会依赖于glibc。glibc除了封装 linux 操作系统所提供的系统服务外,它本身也提供了许多其它一些必要功能服务的实现。由于 glibc 囊括了几乎所有的 UNIX 通行的标准,可以想见其内容包罗万象。而就像其他的 UNIX 系统一样,其内含的档案群分散于系统的树状目录结构中,像一个支架一般撑起整个操作系统。在 GNU/Linux 系统中,其 C 函数库发展史点出了GNU/Linux 演进的几个重要里程碑,用 glibc 作为系统的 C 函式库,是 GNU/Linux 演进的一个重要里程碑。-------摘自百毒百科
错误的升级 Glibc 或 Glibc 损坏会毁了你的操作系统!
那么如何正确在 Centos7 升级 Glibc 呢
推荐全程在 screen 中运行,防止意外断开造成不可意料的后果。
下面所有组件都是撰写本文 2020/7/3 时的最新版,根据您的需要替换。
以下全部操作都是用 root 账户进行的。
升级 GNU Make 与 GCC,安装 Python3
高于 Glibc 2.4 的版本需要比 Centos7 自带的 make 和 GCC 更高的版本。
INSTALL 文件里面有写,这里精简一下:
Recommended Tools for Compilation
=================================
We recommend installing the following GNU tools before attempting to
build the GNU C Library:
* GNU 'make' 4.0 or newer
* GCC 6.2 or newer
* Python 3.4 or later
* GDB 7.8 or later with support for Python 2.7/3.4 or later
如果你只想升级到 Glibc 2.24 则可以跳过此步骤。
1.升级GNU Make 4.3
wget https://ftp.gnu.org/gnu/make/make-4.3.tar.gz
wget https://mirrors.aliyun.com/gnu/make/make-4.3.tar.gz
- 从官方或阿里云的镜像下载,中国大陆从官方下载太慢;
tar -xvf make-4.3.tar.gz
- 解压;
cd make-4.3
- 移动到文件夹;
mkdir build && cd build
- 创建编译文件夹并移动;
../configure
- 跨上一级文件夹编译器配置;
make -j24
- 开始编译;
-j数值
代表编译线程,您可以根据您的处理器核心来决定使用多少线程,如-j8
;-j
则为不限制线程,但可能导致错误;
make install
- 安装;
make --v
- 验证版本;
如果无意外则会输出:
GNU Make 4.3
Built for x86_64-pc-linux-gnu
Copyright (C) 1988-2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
至此升级 make 完成。
2.升级 GCC 10.1.0
wget https://ftp.gnu.org/gnu/gcc/gcc-10.1.0/gcc-10.1.0.tar.gz
wget https://mirrors.aliyun.com/gnu/gcc/gcc-10.1.0/gcc-10.1.0.tar.gz
- 从官方或阿里云的镜像下载,中国大陆从官方下载太慢;
tar -xvf gcc-10.1.0.tar.gz
- 解压;
cd gcc-10.1.0
- 移动到文件夹;
./contrib/download_prerequisites
- 下载依赖包;
mkdir build && cd build
- 创建编译文件夹并移动;
mkdir /usr/local/gcc-10.1.0
- 创建安装文件夹;
../configure --prefix=/usr/local/gcc-10.1.0 --enable-checking=release --enable-languages=c,c++ --disable-multilib
../configure
跨上一级文件夹编译器配置;--prefix=/usr/local/gcc-10.1.0
指定安装目录;--enable-checking=release
在编译器中执行内部一致性检查;--enable-languages=c,c++
指定支持的语言;--disable-multilib
禁止编译适用于多重架构体系的库,就是 X86 X64 兼容之类的;
make -j24
- 开始编译;
-j数值
代表编译线程,您可以根据您的处理器核心来决定使用多少线程,如-j8
;-j
则为不限制线程,但可能导致错误;
make install
- 安装;
export PATH=/usr/local/gcc-10.1.0/bin:$PATH
- 设置为默认编译器,仅对当前会话有效;
- 永久启用后文会提到;
vim ~/.bashrc
- 编辑当前用户的 .bashrc 文件,当然你也可以写到全局配置文件;
在最后一行加入 export PATH=/usr/local/gcc-10.1.0/bin:$PATH
并保存。
source ~/.bashrc
- 让配置生效;
cd /usr/lib64
- 移动到 /lib64 目录;
rm -rf libstdc++.so.6
- 删除老版本的 libstc++ 软连接,使用
rm -rf
删软连接的时候千万不要在后面加/
;
ln -s /usr/local/gcc-10.1.0/lib64/libstdc++.so.6.0.28 libstdc++.so.6
- 把新的 libstc++ 软连接到系统库
然后我建议你在需要的时候链接回老版本,因为之后可能会遇到 lib64/libstdc++.so.6: undefined symbol: libiconv
这样的错误,导致 yum 不可用之类的问题。
连回老版本的方法:
cd /lib64
rm -rf libstdc++.so.6
ln -s libstdc++.so.6.0.19 libstdc++.so.6
gcc -v
- 检查新的 GCC 是不是生效了
如果无意外则会输出
使用内建 specs。
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/local/gcc-10.1.0/libexec/gcc/x86_64-pc-linux-gnu/10.1.0/lto-wrapper
目标:x86_64-pc-linux-gnu
配置为:../configure --prefix=/usr/local/gcc-10.1.0 --enable-checking=release --enable-languages=c,c++ --disable-multilib
线程模型:posix
Supported LTO compression algorithms: zlib
gcc 版本 10.1.0 (GCC)
strings /usr/lib64/libstdc++.so.6 | grep 'CXXABI'
- 检查新的 libstc++ 是不是生效了
如果无意外则会输出
CXXABI_1.3
CXXABI_1.3.1
CXXABI_1.3.2
CXXABI_1.3.3
CXXABI_1.3.4
CXXABI_1.3.5
CXXABI_1.3.6
CXXABI_1.3.7
CXXABI_1.3.8
CXXABI_1.3.9
CXXABI_1.3.10
CXXABI_1.3.11
CXXABI_1.3.12
CXXABI_TM_1
CXXABI_FLOAT128
CXXABI_1.3
CXXABI_1.3.11
CXXABI_1.3.2
CXXABI_1.3.6
CXXABI_FLOAT128
CXXABI_1.3.12
CXXABI_1.3.9
CXXABI_1.3.1
CXXABI_1.3.5
CXXABI_1.3.8
CXXABI_1.3.4
CXXABI_TM_1
CXXABI_1.3.7
CXXABI_1.3.10
CXXABI_1.3.3
至此升级 GCC 完成。
3.安装Python3
这个略了。
升级 Glibc 2.31
wget https://ftp.gnu.org/gnu/glibc/glibc-2.31.tar.gz
wget https://mirrors.aliyun.com/gnu/glibc/glibc-2.31.tar.gz
- 从官方或阿里云的镜像下载,中国大陆从官方下载太慢;
tar -xvf glibc-2.31.tar.gz
cd glibc-2.31
mkdir build
cd build
- 上面解释过了;
../configure --prefix=/usr --disable-profile --enable-add-ons --with-headers=/usr/include --with-binutils=/usr/bin
../configure
跨上一级文件夹编译器配置;- 不要改
--prefix=/usr
; --prefix=/usr
指定安装目录;--disable-profile
关掉 profiling 信息相关的库文件编译;--enable-add-ons
指示 glibc 使用附加的 NPTL 包作为线程库;--with-headers=/usr/include
指示 glibc 按照这个目录中的内核头文件编译自己,从而精确的知道内核的特性以根据这些特性对自己进行最佳化编译;--with-binutils=/usr/bin
保证在编译 glibc 时不会用错 Binutils;
make -j24
- 开始编译;
-j数值
代表编译线程,您可以根据您的处理器核心来决定使用多少线程,如 -j8;-j
则为不限制线程,但可能导致错误;
make install
- 安装;
这一步可能会出现
Execution of gcc -B/usr/bin/ failed!
The script has found some problems with your installation!
Please read the FAQ and the README file and check the following:
- Did you change the gcc specs file (necessary after upgrading from
Linux libc5)?
- Are there any symbolic links of the form libXXX.so to old libraries?
Links like libm.so -> libm.so.5 (where libm.so.5 is an old library) are wrong,
libm.so should point to the newly installed glibc file - and there should be
only one such link (check e.g. /lib and /usr/lib)
You should restart this script from your build directory after you've
fixed all problems!
Btw. the script doesn't work if you're installing GNU libc not as your
primary library!
make[1]: *** [Makefile:120: install] Error 1
make[1]: Leaving directory '/root/glibc-2.31'
make: *** [Makefile:12: install] Error 2
搜索此内容,得出的结果是大概不用管(?)
不放心的可以检测一下 libm.so
ls -l /usr/lib64/libm.so.6
没有意外就是已经连接到新版本了,如下
lrwxrwxrwx 1 root root 12 Jul 3 02:32 /usr/lib64/libm.so.6 -> libm-2.31.so
然后再次尝试安装还是报错,不太懂。
下面的检测看起来已经是安装成功了,系统/程序也没有异样。
ls -l /lib64/libc.so.6
- 检测是否已经安装,检查软连接;
出现
lrwxrwxrwx 1 root root 12 Jul 3 02:32 /lib64/libc.so.6 -> libc-2.31.so
即为成功
strings /lib64/libc.so.6 | grep GLIBC
- 再次验证
如果无意外则会输出
GLIBC_2.2.5
GLIBC_2.2.6
GLIBC_2.3
GLIBC_2.3.2
GLIBC_2.3.3
GLIBC_2.3.4
GLIBC_2.4
GLIBC_2.5
GLIBC_2.6
GLIBC_2.7
GLIBC_2.8
GLIBC_2.9
GLIBC_2.10
GLIBC_2.11
GLIBC_2.12
GLIBC_2.13
GLIBC_2.14
GLIBC_2.15
GLIBC_2.16
GLIBC_2.17
GLIBC_2.18
GLIBC_2.22
GLIBC_2.23
GLIBC_2.24
GLIBC_2.25
GLIBC_2.26
GLIBC_2.27
GLIBC_2.28
GLIBC_2.29
GLIBC_2.30
GLIBC_PRIVATE
为什么没有 2.31,我也不知道。
更新完可能会有的错误
更新完必定会有错误,这就是代价。
如果你运行 locale 命令报错的话,或者中文或其他语言变成了?????????
那么你需要
cd glibc-2.31/build
- 移动到编译 Glibc 的目录;
make localedata/install-locales
- 编译语言文件;
make install
- 再安装一次;
然后你的中文或是其他语言应该就不会????????了
遇到 lib64/libstdc++.so.6: undefined symbol: libiconv
这个原因是 libstdc++ 版本不匹配。解决方法:把 libstdc++ 的软连接改回老版本
这个问题应该是经常出现,比如 yum 什么的,多备着吧。
cd /lib64
rm -rf libstdc++.so.6
ln -s libstdc++.so.6.0.19 libstdc++.so.6
遇到 Error: /usr/lib64/libstdc++.so.6: version `CXXABI_1.3.*' not found
这个原因是 libstdc++ 版本不够新,解决方法:把 libstdc++ 的软连接改成新版本
首先找到你的gcc
源码编译文件夹,比如我的在/root/gcc-10.1.0/
cd /root/gcc-10.1.0/build/x86_64-pc-linux-gnu/libstdc++-v3/src/.libs
cp libstdc++.so.6.0.28 /usr/lib64/
- 把最新的 libstdc++.so.6 复制到 /usr/lib64/
cd /usr/lib64
rm -rf libstdc++.so.6
ln -s libstdc++.so.6.0.28 libstdc++.so.6
rm -rf libstdc++.so.6
删除老的软连接;- l
n -s libstdc++.so.6.0.28 libstdc++.so.6
把 libstdc++.so.6.0.28 软连接到 libstdc++.so.6;
更新完如果你的 yum 无任何反应
可能是因为 rpm 数据库有问题导致卡死
rm -f /var/lib/rpm/__db.00*
rpm --rebuilddb
yum clean all
rm -f /var/lib/rpm/__db.00*
删除 rpm 数据库文件;rpm --rebuilddb
重建 rpm数据库;yum clean all
清理可能的缓存;
然后你的 yum 应该能用了
6 条评论
109 永远滴神!
厉害,网上找到的最靠谱的方法
是的,靠谱,没有之一
tar -xvf glibc-2.31.tar.xz 写错了, 应该是 : tar -xvf glibc-2.31.tar.gz
回复 #4
同样,tar -xvf gcc-10.1.0.tar.xz -> tar -xvf gcc-10.1.0.tar.gz
回复 #5
感谢指正,已修改。