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

QiuSYan ( ᗜ ‸ ᗜ )

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 服务器平台提供了两种环境:PythonJava。一开始我是拿来搭建我的 Minecraft 服务器,因此选的是 Java 环境。
前段时间我寻思着,既然我都已经把 QQbot 后端,也就是 gocq 给扔到服务器上面了,那我能不能一起复活一下我的 Nonebot 机器人呢?
说干就干。Nonebot 是由 Python 写的,且仅支持 Python 3.9 及以上版本,我直接就在我虚拟机上用 Python3.10 创了个虚拟环境扔了上去。
结果在使用 Python 时报错:

1
2
3
4
5
/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)
/home/container/plugins/nb/.venv/bin/python3.10: /lib/x86_64-linux-gnu/libm.so.6: version `GLIBC_2.29' not found (required by /home/container/plugins/nb/.venv/bin/python3.10)
/home/container/plugins/nb/.venv/bin/python3.10: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.33' not found (required by /home/container/plugins/nb/.venv/bin/python3.10)
/home/container/plugins/nb/.venv/bin/python3.10: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.32' not found (required by /home/container/plugins/nb/.venv/bin/python3.10)
/home/container/plugins/nb/.venv/bin/python3.10: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found (required by /home/container/plugins/nb/.venv/bin/python3.10)

寄。glibc 版本低了。
然后一看平台给的容器镜像是 Debian 6,glibc 版本是 2.28,也升不了 glibc,那就只能启动 编译大法 了!

工具

  • 一台可联网的 Linux 机器 (没有的可以整个虚拟机 我用的是 Ubuntu 22.04
  • 较好的耐心
  • 自行使用搜索引擎的能力

开始

第三节第四节的所有操作均在 Docker 容器内进行

先使用脚本一键安装 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
2
3
4
5
6
7
# 换源
sed -i 's@//.*archive.ubuntu.com@//mirrors.tuna.tsinghua.edu.cn@g' /etc/apt/sources.list
sed -i 's/security.ubuntu.com/mirrors.tuna.tsinghua.edu.cn/g' /etc/apt/sources.list

# 更新与安装
apt-get update
apt-get install -y build-essential zlib1g-dev libssl-dev libffi-dev libbz2-dev libsqlite3-dev libreadline-dev liblzma-dev tk-dev patchelf rsync

然后下载 Python3.10 的源码:

1
2
3
4
cd /root
wget https://www.python.org/ftp/python/3.10.13/Python-3.10.13.tgz
tar -xzf Python-3.10.13.tgz
cd Python-3.10.13

配置编译参数:

1
2
3
4
5
6
./configure \
--prefix=/opt/python-3.10-static \
--enable-optimizations \
--with-lto \
--with-system-ffi=no \
--enable-shared

仅编译不安装:

1
make -j$(nproc)

手动生成缺失的模块:

1
2
3
4
# 进入构建目录
cd build/lib.linux-x86_64-3.10
# 手动生成缺失的模块
./python3.10 -c "import _posixsubprocess"

跳过 ensurepip 安装(后续手动安装 pip):

之前直接安装过出错了,不知道为什么,只能先跳过了

1
make install ENSUREPIP=no

make 完成后手动安装 pip:

1
2
3
4
5
# 下载get-pip.py
curl -O https://bootstrap.pypa.io/get-pip.py

# 使用编译的Python安装pip
/opt/python-3.10-static/bin/python3.10 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
2
3
cp /usr/lib/x86_64-linux-gnu/libssl.so.1.1 /opt/myenv/lib/
cp /usr/lib/x86_64-linux-gnu/libcrypto.so.1.1 /opt/myenv/lib/
cp /opt/python-3.10-static/lib/libpython3.10.so.1.0 /opt/myenv/lib

随后使用 patchelf 修改 Python 解释器和库的链接路径:

1
2
patchelf --set-rpath '$ORIGIN/../lib' /opt/myenv/bin/python3.10
patchelf --set-rpath '$ORIGIN' /opt/myenv/lib/libssl.so.1.1

关于 patchelf 有个需要注意的地方:
前面使用了 apt 直接安装了较低版本的 patchelf,这个低版本的使用指令会报错,所以需要安装 Github 上的最新版本。

  1. 克隆仓库:
    1
    git clone https://github.com/NixOS/patchelf.git
  2. 进入目录,运行脚本以生成构建所需的文件:
    1
    2
    cd patchelf
    ./bootstrap.sh
  3. 运行 configure 脚本来配置构建环境:
    1
    ./configure
  4. 使用 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
2
# 复制库到虚拟环境
rsync -av --exclude='site-packages/' /opt/python-3.10-static/lib/python3.10/ /opt/myenv/lib/python3.10/

最后用 7zzipmyenv 目录压缩,用 docker cp 复制到宿主机后 扔到目标机器上即可。

好了,目前为止准备工作算是做完了。之后是将其转移到目标机器上后的步骤了。

目标机器

转移到目标机器上后,并不能马上使用,还要经过最后一道程序才能正常使用 python 和 pip:
需要更改 myenvpippyvenv.cfgpython 二进制文件的路径

比如说,我原本的 python 主体路径 为 /opt/python-3.10-static
目标机器上的虚拟环境路径为 /home/container/myenv
则使用指令一键替换:

1
2
3
4
5
6
7
# 替换pyvenv.cfg
cd /home/container/myenv
sed -i "s|/opt/python-3.10-static|/home/container/myenv|g" pyvenv.cfg

# 替换pip
cd /home/container/myenv/bin
sed -i "s|/opt/python-3.10-static|/home/container/myenv|g" pip pip3 pip3.10

别忘了加 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 进行许可。
评论
Nickname
Email
Website
0/500
  • OωO
  • |´・ω・) ノ
  • ヾ (≧∇≦*) ゝ
  • (☆ω☆)
  • (╯‵□′)╯︵┴─┴
  •  ̄﹃ ̄
  • (/ω\)
  • ∠( ᐛ 」∠)_
  • (๑•̀ㅁ•́ฅ)
  • →_→
  • ୧(๑•̀⌄•́๑)૭
  • ٩(ˊᗜˋ*)و
  • (ノ °ο°) ノ
  • (´இ皿இ`)
  • ⌇●﹏●⌇
  • (ฅ´ω`ฅ)
  • (╯°A°)╯︵○○○
  • φ( ̄∇ ̄o)
  • ヾ (´・ ・`。) ノ "
  • (ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
  • (ó﹏ò。)
  • Σ(っ °Д °;) っ
  • (,,´・ω・)ノ"(´ っ ω・`。)
  • ╮(╯▽╰)╭
  • o(*////▽////*)q
  • >﹏<
  • ( ๑´•ω•) "(ㆆᴗㆆ)
  • 😂
  • 😀
  • 😅
  • 😊
  • 🙂
  • 🙃
  • 😌
  • 😍
  • 😘
  • 😜
  • 😝
  • 😏
  • 😒
  • 🙄
  • 😳
  • 😡
  • 😔
  • 😫
  • 😱
  • 😭
  • 💩
  • 👻
  • 🙌
  • 🖕
  • 👍
  • 👫
  • 👬
  • 👭
  • 🌚
  • 🌝
  • 🙈
  • 💊
  • 😶
  • 🙏
  • 🍦
  • 🍉
  • 😣
  • 颜文字
  • Emoji
  • Bilibili
0 comments
No comment
目录
高版本 Python 在低 glibc 版本下的使用方法