资讯动态

CentOS源码编译Python 3.12:避开OpenSSL和系统Python冲突的完整指南

发布时间:2026/10/18 10:26:37 来源:尧图企业网站定制
在 CentOS 上装 Python 3.12说难不难说简单也真有不少坑。这篇文章不绕弯子直接讲我从下载源码到装完跑通的全过程包括那些文档里不会写的坑比如 OpenSSL 版本不对导致 ssl 模块装不上、装完 python3 命令还指向旧版本、pip 装包报错等等。如果你准备在 CentOS 7 或者 CentOS 8/9 上源码编译安装 Python 3.12.x这篇就是给你写的。先说结论CentOS 自带的 Python 版本普遍偏老很多新项目用不了而 yum 和系统组件又深度依赖旧版 Python你不能直接替换系统自带的否则会把系统搞挂。所以我下面讲的方法核心思路就是“源码编译 独立安装目录 不影响系统 Python”。1. 动手之前先搞清楚为什么要源码编译安装1.1 CentOS 自带的 Python 为什么不够用我碰到过不少朋友第一反应是直接yum install python3不就行了吗行但是装出来大概率是 Python 3.6 或者 3.8具体取决于你的 CentOS 版本。CentOS 7 默认带的 python 是 2.7python3 是 3.6CentOS 8 带的 python3 是 3.6/3.8 的样子。这些版本放到现在跑一些新框架、新语法早就力不从心了。而且这里有个非常重要的提醒yum 这个包管理器本身是依赖系统自带的 Python 的。在 CentOS 7 上yum 用的就是 Python 2.7。如果你手贱把系统的/usr/bin/python直接指向了 Python 3.x你猜怎么着yum 直接没法用了系统里一堆管理工具也跟着废掉。我见过有人这么干最后只能把软链接原样改回来甚至重装系统。所以最稳妥的思路就是让新版本的 Python 装在一个独立的目录里比如/usr/local/python312然后通过改 PATH 或者建软链接的方式让python3.12这个命令指向它不影响系统默认的/usr/bin/python。这就是所谓的“和平共处”。1.2 源码编译的核心思路源码编译安装的本质就是从 Python 官网下载源代码包在你自己的机器上完成编译、链接、安装到指定目录。整个过程可以理解为把一堆 C 源码变成可执行的二进制文件。为什么不用现成的 rpm 包或者第三方仓库因为 CentOS 官方源里的 Python 版本太老第三方仓库比如 EPEL 或者 SCL的版本也不一定跟进得快而且版本选择上不够自由。源码编译最大的好处就是你想装哪个版本就装哪个版本想装到哪个目录就装到哪个目录还能自己控制编译选项比如开优化比如指定 OpenSSL 的路径。当然代价就是编译需要时间和机器资源而且你得先把编译工具链和依赖库准备好。这一步是最容易出问题的很多人编译到一半报错就是依赖没装全。2. 环境准备与依赖安装2.1 安装编译工具链在 CentOS 上编译 C 源码本质上需要 gcc、make 这些基础工具。CentOS 7 上默认环境非常精简很多机器连 gcc 都没有。所以第一步先装编译工具组yum install -y gcc gcc-c make如果你是 CentOS 8/9把 yum 换成 dnf 即可dnf install -y gcc gcc-c make这里顺便说一句gcc-c必须装因为 Python 的很多扩展模块和依赖库在编译时会用到 C 编译器。只装 gcc 不装 gcc-c后面编译某些依赖就可能报错。另外推荐把zlib-devel也装上。这个东西负责压缩支持Python 的包管理工具 pip 在安装某些依赖时会用到 zlib。不装的话最常见的结果就是编译 Python 本身时提示ModuleNotFoundError: No module named zlib更常见的场景是后面用 pip 安装依赖时在源码编译环节因为缺少 zlib 而失败。所以这里一步到位yum install -y zlib-devel bzip2-devel libffi-devel这几个分别是压缩库、bzip2 压缩库以及 libffi用于调用 C 语言函数接口的底层库Python 的ctypes和cffi都依赖它。装完这三个能避免后面不少麻烦。2.2 OpenSSL 等关键依赖的处理说到依赖最重要的其实是 OpenSSL。Python 3.12 对 OpenSSL 的版本要求比之前更高它需要 OpenSSL 1.1.1 或更新版本。但 CentOS 7 系统自带的 OpenSSL 版本是 1.0.2k太老了直接编译 Python 3.12 的话最终编译出来的 Python 会缺少_ssl模块——也就是你用不了 HTTPS 请求pip 也基本没法用因为它要连 PyPI 下载包。在 CentOS 7 上我的处理办法是自己编译一个新版本的 OpenSSL放到独立目录然后编译 Python 的时候用--with-openssl参数指定路径。先说 CentOS 8/9系统自带的 OpenSSL 一般是 1.1.1满足 Python 3.12 的要求所以这条可以跳过。但如果你用的还是 CentOS 7或者某个精简过的老系统请务必跟着做。首先安装 OpenSSL 编译需要的 Perl以及必要的依赖yum install -y perl-core pcre-devel然后下载 OpenSSL 1.1.1 的源码这里以 1.1.1w 为例这是 1.1.1 系列的最终版本cd /usr/local/src wget https://www.openssl.org/source/openssl-1.1.1w.tar.gz tar -xzf openssl-1.1.1w.tar.gz cd openssl-1.1.1w接下来编译安装我习惯装到/usr/local/openssl这个目录./config --prefix/usr/local/openssl shared zlib make -j4 make install这里shared参数是生成动态库zlib是启用 zlib 压缩支持。如果编译过程报错缺少perl模块检查一下perl-core是否装好。编译完成之后还需要做一件事让系统能找到 OpenSSL 的动态库。新建一个文件/etc/ld.so.conf.d/openssl-1.1.1.conf内容写入/usr/local/openssl/lib然后执行ldconfig这一步的意义在于编译 Python 时不仅需要 OpenSSL 的头文件Python 运行时还要加载 OpenSSL 的动态库。如果动态库路径没加进去即使 Python 编译通过后面 import ssl 或者用 pip 时仍然可能报错。2.3 版本号的坑3.12.10 到底存不存在这里得专门说一个很多新手容易忽略的问题你在网上看到有人说“Python 3.12.10”先别急着下载先到 Python 官网看一眼这个版本号是否真实存在。Python 的版本发布有自己的节奏3.12 系列会陆续发布 3.12.0、3.12.1、3.12.2 这样递增的补丁版本。如果你看到的“3.12.10”正好是官方已经发布的版本那直接用没问题。如果你看到的时间点比较早官方还没发到 3.12.10那这个版本号很可能就是记错了或者臆想出来的号。我写这篇的时候Python 3.12 系列一直在发新补丁版所以 3.12.10 这个号是否已经发布请以官方为准。这不是抬杠是真有人在网上拿不存在的版本号提问下载时却发现 404。如果你也遇到这种情况正确做法是打开 Python 官方下载页面找到 3.12 系列中数字最大的那个补丁版本把下载链接里的版本号替换成实际的就行后面所有步骤完全一样。也就是说下面所有步骤里的版本号你完全可以替换为当时官方最新的 3.12.x 补丁版。3. 源码下载与编译安装全流程3.1 下载源码包与校验先创建源码目录然后去官网下载源码包。以 3.12.10 为例cd /usr/local/src wget https://www.python.org/ftp/python/3.12.10/Python-3.12.10.tgz下载完建议先做一下校验。官方提供了校验和文件你可以把对应的.sig文件也下载下来用 gpg 去验证签名也可以简单地用md5sum或者sha256sum自行比对一下。仓库里通常有SHA256SUMS文件。sha256sum Python-3.12.10.tgz把输出结果和官方文件比对一下。这一步虽然很多人不做但我强烈建议养成习惯。源码包被篡改的极端情况虽然少但一旦发生后果不是闹着玩的。另外wget的时候注意下载的是.tgz还是.tar.xz网上两种格式都有解压命令略有不同。然后解压tar -zxvf Python-3.12.10.tgz # 如果下载的是 .tar.xz用 tar -xJvf cd Python-3.12.103.2 configure 配置要点编译前最重要的一步就是 configure。这一步会检查系统环境、依赖库并生成 Makefile。很多人随便敲一下./configure就不管了最后装出来的 Python 缺东缺西。我这边建议的参数是./configure --prefix/usr/local/python312 \ --enable-optimizations \ --with-ensurepipinstall \ --with-openssl/usr/local/openssl逐个解释一下--prefix/usr/local/python312指定安装目录。让 Python 独立安装在/usr/local/python312下面而不是覆盖系统默认路径。这是不影响系统 Python的关键。--enable-optimizations开启编译优化。这个选项会做 Profile-Guided OptimizationPGO也就是根据运行时的测试情况来优化生成的二进制编译出来的 Python 执行性能会更好。代价是编译时间会明显变长我编译的时候大概花了二三十分钟如果你机器性能一般时间还会更久。--with-ensurepipinstall自动把 pip 装上。这个很关键如果不加你后面可能还得手动运行python -m ensurepip。--with-openssl/usr/local/openssl告诉 Python 使用我们自己编译的 OpenSSL。如果你用的是 CentOS 8/9系统 OpenSSL 版本足够可以去掉这个参数或者指定为系统路径。如果你的系统没有单独编译 OpenSSL并且系统自带的版本满足要求1.1.1 以上可以不加最后一个参数。但 CentOS 7 上必须加否则 ssl 模块会缺失。configure 执行完后会在屏幕上输出一大段检测结果。别急着往下走重点看有没有WARNING或者checking for openssl... no之类的字样。如果提示找不到某个库就先解决依赖再继续省得后面 build 到一半才报错。3.3 make 与 make installconfigure 没问题之后开始编译make -j4-j4意思是并行编译4 代表用 4 个 CPU 核心。如果你的机器核心数多可以写-j8甚至更多能显著缩短编译时间。但要注意如果机器内存不大并行数太高可能导致编译过程中内存不足表现就是编译进程被系统杀掉。我一般先看下机器配置内存 4G 左右就用-j28G 以上才用-j4或更高。编译过程会输出一大堆信息看到最后出现Successfully installed ...之类的提示就说明编译完成。如果中途报错不要慌看最后几行错误信息就能定位问题。最常见的就是缺某个头文件比如zlib.h。这时候返回去安装对应的-devel包重新跑make就行。编译完成后正式安装make install这一步会把 Python 文件复制到/usr/local/python312目录。注意如果你之前编译过一次第二次修改了 configure 参数建议先执行make clean清掉旧的编译缓存再重新 configure否则可能出现一些奇怪的链接错误。安装完以后验证一下核心模块/usr/local/python312/bin/python3.12 -c import ssl; print(ssl.OPENSSL_VERSION) /usr/local/python312/bin/python3.12 -c import zlib; print(zlib.ZLIB_VERSION)第一句能看到 OpenSSL 版本号第二句能看到 zlib 版本两个都不报错说明关键依赖到位了。3.4 altinstall 与 install 的区别这里必须重点讲一个很多人纠结的问题make install和make altinstall到底有什么区别简单说make install会同时安装python3、python等不带版本号的命令这会和系统自带的 Python 抢名字。在 CentOS 上我不推荐用make install原因前面已经说了——系统的/usr/bin/python不能动。而make altinstall只安装带版本号的命令比如python3.12不会生成python3这种不带完整版本号的命令所以不会覆盖系统原有命令。我个人的习惯是自己指定--prefix装到独立目录然后用make install因为反正装到独立目录不会和系统自带 Python 起冲突。但如果你用的是默认前缀/usr/local那还是用make altinstall更安全。不管哪种方式装完之后 Python 本体都在只是命令名字不一样。下面我统一按我自己的/usr/local/python312路径来讲。你的路径如果不是这个把下面的命令对应改一下就行。4. 安装后的环境配置4.1 PATH 与软链接设置装好之后直接敲python3.12大概率是找不到的因为/usr/local/python312/bin不在系统 PATH 里。你有两种办法解决我建议两个都做。第一种建立软链接让/usr/local/bin/python3.12指向真实安装路径ln -s /usr/local/python312/bin/python3.12 /usr/local/bin/python3.12 ln -s /usr/local/python312/bin/pip3.12 /usr/local/bin/pip3.12注意软链接的名字必须带完整版本号。不要建一个python3的软链接去指向 Python 3.12因为系统可能已经有/usr/bin/python3了。除非你确认系统默认 Python3 可以覆盖否则别这么干。第二种把安装目录加入 PATH。编辑/etc/profile.d/python312.shexport PATH/usr/local/python312/bin:$PATH然后让配置生效source /etc/profile.d/python312.sh这里加 PATH 的好处是以后python3.12和pip3.12命令在任何地方直接就能用。缺点是如果你同时装了多个 Python 版本要小心 PATH 顺序。我把这个文件放在/etc/profile.d下面这样所有用户都能用到。然后注销重新登录或者重新开一个终端验证一下python3.12 --version pip3.12 --version如果显示 Python 3.12.x就可以了。4.2 pip 与虚拟环境Python 3.12 自带的 pip 会随着编译一起装好因为我们加了--with-ensurepipinstall。如果因为某些原因没有装可以手动执行/usr/local/python312/bin/python3.12 -m ensurepip然后升级一下 pip/usr/local/python312/bin/python3.12 -m pip install --upgrade pip这里重点说一下虚拟环境。我强烈建议以后每个项目都用虚拟环境不要直接往系统环境里 pip install。原因很简单不同项目对包版本的要求可能互相冲突。项目 A 要 Django 3.2项目 B 要 Django 4.2直接装在同一个环境里必然打架。虚拟环境相当于给每个项目一个独立的房间互不干扰。创建虚拟环境/usr/local/python312/bin/python3.12 -m venv /opt/myproject_env然后激活source /opt/myproject_env/bin/activate激活之后命令行前面会出现(myproject_env)标记这时候你敲python、pip用的都是这个虚拟环境里的不会和全局环境冲突。想退出虚拟环境直接执行deactivate还有个小技巧如果你想知道当前用的 Python 是哪个执行which python能直接看到路径。我经常看到有人明明激活了虚拟环境却还在用系统 Python最后各种诡异报错。先查一下which再说。4.3 验证安装是否成功环境配置完以后别急着拿项目开刀先把基本功能都测一遍。我列了几个常用的验证项你可以一条一条执行看看python3.12 --version python3.12 -c import ssl, zlib, bz2, lzma, sqlite3; print(ok) python3.12 -m pip --version python3.12 -c import json, hashlib; print(hashlib.sha256(btest).hexdigest())第一条验证版本第二条验证常用模块第三条验证 pip第四条验证哈希算法是否正常。如果第二条报ModuleNotFoundError说明对应模块因为缺少系统库没有编译进去。比如缺 lzma通常要装xz-devel。缺 sqlite3要装sqlite-devel。如果需要补装依赖装完对应的-devel包后回到/usr/local/src/Python-3.12.10目录执行make clean之后重新 configure、make、make install 整套流程。是的源码编译的缺点就是这个——装完才发现的缺模块得重新编译一遍没有捷径。5. 常见问题与排查实录5.1 import ssl 报错 / 找不到 _ssl 模块这是 CentOS 7 上最典型的坑错误信息类似ModuleNotFoundError: No module named _ssl或者 pip 执行时报pip is configured with locations that require TLS/SSL, however the ssl module in Python is not available.原因就是我前面说的系统自带的 OpenSSL 版本太旧或者编译时没指定新版 OpenSSL 路径。排查方法python3.12 -c import ssl如果报错先确认你编译 Python 时是否带了--with-openssl/usr/local/openssl参数。如果带了但还是报错检查/usr/local/openssl/lib是否在动态库搜索路径里ldconfig -p | grep ssl看不到/usr/local/openssl/lib/libssl.so的话确认/etc/ld.so.conf.d/openssl-1.1.1.conf文件是否存在且内容正确然后重新ldconfig。还有一种情况你确实带了参数但 configure 的时候把路径写错了导致 Python 没找到 OpenSSL 的头文件。可以去config.log里搜openssl关键词看到底去哪里找了。5.2 装完以后 python3 还是旧版本如果你敲python3 --version显示的还是 Python 3.6而python3.12 --version正常说明你没有正确修改 PATH 或者没有建立软链接。按 4.1 节的做法两个方案选一个执行。但记住不要直接把/usr/bin/python3覆盖掉那样会连累系统工具。顺便说一句很多人以为改 PATH 是改.bashrc这在你自己账号下没问题但如果你想全局生效放在/etc/profile.d/下面更好。如果你改了.bashrc但当前终端没生效执行source ~/.bashrc再试。5.3 pip 安装依赖时报错最常见的有两类。第一类是编译依赖时报错缺失头文件比如装某些带 C 扩展的包时提示fatal error: Python.h: No such file or directory。这说明当前环境缺少 Python 的头文件而我们的 Python 是源码编译的头文件在/usr/local/python312/include/python3.12目录。如果你用的虚拟环境出现这个问题一般是编译报错的具体包依赖某些系统库按提示安装对应的-devel包就好。第二类是权限问题。如果你不用虚拟环境直接往全局环境里安装包有时候会碰到Permission denied。两种情况解法不同全局环境用sudo或者直接以 root 用户装虚拟环境不存在这个问题因为虚拟环境目录权限归你自己。我的习惯是任何项目都建虚拟环境。装包不要图省事全局环境装得乱七八糟最后出了问题几乎没法排查。5.4 编译时间太长 / 机器卡死有人问我加了--enable-optimizations之后编译要等很久是不是不正常正常的PGO 优化需要额外执行一轮测试程序收集性能数据整个过程比普通编译慢两三倍都正常。如果你的机器内存小比如 2G编译时候内存不够导致进程被杀解决方法是降低并行度用make -j1。虽然慢但至少能跑完。或者干脆去掉--enable-optimizations只追求能装上性能差点就差点很多场景下差异没那么明显。5.5 和 yum 的兼容性问题怎么避免最后再提一次别碰系统 Python 的命令名。在 CentOS 7 上/usr/bin/python是指向 Python 2.7 的yum依赖它。在 CentOS 8/9 上/usr/bin/python3是系统组件依赖的。你新装的 Python 3.12 虽然不影响它们但如果你为了让python3命令指向新版本而强行替换了软链接yum 或者 dnf 就会出问题。最保险的方案就是不用python3这个不带版本号的名字统一用python3.12或者虚拟环境里的python。养成这个习惯能省掉后续一堆麻烦。我的实际体会这套流程我前前后后跑过好几遍CentOS 7 编译一次大概 20 到 40 分钟CentOS 8/9 稍微快一点主要差在 PGO 那一步。最让我省心的做法就是先把 OpenSSL 在/usr/local/openssl单独装好然后 configure 的参数里一步到位别想着后面再补救。补模块就意味着重新编译浪费时间。另外一个经验是源码目录解压之后configure 之前先把依赖都装齐。你可以先用yum install -y gcc gcc-c make zlib-devel bzip2-devel libffi-devel这一条命令把最常用的装完再缺什么补什么。这样整个编译过程基本不会中途停下来。如果你只是在 CentOS 系统上跑项目不折腾系统 Python这套独立安装的方案是性价比最高的。既解决了版本太旧的问题又保证了系统的稳定性。等哪天你习惯了 Python 3.12 的语法和性能再回头看系统自带的那个旧版本就会觉得这一步花的功夫特别值了。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑