Ubuntu安装Python 3.7缺少ssl或libffi依赖怎么解决
在 Ubuntu 环境下从源码编译或通过版本工具安装 Python 3.7 时,最常见的两类阻碍是 _ssl 模块构建失败(导致后续 pip 无法拉取 HTTPS 依赖)和 _ctypes 模块缺失(导致 ModuleNotFoundError: No module named '_ctypes')。这两类问题的本质是底层 C 扩展头文件缺失,或者宿主机当前默认的 OpenSSL 库版本与 Python 3.7 源码不兼容。完整的解决路径是:首先通过软件源补齐编译构建工具集与 libffi-dev 消除 ctypes 缺失;随后根据 Ubuntu 发行版版本判定 OpenSSL 兼容性,针对 Ubuntu 18.04/20.04 直接安装系统开发库,针对 Ubuntu 22.04 及更高版本独立构建 OpenSSL 1.1.1 隔离环境并显式链接,最后使用 altinstall 安全安装并完成验证。
一、故障表象与深层根本原因分析
在执行 Python 3.7 源码编译的 make 阶段,控制台尾部经常会出现类似以下提示:
虽然最终提示“Python build finished successfully”,但这仅代表解释器核心可执行文件完成构建,而上述标出的可选 C 扩展模块被直接略过。若不加以解决直接使用该 Python 环境,将在运行时遇到直接阻碍:
_ctypes缺失问题:Python 标准库的ctypes模块高度依赖底层系统库libffi(外部函数接口开发库)。若系统缺失其 C 头文件(主要是ffi.h),构建脚本无法编译出_ctypes.so。当执行import ctypes或安装大部分包含 C 扩展的轮子包时,将直接抛出ModuleNotFoundError: No module named '_ctypes'。_ssl缺失与版本冲突问题:Python 3.7 开发维护周期较早,其内部_ssl.c模块针对 OpenSSL 1.0.2 与 1.1.x 的 API 规范编写。在 Ubuntu 18.04 和 20.04 中,系统默认提供的是 OpenSSL 1.1.1,缺失仅因未安装libssl-dev;但在 Ubuntu 22.04(Jammy)与 24.04(Noble)中,操作系统默认升级为 OpenSSL 3.0+,废弃了旧版大量结构体与直接函数指针。即使安装了系统的libssl-dev,Python 3.7 构建脚本也会判定版本不满足要求而自动跳过构建,最终导致解释器无法使用 HTTPS。
二、基础环境准备与 libffi-dev 依赖安装
在所有 Ubuntu 发行版中,libffi-dev 均可直接通过官方 APT 源进行安装。除此之外,建议同时补齐 Python 3.7 构建所需的完整常用编译工具链和辅助压缩库,避免在编译过程中出现二次缺包中断。
在终端中执行更新并安装基础依赖集:
sudo apt update
sudo apt install -y build-essential libffi-dev zlib1g-dev \
libbz2-dev libreadline-dev libsqlite3-dev libncurses5-dev \
libgdbm-dev libnss3-dev wget curl llvm xz-utils tk-dev
执行该命令后,系统将在 /usr/include/ 或 /usr/include/x86_64-linux-gnu/ 路径下部署 ffi.h 与 ffitarget.h。Python 源码的 setup.py 会自动探测到此路径,从而彻底消除 _ctypes 的构建缺失问题。
三、按 Ubuntu 版本解决 OpenSSL 依赖
处理 OpenSSL 依赖前,必须先核实当前服务器或本地机器的 Ubuntu 实际发行版本:
lsb_release -a
方案 A:针对 Ubuntu 18.04 / 20.04
在 Ubuntu 18.04 和 20.04 LTS 中,系统自带的 OpenSSL 属于 1.1.1 系列,与 Python 3.7 完美匹配。只需要通过包管理器安装开发头文件包即可:
sudo apt install -y libssl-dev
安装完成后,系统 /usr/include/openssl 目录下会包含全套 1.1.1 版头文件,在后续配置 Python 时无需指定特殊路径,默认即可成功检测。
方案 B:针对 Ubuntu 22.04 / 24.04(独立编译 OpenSSL 1.1.1)
若在 Ubuntu 22.04+ 执行 sudo apt install libssl-dev,安装的将是 OpenSSL 3.0 或 3.2 的头文件,Python 3.7 编译依然会报 ssl 失败。切勿尝试通过强制覆盖或卸载系统 OpenSSL 3.0 来解决,否则会导致系统的 apt、ssh 和桌面会话等基础服务直接损坏瘫痪。标准且安全的做法是:将 OpenSSL 1.1.1 独立安装在一个隔离目录(如 /usr/local/openssl11),专供 Python 3.7 链接使用。
四、Ubuntu 22.04 / 24.04 独立编译 OpenSSL 1.1.1 完整操作
为了保证系统稳定与隔离性,下面给出下载官方 OpenSSL 1.1.1 源码并在 /usr/local/openssl11 完成独立部署的具体步骤。
1. 获取并解压 OpenSSL 1.1.1 源码
cd /tmp
wget https://www.openssl.org/source/openssl-1.1.1w.tar.gz
tar -zxvf openssl-1.1.1w.tar.gz
cd openssl-1.1.1w
2. 指定前缀并编译安装
使用 --prefix 与 --openssldir 将安装路径锁定在 /usr/local/openssl11,并声明生成共享库(shared):
./config --prefix=/usr/local/openssl11 --openssldir=/usr/local/openssl11 shared zlib
make -j$(nproc)
sudo make install_sw
使用 install_sw 替代常规的 install,可以跳过手册页(man docs)的生成与写入,既大幅节约安装时间,又防止旧版手册覆盖系统的 OpenSSL 3.x 手册。
3. 注册共享库路径
为了让编译生成的动态库 libssl.so.1.1 和 libcrypto.so.1.1 能被系统动态链接器寻址,创建独立的 ld 配置文件:
echo "/usr/local/openssl11/lib" | sudo tee /etc/ld.so.conf.d/openssl11.conf
sudo ldconfig -v | grep -E "libssl.so.1.1|libcrypto.so.1.1"
五、重新配置与编译安装 Python 3.7
完成依赖库准备后,下载并进入 Python 3.7 源码包(以稳定版本 3.7.17 为例)。
cd /tmp
wget https://www.python.org/ftp/python/3.7.17/Python-3.7.17.tgz
tar -zxvf Python-3.7.17.tgz
cd Python-3.7.17
1. 配置阶段(带参数)
在 Ubuntu 18.04/20.04 下,执行常规配置:
./configure --enable-optimizations --with-ensurepip=install
在 Ubuntu 22.04 / 24.04 下,显式传入我们刚刚部署的 OpenSSL 1.1.1 路径:
./configure --enable-optimizations \
--with-openssl=/usr/local/openssl11 \
--with-ensurepip=install \
LDFLAGS="-Wl,-rpath=/usr/local/openssl11/lib"
传入 -Wl,-rpath=/usr/local/openssl11/lib 会把动态库寻址路径硬编码入生成的 Python 二进制 ELF 头中。这样即使在某些不读取全局 ld.so.conf 的隔离子进程或特定容器内运行,Python 3.7 也能精准定位到 /usr/local/openssl11/lib/libssl.so.1.1,杜绝运行时报错。
2. 执行多核编译与安全安装
make -j$(nproc)
sudo make altinstall
切忌使用 make install。如果执行 make install,会直接覆盖 Ubuntu 系统自带的 /usr/bin/python3 软链接,导致系统级管理工具(如 apt、cloud-init)因解释器版本变更而崩溃。altinstall 仅会创建带版本后缀的 /usr/local/bin/python3.7 与 pip3.7,确保系统原有 Python 环境完全不受影响。
六、结果验证与排错排查决策树
安装完成后,必须逐一验证 ctypes、ssl 以及 pip 核心功能:
1. 验证 ctypes 动态调用模块
python3.7 -c "import _ctypes; print('ctypes 模块加载成功')"
2. 验证 ssl 模块与底层 OpenSSL 版本
python3.7 -c "import ssl; print(ssl.OPENSSL_VERSION)"
3. 验证 pip HTTPS 网络连接能力
python3.7 -m pip --version
python3.7 -m pip install --upgrade pip --dry-run
七、补充场景:通过 pyenv 安装时的参数传递
若读者习惯使用 pyenv 管理多版本 Python,在 Ubuntu 22.04+ 执行 pyenv install 3.7.17 同样会默认触发 ERROR: The Python ssl extension was not compiled. Missing the OpenSSL lib? 报错。在上述步骤完成 OpenSSL 1.1.1 独立安装至 /usr/local/openssl11 之后,可以通过环境变量将编译配置传递给 pyenv:
CONFIGURE_OPTS="--with-openssl=/usr/local/openssl11" \
CPPFLAGS="-I/usr/local/openssl11/include" \
LDFLAGS="-L/usr/local/openssl11/lib -Wl,-rpath=/usr/local/openssl11/lib" \
pyenv install 3.7.17
pyenv 将自动拉取编译参数,准确绑定独立的 OpenSSL 1.1.1,从而在无需任何侵入性修改的情况下顺利构建出具备完整 SSL 与 ctypes 支持的 Python 3.7 环境。
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













