CentOS 7.9 glibc 2.17 源码编译升级到 glibc 2.31


环境

项目
系统 CentOS Linux release 7.9.2009
升级前 glibc 2.17
升级后 glibc 2.31
升级前 gcc 4.8.5
升级后 gcc 9.3.0
升级前 make 3.82
升级后 make 4.3
工作目录 /tmp/glibc-upgrade

1. 配置 yum 阿里源

bash 复制代码
mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.back
wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
yum clean all
yum makecache

2. 安装依赖

bash 复制代码
yum install -y python3 bison gcc-c++ glibc-devel glibc-headers texinfo

3. 升级 make 4.3

bash 复制代码
mkdir -p /tmp/glibc-upgrade && cd /tmp/glibc-upgrade
wget https://mirrors.aliyun.com/gnu/make/make-4.3.tar.gz
tar -zxf make-4.3.tar.gz
cd make-4.3
mkdir build && cd build
../configure --prefix=/usr
make -j$(nproc)
make install
make --version   # 验证: GNU Make 4.3

4. 升级 gcc 9.3.0

编译耗时约 40-60 分钟。

bash 复制代码
cd /tmp/glibc-upgrade
wget https://mirrors.aliyun.com/gnu/gcc/gcc-9.3.0/gcc-9.3.0.tar.gz
tar -zxf gcc-9.3.0.tar.gz
cd gcc-9.3.0
./contrib/download_prerequisites
mkdir build && cd build
../configure --enable-checking=release --enable-languages=c,c++ --disable-multilib --prefix=/usr/local/gcc
make -j$(nproc)
make install

配置软链接:

bash 复制代码
mv /usr/bin/gcc /usr/bin/gcc_4.8.5
ln -s /usr/local/gcc/bin/gcc /usr/bin/gcc
mv /usr/bin/g++ /usr/bin/g++_4.8.5
ln -s /usr/local/gcc/bin/g++ /usr/bin/g++
echo /usr/local/gcc/lib64 > /etc/ld.so.conf.d/gcc.conf
ldconfig
gcc -v   # 验证: gcc version 9.3.0

ldconfig 警告 /usr/local/gcc/lib64/libstdc++.so.6.0.28-gdb.py is not an ELF file 可忽略。

5. 编译安装 glibc 2.31

风险提示make install 会覆盖系统 /usr 下的 glibc 库。若编译失败不要 执行 make install,否则系统可能崩溃。安装成功后不要断开当前 SSH,先新开会话验证。

编译(约 20 分钟):

bash 复制代码
cd /tmp/glibc-upgrade
wget https://mirrors.aliyun.com/gnu/glibc/glibc-2.31.tar.gz
tar -zxf 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 --disable-sanity-checks --disable-werror
make -j$(nproc)

备份并安装:

bash 复制代码
cp -r /usr/lib64 /usr/lib64.back
make install

make install 最后的 test-installation.plcannot find -lnss_test2 是已知问题,不影响核心库安装。

验证:

bash 复制代码
ldd --version   # 输出: ldd (GNU libc) 2.31

注意rpm -q glibc 仍显示 2.17 --- 源码编译不会更新 RPM 数据库,是正常的。运行时依赖实际文件,不影响功能。

屏蔽 yum glibc 更新

源码安装后,yum update 可能因文件冲突报错。需将 glibc 加入 yum 排除列表:

bash 复制代码
echo "exclude=glibc*" >> /etc/yum.conf

验证:

bash 复制代码
grep exclude /etc/yum.conf   # 输出: exclude=glibc*

6. 安装 locale(可选)

bash 复制代码
make localedata/install-locales

验证结果

bash 复制代码
ldd --version   # ldd (GNU libc) 2.31
gcc --version   # gcc (GCC) 9.3.0
g++ --version   # g++ (GCC) 9.3.0
make --version  # GNU Make 4.3

注意事项

  1. 勿断开当前 SSH。新开会话验证系统正常后再关闭。
  2. 备份 /usr/lib64.back 保留,异常时可恢复。
  3. 旧版本二进制保留:
    • gcc 旧版: /usr/bin/gcc_4.8.5
    • glibc 旧版: /lib64/libc-2.17.so
  4. 确认稳定后可清理 /tmp/glibc-upgrade/

拓展:安装 devtoolset-11(GCC 11)

为什么需要

glibc 2.31 升级后,新版应用(如 Node.js ≥20)对新版 GCC 运行时(libstdc++.so.6libgcc_slibatomic)有要求:

运行时 系统默认 (glibc 升级后) 新版需要 不升级的后果
libstdc++.so.6 GLIBCXX 3.4.19 (GCC 4.8.5) ≥ GLIBCXX 3.4.21 Node 24 等无法启动
libgcc_s.so.1 GCC 4.8.5 ≥ GCC 11 异常处理与新 libstdc++ 不匹配
libatomic.so.1 ❌ 不存在 部分新代码需要 某些原生模块编译失败
方案对比
方案 优点 缺点 推荐
手动替换 libstdc++ 操作简单 只解决一个库,不配套
devtoolset-11 覆盖系统 libstdc++ 官方渠道、完整配套,同时升级 libgcc_s/libatomic 需配置 CentOS SCL 源
devtoolset-11 运行时启用 (source enable) 无需改动系统库 每个 shell 需手动启用,守护进程/服务可能找不到 开发环境可行

推荐方案:安装 devtoolset-11 并将 libstdc++.so.6 覆盖到系统路径,既保证所有进程能找到新版库,又获得完整的 GCC 工具链。

安装步骤

1. 配置 SCL 源

CentOS 7 官方源已失效,需指向 vault.archiv:

bash 复制代码
yum install -y centos-release-scl

# 替换 SCL 源为 vault.centos.org
cat > /etc/yum.repos.d/CentOS-SCLo-scl-rh.repo << 'EOF'
[centos-sclo-rh]
name=CentOS-7 - SCLo rh
baseurl=https://vault.centos.org/7.9.2009/sclo/$basearch/rh/
gpgcheck=1
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-SIG-SCLo
EOF

cat > /etc/yum.repos.d/CentOS-SCLo-scl.repo << 'EOF'
[centos-sclo-sclo]
name=CentOS-7 - SCLo sclo
baseurl=https://vault.centos.org/7.9.2009/sclo/$basearch/sclo/
gpgcheck=1
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-SIG-SCLo
EOF

yum clean all && yum makecache
2. 安装 devtoolset-11
bash 复制代码
yum install -y devtoolset-11-gcc devtoolset-11-gcc-c++
3. 获取新版 libstdc++.so.6 运行时

devtoolset-11 默认不提供独立的 libstdc++.so.6 运行时文件,需从 CentOS 8 vault 下载:

bash 复制代码
# 下载 CentOS 8 的 libstdc++ RPM
curl -sL "https://vault.centos.org/8.5.2111/BaseOS/x86_64/os/Packages/libstdc++-8.5.0-4.el8_5.x86_64.rpm" -o /tmp/libstdc++-centos8.rpm

# 提取 libstdc++.so.6.0.25
mkdir -p /tmp/rpm_extract
cd /tmp/rpm_extract
rpm2cpio /tmp/libstdc++-centos8.rpm | cpio -idm

# 覆盖到系统路径
cp /tmp/rpm_extract/usr/lib64/libstdc++.so.6.0.25 /usr/lib64/libstdc++.so.6.0.25
ln -sf libstdc++.so.6.0.25 /usr/lib64/libstdc++.so.6
ldconfig

# 验证
strings /usr/lib64/libstdc++.so.6 | grep GLIBCXX | tail -1
# 预期输出: GLIBCXX_3.4.25

# 清理
rm -rf /tmp/rpm_extract /tmp/libstdc++-centos8.rpm

此 libstdc++.so.6.0.25 来自 RHEL 8 官方 RPM,最低需要 glibc 2.18,与已升级的 glibc 2.31 兼容。

4. 验证
bash 复制代码
# 确认 libstdc++.so.6 指向新版
ls -la /usr/lib64/libstdc++.so.6
# lrwxrwxrwx. 1 root root 19 ... libstdc++.so.6 -> libstdc++.so.6.0.25

# 确认 GLIBCXX 版本
strings /usr/lib64/libstdc++.so.6 | grep -E "^GLIBCXX_3\.4" | sort -V | tail -3
# GLIBCXX_3.4.23
# GLIBCXX_3.4.24
# GLIBCXX_3.4.25

# 测试 node 24(如已安装)
source ~/.nvm/nvm.sh && nvm use 24 && node --version
# v24.x.x

默认启用 devtoolset(可选)

将以下内容加入 ~/.bashrc,使新 shell 自动使用 GCC 11:

bash 复制代码
# devtoolset-11 (GCC 11)
[ -s "/opt/rh/devtoolset-11/enable" ] && source "/opt/rh/devtoolset-11/enable"
bash 复制代码
# 验证新 shell 自动启用
bash -l -c 'gcc --version'
# gcc (GCC) 11.2.1 20220127 (Red Hat 11.2.1-9)

启用后 gcc/g++ 指向 GCC 11,向后兼容,不影响系统已有工具。如需临时切回 4.8.5,可运行 source /opt/rh/devtoolset-11/disable

相关推荐
charlie1145141911 小时前
嵌入式Linux驱动开发——class 和 device 模型 - 自动创建设备节点的幕后机制
linux·运维·驱动开发
杨云龙UP3 小时前
SQL Server2022部署:Windows Server 2016下安装、SSMS配置、备份还原与1433端口放通全流程_20260508
运维·服务器·数据库·sql·sqlserver·2022
梦想与想象-广州大智汇3 小时前
自建docker加速镜像,使用 Cloudflare Workers/Pages 部署加速教程
运维·docker·容器
枳实-叶3 小时前
【Linux驱动开发】第四天:dmesg日志全解+驱动加载失败极速排查
linux·运维·驱动开发
武超杰3 小时前
Nginx从入门到精通
运维·nginx
wdfk_prog4 小时前
正常关闭虚拟机时,不要点“关机”,而要点“关闭客户机”
linux·c语言·网络·ide·vscode
weixin_704266054 小时前
Nginx 反向代理 + 6 种负载均衡策略
运维·nginx
fish_xk5 小时前
Linux开方工具
linux·运维·服务器
中科三方7 小时前
输入域名后无法访问?教你快速区分域名解析问题与服务器问题
运维·服务器