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

QiuSYan ( ᗜ ‸ ᗜ )

AI 摘要

正在生成中……

写这篇文章是因为前段时间想在某平台上的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-07-13 13:23:16
  • 链接: https://blog.qiusyan.top/posts/23909.html
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
评论
目录
高版本Python在低glibc版本下的使用方法