高版本 Python 在低 glibc 版本下的使用方法

AI 摘要
文章标题:低 glibc 版本下使用高版本 Python 的编译与迁移指南 ・问题背景:在 Java 环境中尝试使用 Python 3.10,遇到 glibc 版本不兼容问题(版本 2.28)。 ・解决方案: 1. 利用 Docker 构建 Ubuntu 18.04 镜像,版本与服务器一致以兼容 glibc 2.28。 2. 安装必要的构建工具(如 build-essential、zlib 等)。 3. 下载并编译 Python 3.10 源码,配置参数以生成静态版本。 4. 手动安装 pip 并跳过 ensurepip。 5. 配置虚拟环境,复制动态库和 patchelf。 6. 避免库路径错误,手动复制标准库并调整配置文件路径。 7. 将虚拟环境压缩并转移至目标机器,执行替换和 PATH 设置。 ・适用场景:适用于在 glibc 版本较低的环境中使用较高版本 Python 的开发者,如老旧平台或受限环境下的部署。 ・注意事项:编译过程需联网,且可能涉及版本兼容性和脚本更新问题。
写这篇文章是因为前段时间想在某平台上的 Java 环境中使用 Python,当时搞了半天才搞好,特此记录以免将来忘记。
前言
某 Minecraft 服务器平台提供了两种环境:Python
和 Java
。一开始我是拿来搭建我的 Minecraft 服务器,因此选的是 Java 环境。
前段时间我寻思着,既然我都已经把 QQbot 后端,也就是 gocq
给扔到服务器上面了,那我能不能一起复活一下我的 Nonebot 机器人呢?
说干就干。Nonebot
是由 Python 写的,且仅支持 Python 3.9
及以上版本,我直接就在我虚拟机上用 Python3.10 创了个虚拟环境扔了上去。
结果在使用 Python 时报错:
1 | /home/container/plugins/nb/.venv/bin/python3.10: /lib/x86_64-linux-gnu/libm.so.6: version `GLIBC_2.35' not found (required by /home/container/plugins/nb/.venv/bin/python3.10) |
寄。glibc 版本低了。
然后一看平台给的容器镜像是 Debian 6
,glibc 版本是 2.28,也升不了 glibc,那就只能启动 编译大法 了!
工具
- 一台可联网的 Linux 机器 (没有的可以整个虚拟机 我用的是
Ubuntu 22.04
) - 较好的耐心
- 自行使用搜索引擎的能力
开始
先使用脚本一键安装 Docker:
1 | bash <(curl -sSL https://linuxmirrors.cn/docker.sh) |
此脚本会自动更换 docker 源,按照脚本指引安装即可。
然后启动一个相同 glibc 版本的 docker 镜像。由于平台上面的是 glibc 2.28,我这里就选用 Ubuntu 18.04 (glibc 版本 2.28) 来构建:
1 | docker run -it --name pybuild ubuntu:18.04 |
下载完镜像后会自动进入容器中。随后换源与下载必要的构建工具:
1 | # 换源 |
然后下载 Python3.10 的源码:
1 | cd /root |
配置编译参数:
1 | ./configure \ |
仅编译不安装:
1 | make -j$(nproc) |
手动生成缺失的模块:
1 | # 进入构建目录 |
跳过 ensurepip 安装(后续手动安装 pip):
之前直接安装过出错了,不知道为什么,只能先跳过了
1 | make install ENSUREPIP=no |
make 完成后手动安装 pip:
1 | # 下载get-pip.py |
现在你的可用于低 glibc 版本的 Python3.10 就编译好了,路径位于 Docker
容器中的 /opt/python-3.10-static
。不过如果需要正常使用的话,还需要加一条 PATH:
1 | export LD_LIBRARY_PATH="/opt/python-3.10-static/lib:$LD_LIBRARY_PATH" |
这样才能正常使用 不要问我为什么要手动指定路径因为我也不知道 。
用例:
1 | /opt/python-3.10-static/bin/python --version |
虚拟环境
现在,Python 本体已经编译好了,但是为了便捷性与不必要的麻烦,通常是 将虚拟环境迁移到其他机器 而非本体。
以
/opt/python-3.10-static/bin
为 Python 目录
先创建一个虚拟环境:
1 | /opt/python-3.10-static/bin/python3.10 -m venv --copies /opt/myenv |
使用
--copies
参数来复制二进制文件
再复制一些必要动态库到虚拟环境:
1 | cp /usr/lib/x86_64-linux-gnu/libssl.so.1.1 /opt/myenv/lib/ |
随后使用 patchelf 修改 Python 解释器和库的链接路径:
1 | patchelf --set-rpath '$ORIGIN/../lib' /opt/myenv/bin/python3.10 |
关于
patchelf
有个需要注意的地方:
前面使用了 apt 直接安装了较低版本的patchelf
,这个低版本的使用指令会报错,所以需要安装Github
上的最新版本。
- 克隆仓库:
1 git clone https://github.com/NixOS/patchelf.git- 进入目录,运行脚本以生成构建所需的文件:
1
2 cd patchelf
./bootstrap.sh- 运行 configure 脚本来配置构建环境:
1 ./configure- 使用
make
编译 / 测试 / 安装
1
2
3
4
5
6
7
8 # 编译项目
make
# 测试项目
make check
# 安装 patchelf
make install
然后就是跟之前一样的加一条 PATH:
1 | export LD_LIBRARY_PATH="/opt/myenv/lib:$LD_LIBRARY_PATH" |
由于这将是单独的 Py 虚拟环境,而其内置的标准库(如 encodings
等)未在虚拟环境中,如果直接运行它的 py 和 pip 会报错,所以需要手动复制。
1 | # 复制库到虚拟环境 |
最后用 7z
或 zip
将 myenv
目录压缩,用 docker cp
复制到宿主机后 扔到目标机器上即可。
好了,目前为止准备工作算是做完了。之后是将其转移到目标机器上后的步骤了。
目标机器
转移到目标机器上后,并不能马上使用,还要经过最后一道程序才能正常使用 python 和 pip:
需要更改 myenv
中 pip
和 pyvenv.cfg
中 python 二进制文件的路径。
比如说,我原本的 python 主体路径 为 /opt/python-3.10-static
目标机器上的虚拟环境路径为 /home/container/myenv
则使用指令一键替换:
1 | # 替换pyvenv.cfg |
别忘了加 PATH:
1 | export LD_LIBRARY_PATH="/home/container/myenv/lib:$LD_LIBRARY_PATH" |
之后使用的时候直接用 /home/container/myenv/bin/python
即可。
- 标题: 高版本 Python 在低 glibc 版本下的使用方法
- 作者: QiuSYan
- 创建于 : 2025-04-05 11:45:01
- 更新于 : 2025-04-26 21:23:17
- 链接: https://blog.qiusyan.top/posts/23909.html
- 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。