编译安装是最灵活的——编译安装学会了,以后不管仓库里有没有你要的版本,都可以自己搞定。跟着做,每一步都有注释和期待回显,出了问题翻 Q&A。
1. 为什么要选编译安装?
在上一篇「在线安装篇」里,我们用 apt/yum/dnf 一两条命令就把 Python 装好了,简单快捷。那为什么还需要编译安装这种"费力"的方式?
原因如下:
版本自由。官方软件仓库里的 Python 版本由发行版维护者决定,不一定跟上游同步。比如 CentOS 7 官方仓库只有 Python 3.6,Ubuntu 20.04 只有 3.8。但如果你的项目需要 Python 3.12 的某个新特性,或者需要和同事保持完全一致的版本,就只能自己编译。
编译选项可控。你可以在 ./configure 阶段开启或关闭特定的编译选项,比如启用 --enable-optimizations 让 Python 性能提升 10-20%,或者开启 --with-lto(链接时优化)进一步压榨性能。这些都是在线安装做不到的。
安装路径可定制。编译安装可以把 Python 装到你想要的任何目录,不污染系统路径,方便管理和切换。
适合离线或受限环境。有些生产环境不允许直接连外网,只能提前下载好源码包,再进行编译安装。
当然,编译安装的代价是时间和复杂度:需要先装一堆编译依赖,编译过程本身要花几分钟到十几分钟(取决于机器性能),出问题时定位成本也比在线安装高。但只要跟着这篇教程走,流程其实并不难。
2. 环境确认:操作前先摸清底细
2.1 确认 Linux 发行版
# 查看发行版信息,几乎所有 Linux 发行版都有这个文件cat /etc/os-release
期待输出(Ubuntu 22.04 示例):
NAME="Ubuntu"VERSION="22.04.3 LTS (Jammy Jellyfish)"ID=ubuntuID_LIKE=debianPRETTY_NAME="Ubuntu 22.04.3 LTS"VERSION_ID="22.04"
# 备用命令,适合 Debian 系发行版lsb_release -a
期待输出:
NoLSBmodulesareavailable.DistributorID: UbuntuDescription: Ubuntu 22.04.3LTSRelease: 22.04Codename: jammy
2.2 确认系统架构
# 查看 CPU 架构,编译安装时需要确认uname -m
期待输出(常见结果):
x86_64# 64 位 Intel/AMD,最常见aarch64 # 64 位 ARM,如树莓派 4、部分云服务器armv7l # 32 位 ARM,如树莓派 3 及更老的型号
Python 官方源码对主流架构均支持,编译流程一致,不需要特殊处理。
2.3 确认当前用户和权限
# 查看当前用户whoami
期待输出(root 用户):
root
期待输出(普通用户):
ubuntu
编译安装涉及写入 /usr/local 等目录,如果是普通用户,后续命令需要加 sudo。如果是 root 用户,则不需要。
2.4 确认磁盘空间
编译过程会产生大量临时文件,加上源码包和最终安装文件,整体需要至少 1.5 GB 的可用空间。
# 查看各挂载点的磁盘使用情况df -h
期待输出:
Filesystem Size Used Avail Use% Mounted on/dev/sda1 40G 12G 26G 32% /tmpfs 1.9G 01.9G 0% /dev/shm
重点看根目录 / 的 Avail 列,确保至少有 2 GB 剩余空间。
2.5 确认网络和下载工具
# 确认 wget 是否可用(用于下载源码)wget --version | head -1# 如果没有 wget,也可以用 curlcurl --version | head -1
wget --version 期待输出:
GNUWget 1.21.2builtonlinux-gnu.
3. 适配系统与最低配置要求
3.1 支持的发行版
| | | |
|---|
| 18.04 / 20.04 / 22.04 / 24.04 | | |
| | | |
| | | |
| | | |
| | | |
| | | |
CentOS 7 特别说明:CentOS 7 的系统自带 gcc 版本是 4.8.x,编译 Python 3.11+ 时可能遇到编译警告,但不影响功能。如果你需要编译 Python 3.12+,建议先通过 SCL 升级 gcc:sudo yum install devtoolset-11 -y && scl enable devtoolset-11 bash。
3.2 最低硬件配置
编译安装对硬件要求比在线安装高不少,因为编译过程需要 CPU 进行大量运算:
4. 检查系统是否已安装 Python
4.1 检查已有的 Python 版本
# 检查 python3 命令及版本python3 --version# 检查 python 命令(可能指向 Python 2 或不存在)python --version 2>&1# 列出系统里所有 python 相关的可执行文件ls /usr/bin/python* 2>/dev/nullls /usr/local/bin/python* 2>/dev/null
期待输出(Ubuntu 22.04):
Python 3.10.12Python 2isnot installed./usr/bin/python3 /usr/bin/python3.10
# 查看 python3 命令的实际路径which python3whereis python3
whereis python3 期待输出:
python3: /usr/bin/python3 /usr/bin/python3.10 /usr/lib/python3 /usr/share/man/man1/python3.1.gz
4.2 确认编译安装目标路径是否已有内容
编译安装默认会把 Python 装到 /usr/local,先确认这个目录下有没有已有的 Python:
# 查看 /usr/local/bin 下有没有 python 相关文件ls /usr/local/bin/python* 2>/dev/null# 如果没有输出,说明这个路径是干净的
如果有输出类似:
/usr/local/bin/python3 /usr/local/bin/python3.11
说明之前编译安装过 Python,要么先卸载旧版,要么新版本安装到不同路径(通过 --prefix 指定),两个版本可以共存,后文会详细说明。
5. 编译前的准备工作:安装依赖
这是编译安装里最容易出问题的环节。Python 在编译时会检测系统里有没有各种库,有的话就编译进去,没有的话对应功能就会缺失(比如没有 libssl-dev 就没有 HTTPS 支持,没有 zlib1g-dev 就没有 gzip 压缩支持)。
依赖安装要在编译之前做,不能事后补,因为 ./configure 阶段就决定了哪些模块会被编译进去。
5.1 Debian / Ubuntu / Linux Mint
# 第一步:更新软件包索引sudo apt update# 第二步:安装编译 Python 所需的全部依赖# 这是一条完整命令,可以一次性复制粘贴执行sudo apt install -y \ build-essential \ # gcc、g++、make 等核心编译工具 libssl-dev \ # SSL/TLS 支持,pip install 和 https 必须 zlib1g-dev \ # zlib 压缩库,zipfile、gzip 等模块依赖 libbz2-dev \ # bzip2 压缩库,bz2 模块依赖 libreadline-dev \ # readline 库,让交互式解释器支持方向键、历史命令 libsqlite3-dev \ # SQLite 数据库,sqlite3 模块依赖 libffi-dev \ # Foreign Function Interface,ctypes 模块依赖 liblzma-dev \ # lzma 压缩库,lzma 和 xz 模块依赖 libgdbm-dev \ # GNU 数据库,dbm 模块依赖 libgdbm-compat-dev \ # gdbm 兼容层(Ubuntu 20.04+ 需要) libncurses5-dev \ # ncurses 终端库,curses 模块依赖 libncursesw5-dev \ # 宽字符版 ncurses,支持中文等多字节字符 tk-dev \ # Tkinter GUI 框架依赖(不需要 GUI 可以不装) uuid-dev \ # UUID 生成,uuid 模块依赖 wget \ # 下载源码包工具 curl \ # 备用下载工具 git # 版本控制工具(可选)
期待输出(节选):
Reading package lists... DoneBuilding dependency tree... DoneReading state information... DoneThe following additional packages will be installed: binutils binutils-common binutils-x86-64-linux-gnu cpp cpp-11 gcc gcc-11 gcc-11-base g++ g++-11 libc-dev-bin libc6-dev ...The following NEW packages will be installed: build-essential gcc g++ libssl-dev zlib1g-dev libbz2-dev ...0 upgraded, 42 newly installed, 0to remove and3not upgraded.Need toget68.3 MB of archives.After this operation, 287 MB of additional disk space will be used....Setting up build-essential (12.9ubuntu3) ...
最后一行没有 error 就说明依赖安装完成。
5.2 CentOS 7 / RHEL 7(yum)
# 安装 EPEL 扩展仓库(提供部分额外依赖)sudo yum install epel-release -y# 安装编译依赖sudo yum install -y \ gcc \ # C 编译器,核心工具 gcc-c++ \ # C++ 编译器 make \ # 构建工具 openssl-devel \ # SSL/TLS 开发库 zlib-devel \ # zlib 压缩库开发文件 bzip2-devel \ # bzip2 压缩库开发文件 readline-devel \ # readline 库开发文件 sqlite-devel \ # SQLite 开发库 libffi-devel \ # libffi 开发库 xz-devel \ # xz/lzma 压缩库开发文件 gdbm-devel \ # GNU 数据库开发文件 ncurses-devel \ # ncurses 终端库开发文件 tk-devel \ # Tkinter 开发文件(可选) uuid-devel \ # UUID 开发库 wget \ # 下载工具 tar # 解压工具(通常已安装)
期待输出(节选):
Loadedplugins: fastestmirrorLoadingmirrorspeedsfromcachedhostfileResolvingDependencies...Installed:gcc.x86_64 0:4.8.5-44.el7gcc-c++.x86_64 0:4.8.5-44.el7openssl-devel.x86_64 0:1.0.2k-26.el7zlib-devel.x86_64 0:1.2.7-21.el7 ...Complete!
5.3 CentOS 8+ / Fedora / RHEL 8+(dnf)
# 安装编译依赖(CentOS Stream 9 / Fedora 语法)sudo dnf install -y \ gcc \ # C 编译器 gcc-c++ \ # C++ 编译器 make \ # 构建工具 openssl-devel \ # SSL/TLS 开发库 zlib-devel \ # zlib 压缩库 bzip2-devel \ # bzip2 开发文件 readline-devel \ # readline 开发库 sqlite-devel \ # SQLite 开发库 libffi-devel \ # libffi 开发库 xz-devel \ # xz/lzma 开发文件 gdbm-devel \ # gdbm 开发库 ncurses-devel \ # ncurses 开发库 tk-devel \ # Tkinter 开发文件(可选) uuid-devel \ # UUID 开发库 wget \ # 下载工具 tar # 解压工具# CentOS Stream 需要额外启用 CRB(CodeReady Builder)仓库# 部分依赖在这个仓库里sudo dnf config-manager --set-enabled crb 2>/dev/null || \sudo dnf config-manager --set-enabled powertools 2>/dev/null
期待输出(节选):
Dependenciesresolved....Installed:gcc-13.2.1-6.el9.x86_64openssl-devel-3.0.7-27.el9.x86_64zlib-devel-1.2.11-40.el9.x86_64 ...Complete!
6. 下载 Python 源码包
6.1 确认要安装的版本
先去官网确认最新稳定版:https://www.python.org/downloads/source/
本文以 Python 3.12.3 为例(实际操作时请把版本号替换为你需要的版本)。
6.2 下载源码包
# 切换到 /usr/local/src 目录,这是存放第三方源码的惯例路径# 当然也可以放到 ~/Downloads 或其他你喜欢的路径cd /usr/local/src# 用 wget 下载 Python 源码压缩包(XZ 格式,体积更小)# -O 参数指定保存的文件名sudo wget -O Python-3.12.3.tar.xz \ https://www.python.org/ftp/python/3.12.3/Python-3.12.3.tar.xz
期待输出:
--2024-04-0110:23:14-- https://www.python.org/ftp/python/3.12.3/Python-3.12.3.tar.xzResolving www.python.org (www.python.org)... 199.232.144.62, 199.232.140.62Connecting to www.python.org|199.232.144.62|:443... connected.HTTP request sent, awaiting response... 200 OKLength:24940500 (24M) [application/octet-stream]Saving to:'Python-3.12.3.tar.xz'Python-3.12.3.tar.xz 100%[====================>] 23.78M 3.45MB/s in 7.0s2024-04-0110:23:21 (3.45 MB/s) - 'Python-3.12.3.tar.xz' saved [24940500/24940500]
下载完成后,最后一行会显示文件已保存,并给出文件大小(约 24 MB)。
国内下载慢? 官方 FTP 在国内访问可能较慢,可以用以下两个镜像源代替:
华为云镜像:https://mirrors.huaweicloud.com/python/3.12.3/Python-3.12.3.tar.xz
淘宝镜像(通过搜索):https://registry.npmmirror.com/binary.html?path=python/3.12.3/
6.3 验证下载完整性(强烈推荐)
从网络下载的文件可能因为传输中断或被篡改而损坏,用官方提供的 SHA256 校验值验证一下。
# 计算下载文件的 SHA256 哈希值sha256sum Python-3.12.3.tar.xz
期待输出:
a73ac2a94f67a257cbc363427a4f87f2c71a66f2a0a464f5c40f8e9e5f15bab6Python-3.12.3.tar.xz
去官网 https://www.python.org/downloads/release/python-3123/ 找到对应版本的 SHA256 值,比对是否一致。一致则说明文件完整无误,不一致则需要重新下载。
7. 解压与预配置(configure)
7.1 解压源码包
# 解压 xz 格式的 tar 包# -x:解压;-v:显示解压过程;-f:指定文件;-J:处理 xz 格式sudo tar -xvJf Python-3.12.3.tar.xz
期待输出(节选):
Python-3.12.3/Python-3.12.3/Doc/Python-3.12.3/Grammar/Python-3.12.3/Include/Python-3.12.3/Lib/Python-3.12.3/Makefile.pre.inPython-3.12.3/Misc/Python-3.12.3/Modules/Python-3.12.3/Objects/Python-3.12.3/Parser/Python-3.12.3/Programs/Python-3.12.3/Python/...Python-3.12.3/setup.py
解压完成后,当前目录下会多出一个 Python-3.12.3 文件夹。
# 进入解压后的源码目录cd Python-3.12.3# 查看目录结构,了解内容组成ls
期待输出:
configureDocGrammarLICENSEMakefile.pre.inMiscObjectsParserconfigure.acGrammarIncludeLibMakefile.pre.inModulesPCPrograms
configure 就是我们下一步要执行的预配置脚本。
7.2 执行 configure 预配置
configure 脚本的作用是检测当前系统环境,确定哪些功能可以编译,生成最终的 Makefile。
# 标准配置命令,安装到 /usr/local(默认路径,不和系统 Python 冲突)# --prefix:指定安装路径# --enable-optimizations:开启 PGO 性能优化,让 Python 运行速度提升 10-20%# --with-lto:开启链接时优化,进一步提升运行效率# --enable-shared:编译为共享库(某些 IDE 和工具需要,比如 PyCharm)# --with-system-expat:使用系统的 expat 库(XML 解析)# --with-system-ffi:使用系统的 libffi(ctypes 依赖)sudo ./configure \ --prefix=/usr/local \ --enable-optimizations \ --with-lto \ --enable-shared \ --with-system-expat \ --with-system-ffi
关于 --enable-optimizations:这个选项会让编译过程额外进行「性能分析引导优化(PGO)」——先跑一遍测试,再根据测试结果重新编译,因此编译时间会翻 2-3 倍。如果你的机器性能较差,或者只是临时测试用,可以去掉这个选项加快编译速度。
关于安装路径:如果你不想影响 /usr/local,可以把 --prefix 改成自定义路径,例如 --prefix=/opt/python3.12,这样完全独立,更容易管理多版本。
configure 期待输出(节选,会滚屏很长):
checking build system type... x86_64-linux-gnuchecking host system type... x86_64-linux-gnuchecking for --enable-universalsdk... nochecking for --with-universal-archs... no...checking for openssl/ssl.h in /usr... yeschecking whether compiling and linking against OpenSSL works... yes...checking for readline/readline.h... yeschecking for readline/history.h... yes...If you want a release build with all stable optimizations active (PGO, etc),please run ./configure --enable-optimizationscreating Makefile
最关键的是最后几行,出现 creating Makefile 说明 configure 成功,Makefile 已经生成。
配置失败的信号:如果你看到类似 error: could not build the ssl module! 或 WARNING: ...module xxx is not available 的提示,说明某个依赖没装好,需要回头补装对应的 -dev / -devel 包,然后重新运行 configure。
7.3 查看哪些模块将被编译
configure 完成后,可以查看模块编译状态:
# 查看 configure 的输出摘要,确认关键模块状态grep -E "enabled|disabled|yes|no" config.log | tail -50
更直接的方法是查看 Makefile 的配置:
# 查看哪些模块会被跳过(skip = 缺少依赖导致不被编译)grep "skip" Makefile | head -20
如果 _ssl(SSL/HTTPS 支持)和 _hashlib 出现在 skip 列表里,是大问题,pip install 会全部失败,必须修复。其他模块按需决定是否需要。
8. 编译与安装(make & make install)
8.1 编译(make)
# 开始编译# -j$(nproc) 表示使用当前 CPU 全部核心数并行编译,大幅缩短编译时间# nproc 命令会输出 CPU 核心数,$(nproc) 是命令替换,自动获取sudo make -j$(nproc)
先查一下你有几个核:
# 确认 CPU 核心数(方便估算编译时间)nproc
期待输出:
4
这说明你有 4 个核,make -j4 会并行编译,比 make -j1 快 3 倍左右。
编译期间的期待输出(节选,会持续滚屏 3-20 分钟):
gcc -pthread -c -Wno-unused-result -Wsign-compare -DNDEBUG -g -O3 \ -Wall -Wstrict-prototypes -std=c11 -Werror=implicit-function-declaration \ -fexceptions -fprofile-generate -fvisibility=hidden ......building '_ssl' extension...building 'zlib' extension...building 'bz2' extension...
看到 building 'xxx' extension 字样说明各模块正在被编译,这是正常现象。
编译完成的标志:
Generating Profile: 100% (24/24)Freezing runpy...Freezing importlib...Freezing zipimport......
没有出现 Error 就说明编译成功。
编译中断了怎么办? 如果编译过程中出现错误中断,修复问题后可以直接重新执行 sudo make -j$(nproc),已经编译好的部分会被复用,不需要从头开始。
8.2 安装(make altinstall)
# 安装 Python# 这里用 altinstall 而不是 install,非常重要!# install 会覆盖 /usr/local/bin/python3 软链接,可能影响系统工具# altinstall 只创建带完整版本号的可执行文件(如 python3.12),不创建或修改 python3 软链接sudo make altinstall
期待输出:
/usr/bin/install -c -m 644 ./Tools/scripts/pydoc3 /usr/local/lib/python3.12/......Collecting pip Downloading pip-24.0-py3-none-any.whl (2.1 MB) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 2.1/2.1 MB 3.4 MB/s eta 0:00:00Successfully installed pip-24.0 setuptools-65.5.0
Successfully installed pip-24.0 出现说明安装完成,pip 也顺手一起装好了。
make altinstall vs make install 的区别:
make install:创建 python3、python3.12、pip3、pip3.12 等所有软链接,会覆盖同名的系统文件,风险高。make altinstall:只创建 python3.12、pip3.12,不碰 python3、pip3 软链接,更安全。默认用 altinstall。
8.3 更新动态链接库缓存
如果你在 configure 时加了 --enable-shared,需要更新动态链接库缓存,否则运行时可能找不到 libpython3.12.so:
# 更新 /etc/ld.so.cache,让系统能找到新编译的共享库sudo ldconfig# 验证共享库是否注册成功ldconfig -p | grep libpython3.12
期待输出:
libpython3.12.so.1.0 (libc6,x86-64) => /usr/local/lib/libpython3.12.so.1.0
9. 安装完成后的验证与配置
9.1 验证 Python 版本
# 使用带完整版本号的命令(altinstall 方式安装的结果)python3.12 --version
期待输出:
Python 3.12.3
9.2 验证 Python 可以正常运行
# 进入交互式解释器,测试基本功能python3.12
期待输出:
Python 3.12.3 (main, Apr 012024, 10:45:22) [GCC 11.4.0] on linuxType "help", "copyright", "credits"or"license"for more information.>>>
在解释器里测试几个基本操作:
>>> import sys>>> print(sys.version)3.12.3 (main, Apr 012024, 10:45:22) [GCC 11.4.0]>>> import ssl>>> print(ssl.OPENSSL_VERSION)OpenSSL 3.0.215 Mar 2022>>> import sqlite3>>> print(sqlite3.sqlite_version)3.37.2>>> print("编译安装成功!")编译安装成功!>>> exit()
import ssl 成功说明 HTTPS 支持正常;import sqlite3 成功说明数据库模块正常。这两个是最重要的验证点。
9.3 验证安装路径
# 确认 python3.12 可执行文件的位置which python3.12
期待输出:
/usr/local/bin/python3.12
# 查看完整安装文件ls /usr/local/bin/python*ls /usr/local/lib/python3.12/
期待输出:
/usr/local/bin/python3.12 /usr/local/bin/python3.12-config/usr/local/bin/pip3.12 /usr/local/bin/pydoc3.12asyncio collections concurrent ctypes curses dbm ...
9.4 验证所有关键模块
# 用这个命令一次性检查所有编译结果# 如果某个模块出现在"No module named"里,说明编译时依赖缺失python3.12 -c "import sys, os, ssl, hashlib, sqlite3, zlib, bz2, lzma, readline, ctypes, uuidprint('核心模块验证通过:')print(f' ssl: {ssl.OPENSSL_VERSION}')print(f' sqlite3: {sqlite3.sqlite_version}')print(f' zlib: {zlib.ZLIB_VERSION}')print(f' python: {sys.version}')print(' hashlib, bz2, lzma, readline, ctypes, uuid —— 全部 OK')"
期待输出:
核心模块验证通过:ssl: OpenSSL 3.0.2 15 Mar 2022sqlite3: 3.37.2zlib: 1.2.11python: 3.12.3 (main, Apr 01 2024, 10:45:22)[GCC 11.4.0]hashlib, bz2, lzma, readline, ctypes, uuid —— 全部 OK
9.5 配置 PATH(让 python3.12 更方便调用)
编译安装完成后,python3.12 和 pip3.12 已经可以直接调用了(因为 /usr/local/bin 通常在 PATH 里)。如果调用时提示找不到命令,就把路径加进去:
# 确认 /usr/local/bin 是否在 PATH 里echo$PATH
期待输出包含:
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
如果 /usr/local/bin 不在 PATH 里:
# 临时加入(当前 Shell 有效)export PATH=/usr/local/bin:$PATH# 永久生效:写入 ~/.bashrcecho'export PATH=/usr/local/bin:$PATH' >> ~/.bashrcsource ~/.bashrc
10. pip 配置与国内换源
编译安装完成后,pip 已经自带了(在 make altinstall 阶段安装),但版本可能不是最新的,而且默认源在国内访问慢,需要配置。
10.1 验证 pip 版本
# 查看 pip3.12 的版本和它对应的 Python 解释器pip3.12 --version
期待输出:
pip 24.0from /usr/local/lib/python3.12/site-packages/pip (python 3.12)
10.2 升级 pip 到最新版
# 用 python3.12 -m pip 方式升级,确保 pip 和解释器配套python3.12 -m pip install --upgrade pip
期待输出:
Requirement already satisfied: pip in /usr/local/lib/python3.12/site-packages (24.0)# 或者Successfully installed pip-24.1
10.3 配置国内镜像源(永久生效)
# 为 python3.12 对应的 pip 配置阿里云镜像pip3.12 config set global.index-url https://mirrors.aliyun.com/pypi/simple/pip3.12 config set global.trusted-host mirrors.aliyun.com# 查看配置是否生效pip3.12 config list
期待输出:
Writing to /root/.config/pip/pip.confglobal.index-url='https://mirrors.aliyun.com/pypi/simple/'global.trusted-host='mirrors.aliyun.com'
# 测试:安装一个小包验证 pip 是否正常工作pip3.12 install requests
期待输出:
Collecting requests Downloading https://mirrors.aliyun.com/pypi/packages/.../requests-2.31.0-py3-none-any.whl...Successfully installed certifi-2024.2.2 charset-normalizer-3.3.2 idna-3.6 requests-2.31.0 urllib3-2.2.0
11. 虚拟环境的创建与使用
编译安装的 Python 同样完整支持 venv,强烈建议每个项目使用独立虚拟环境。
11.1 创建虚拟环境
# 切换到你的项目目录mkdir ~/myproject && cd ~/myproject# 用 python3.12 创建虚拟环境(名为 venv)python3.12 -m venv venv
执行后验证:
ls venv/bin/
期待输出:
activateactivate.cshactivate.fishActivate.ps1pippip3pip3.12pythonpython3python3.12
11.2 激活和使用
# 激活虚拟环境source venv/bin/activate# 激活后提示符变化# (venv) ubuntu@hostname:~/myproject$# 确认虚拟环境中的 Python 指向which pythonpython --version
期待输出:
/root/myproject/venv/bin/pythonPython 3.12.3
11.3 在虚拟环境中安装包
# 激活后直接用 pip(不需要 sudo 也不需要加版本号)pip install flask sqlalchemy redis# 查看已安装的包pip list
11.4 退出虚拟环境
deactivate
12. 多版本共存管理
编译安装最大的优势之一就是可以让多个 Python 版本在同一台机器上共存,互不干扰。
12.1 查看当前所有 Python 版本
# 列出系统和 /usr/local/bin 下所有 python 可执行文件ls /usr/bin/python* /usr/local/bin/python* 2>/dev/null
期待输出(同时有系统自带和编译安装的):
/usr/bin/python3 /usr/bin/python3.10/usr/local/bin/python3.11 /usr/local/bin/python3.12
12.2 通过 update-alternatives 管理默认版本
# 把多个版本注册到 update-alternatives 系统# 参数:--install <目标链接> <名称> <实际路径> <优先级># 优先级数字越大,自动模式下会被优先选择sudo update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.10 1sudo update-alternatives --install /usr/bin/python3 python3 /usr/local/bin/python3.11 2sudo update-alternatives --install /usr/bin/python3 python3 /usr/local/bin/python3.12 3# 交互式切换默认版本sudo update-alternatives --config python3
期待交互界面:
There are 3 choices for the alternative python3 (providing /usr/bin/python3). Selection Path Priority Status------------------------------------------------------------* 0 /usr/local/bin/python3.123 auto mode1 /usr/bin/python3.101 manual mode2 /usr/local/bin/python3.112 manual mode3 /usr/local/bin/python3.123 manual modePress <enter> to keep the current choice[*], ortype selection number:
输入你想要的序号,回车确认。
12.3 各版本独立使用(不改默认版本)
不想改 python3 默认指向?直接用带完整版本号的命令即可:
# 明确指定用哪个版本运行脚本python3.10 script.pypython3.11 script.pypython3.12 script.py# 各版本的 pip 也独立存在pip3.10 install 包名pip3.11 install 包名pip3.12 install 包名
13. 卸载编译安装的 Python
编译安装没有自动卸载工具,需要手动删除文件。但只要安装路径是单独的(比如 /usr/local 或 /opt/python3.12),手动删除很干净。
13.1 卸载通过 `make altinstall` 安装到 `/usr/local` 的 Python 3.12
# 删除可执行文件sudo rm -f /usr/local/bin/python3.12sudo rm -f /usr/local/bin/python3.12-configsudo rm -f /usr/local/bin/pip3.12sudo rm -f /usr/local/bin/pydoc3.12sudo rm -f /usr/local/bin/idle3.12sudo rm -f /usr/local/bin/2to3-3.12# 删除标准库目录sudo rm -rf /usr/local/lib/python3.12/# 删除共享库文件sudo rm -f /usr/local/lib/libpython3.12.sosudo rm -f /usr/local/lib/libpython3.12.so.1.0# 删除头文件sudo rm -rf /usr/local/include/python3.12/# 删除 pkg-config 配置文件sudo rm -f /usr/local/lib/pkgconfig/python-3.12.pcsudo rm -f /usr/local/lib/pkgconfig/python-3.12-embed.pc# 更新动态链接库缓存sudo ldconfig# 如果之前在 update-alternatives 中注册过,也要移除sudo update-alternatives --remove python3 /usr/local/bin/python3.12
验证卸载成功:
python3.12 --version
期待输出:
bash: python3.12: command not found
13.2 如果安装到了自定义 `--prefix` 路径(如 `/opt/python3.12`)
这种情况最简单,直接删整个目录:
# 删除整个安装目录sudo rm -rf /opt/python3.12/# 更新动态链接库缓存sudo ldconfig
13.3 清理源码目录(可选)
# 如果你不再需要源码和编译产物,可以清理sudo rm -rf /usr/local/src/Python-3.12.3/sudo rm -f /usr/local/src/Python-3.12.3.tar.xz
14. 常见问题 Q&A
Q1:configure 提示 "WARNING: Python build finished successfully! The necessary bits to build these optional modules were not found"
含义:这不是错误,是警告。有几个可选模块因为缺少依赖没有被编译进去。
常见缺失模块和解决方法:
# 缺少 _ssl(最严重,影响 pip)# Debian/Ubuntu:sudo apt install libssl-dev -y# CentOS/RHEL:sudo yum install openssl-devel -y# 缺少 _tkinter(Tkinter GUI,不需要 GUI 的话可以忽略)# Debian/Ubuntu:sudo apt install tk-dev -y# 缺少 readline(影响交互式解释器的方向键等功能)# Debian/Ubuntu:sudo apt install libreadline-dev -y# 缺少 _lzma / _bz2sudo apt install liblzma-dev libbz2-dev -y
解决方法:装好对应依赖后,回到源码目录重新执行 configure 和 make。
Q2:make 过程中出现 "Error 1" 或 "make[1]: *** [xxx] Error 1"
原因:编译过程中某个文件编译失败,通常是依赖问题或 gcc 版本问题。
解决思路:
# 1. 查看具体错误信息(Error 1 通常出现在大量输出之后,往上翻)sudo make -j$(nproc) 2>&1 | tee /tmp/build.log# 如果输出太多,提取关键错误grep -E "Error|error:|fatal:" /tmp/build.log | head -30
常见原因:
error: openssl/ssl.h: No such file or directory → 缺少 libssl-dev,装完重新 configureimplicit declaration of function → gcc 版本过老(CentOS 7 的 gcc 4.8),升级 gcc 或用较旧的 Python 版本
Q3:运行 python3.12 时提示 "error while loading shared libraries: libpython3.12.so.1.0"
原因:编译时开启了 --enable-shared,但系统没有找到共享库文件。
解决方法:
# 方法一:更新动态链接库缓存(最常见的解决方法)sudo ldconfig# 方法二:手动把共享库路径加到配置里echo'/usr/local/lib' | sudo tee /etc/ld.so.conf.d/python3.12.confsudo ldconfig# 验证ldconfig -p | grep libpython3.12
Q4:make altinstall 完成后,pip3.12 提示 command not found
原因:pip 可能没有随 Python 一起安装(某些配置下会出现)。
解决方法:
# 手动安装 pippython3.12 -m ensurepip --upgrade# 如果 ensurepip 也失败,用 get-pip.pywget https://bootstrap.pypa.io/get-pip.py -O /tmp/get-pip.pypython3.12 /tmp/get-pip.py
Q5:configure 时 --enable-optimizations 让编译卡很久,甚至超时
原因:--enable-optimizations 会进行 PGO(Profile-Guided Optimization),需要运行完整的测试套件收集性能数据,单核机器可能需要 30 分钟以上。
解决方法:
# 方案一:去掉 --enable-optimizations,正常编译sudo ./configure --prefix=/usr/local --with-lto --enable-shared# 方案二:保留优化但限制 make 并行度,防止内存不足导致超时sudo make -j2 # 限制为 2 个并行任务
Q6:make 时提示 "virtual memory exhausted: Cannot allocate memory"
原因:编译过程内存不足,常见于 512 MB 或 1 GB 内存的小型服务器。
解决方法:
# 方法一:减少并行编译任务数(减少内存占用)sudo make -j1 # 单线程编译,最省内存,但最慢# 方法二:创建临时 swap 空间(增加虚拟内存)# 创建 2 GB 的 swap 文件sudo fallocate -l 2G /swapfilesudo chmod 600 /swapfilesudo mkswap /swapfilesudo swapon /swapfile# 编译完成后可以关闭 swap(可选)sudo swapoff /swapfilesudo rm /swapfile
Q7:安装完成后 import ssl 报错 "No module named '_ssl'"
原因:configure 阶段没有找到 OpenSSL 开发库,_ssl 模块没有被编译进去。
解决方法:
# 1. 先安装 OpenSSL 开发库# Debian/Ubuntu:sudo apt install libssl-dev -y# CentOS/RHEL:sudo yum install openssl-devel -y# 2. 回到源码目录,清理之前的编译结果cd /usr/local/src/Python-3.12.3sudo make clean# 3. 重新执行 configuresudo ./configure --prefix=/usr/local --enable-optimizations --enable-shared# 4. 重新编译和安装sudo make -j$(nproc)sudo make altinstall
Q8:如何查看当前编译安装的 Python 都包含哪些模块?
# 查看所有已编译的内置模块和扩展模块python3.12 -c "import sys; print('\n'.join(sorted(sys.stdlib_module_names)))"# 查看哪些扩展模块实际被加载python3.12 -c "import sys; print([m for m in sys.modules if not m.startswith('_')])"# 专门检查某个模块是否可用python3.12 -c "import ssl; print('ssl OK')"python3.12 -c "import tkinter; print('tkinter OK')"
Q9:编译安装的 Python 和系统 Python 会互相影响吗?
不会。两者完全独立:
- 系统 Python(
/usr/bin/python3)有自己的标准库(/usr/lib/python3.x/)和 site-packages。 - 编译安装的 Python(
/usr/local/bin/python3.12)有自己的标准库(/usr/local/lib/python3.12/)和 site-packages。
用 pip3.12 install 安装的包只会出现在 /usr/local/lib/python3.12/site-packages/,不会影响系统 Python 的包。反过来也一样。
Q10:想在编译安装的 Python 上运行 `python` 命令(不带版本号),怎么配置?
# 方法一:创建软链接(简单粗暴,但要小心别覆盖系统的 python3)sudo ln -sf /usr/local/bin/python3.12 /usr/local/bin/python3sudo ln -sf /usr/local/bin/python3.12 /usr/local/bin/pythonsudo ln -sf /usr/local/bin/pip3.12 /usr/local/bin/pip3sudo ln -sf /usr/local/bin/pip3.12 /usr/local/bin/pip# 方法二:用 update-alternatives 管理(推荐,可以方便切换)sudo update-alternatives --install /usr/bin/python3 python3 /usr/local/bin/python3.12 10sudo update-alternatives --config python3
15. 小总结
编译安装 Python 的整体流程,用一张清单来回顾:
第一步:环境确认。 用 cat /etc/os-release 确认发行版,df -h 确保有 2 GB 以上磁盘空间,uname -m 确认架构,whoami 确认权限。
第二步:安装编译依赖。 根据发行版选对应的包管理器安装依赖,核心依赖是 gcc、make、libssl-dev(或 openssl-devel)、zlib-dev、libffi-dev。依赖必须在 configure 之前装好,事后补装需要重新 configure。
第三步:下载并验证源码。 从官网或国内镜像下载 .tar.xz,用 sha256sum 验证完整性。
第四步:configure 预配置。 关键选项:--prefix 指定安装路径(建议 /usr/local),--enable-optimizations 开启性能优化(慢但值得),--enable-shared 支持共享库,--with-lto 开启链接时优化。
第五步:编译。sudo make -j$(nproc),用全部 CPU 核加速,耐心等待。
第六步:安装。sudo make altinstall,不是 make install,避免覆盖系统 Python 软链接。然后 sudo ldconfig 更新动态库缓存。
第七步:验证。python3.12 --version + python3.12 -c "import ssl, sqlite3" 验证核心模块,pip3.12 --version 验证 pip。
第八步:配置 pip 国内源,创建虚拟环境。 项目开发请一定用虚拟环境,别往系统或全局 Python 里乱装包。
最新最全的的内容在永久域名 itinstall.dev ,可以收藏备用。