编译安装是三种方式里步骤最多的,但也是最灵活的——想装哪个版本装哪个,官方仓库里没有的也能装。跟着做,每一步都有注释和期待回显,出了问题翻 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=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 22.04.3 LTS"
VERSION_ID="22.04"
# 备用命令,适合 Debian 系发行版
lsb_release -a

期待输出:

No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 22.04.3 LTS
Release:        22.04
Codename:       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     0  1.9G   0% /dev/shm

重点看根目录 /Avail 列,确保至少有 2 GB 剩余空间。

2.5 确认网络和下载工具

# 确认 wget 是否可用(用于下载源码)
wget --version | head -1

# 如果没有 wget,也可以用 curl
curl --version | head -1

wget --version 期待输出:

GNU Wget 1.21.2 built on linux-gnu.

3. 适配系统与最低配置要求

3.1 支持的发行版

发行版 版本 包管理器 编译支持情况
Ubuntu 18.04 / 20.04 / 22.04 / 24.04 apt 完整支持,推荐
Debian 10 / 11 / 12 apt 完整支持
Linux Mint 19 / 20 / 21 apt 完整支持
CentOS 7 yum 支持,gcc 版本较旧(4.8),需注意
CentOS 8 / 9 Stream dnf 完整支持
RHEL 7 / 8 / 9 yum / dnf 完整支持

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 进行大量运算:

配置项 最低要求 推荐
CPU 单核 1 GHz 双核及以上,编译更快
内存(RAM) 1 GB 2 GB 及以上
磁盘空间 1.5 GB(源码 + 编译 + 安装) 3 GB(留有余量)
网络 能下载源码包(约 25 MB) 宽带,下载源码更快

4. 检查系统是否已安装 Python

4.1 检查已有的 Python 版本

# 检查 python3 命令及版本
python3 --version

# 检查 python 命令(可能指向 Python 2 或不存在)
python --version 2>&1

# 列出系统里所有 python 相关的可执行文件
ls /usr/bin/python* 2>/dev/null
ls /usr/local/bin/python* 2>/dev/null

期待输出(Ubuntu 22.04):

Python 3.10.12
Python 2 is not installed.
/usr/bin/python3  /usr/bin/python3.10
# 查看 python3 命令的实际路径
which python3
whereis 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... Done
Building dependency tree... Done
Reading state information... Done
The 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, 0 to remove and 3 not upgraded.
Need to get 68.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                 # 解压工具(通常已安装)

期待输出(节选):

Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
Resolving Dependencies
...
Installed:
  gcc.x86_64 0:4.8.5-44.el7          gcc-c++.x86_64 0:4.8.5-44.el7
  openssl-devel.x86_64 0:1.0.2k-26.el7  zlib-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

期待输出(节选):

Dependencies resolved.
...
Installed:
  gcc-13.2.1-6.el9.x86_64
  openssl-devel-3.0.7-27.el9.x86_64
  zlib-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-01 10:23:14--  https://www.python.org/ftp/python/3.12.3/Python-3.12.3.tar.xz
Resolving www.python.org (www.python.org)... 199.232.144.62, 199.232.140.62
Connecting to www.python.org|199.232.144.62|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 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.0s

2024-04-01 10: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

期待输出:

a73ac2a94f67a257cbc363427a4f87f2c71a66f2a0a464f5c40f8e9e5f15bab6  Python-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.in
Python-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

期待输出:

configure    Doc       Grammar  LICENSE  Makefile.pre.in  Misc     Objects  Parser
configure.ac Grammar   Include  Lib      Makefile.pre.in  Modules  PC       Programs

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-gnu
checking host system type... x86_64-linux-gnu
checking for --enable-universalsdk... no
checking for --with-universal-archs... no
...
checking for openssl/ssl.h in /usr... yes
checking whether compiling and linking against OpenSSL works... yes
...
checking for readline/readline.h... yes
checking for readline/history.h... yes
...
If you want a release build with all stable optimizations active (PGO, etc),
please run ./configure --enable-optimizations

creating 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:00
Successfully installed pip-24.0 setuptools-65.5.0

Successfully installed pip-24.0 出现说明安装完成,pip 也顺手一起装好了。

make altinstall vs make install 的区别

  • make install:创建 python3python3.12pip3pip3.12 等所有软链接,会覆盖同名的系统文件,风险高。
  • make altinstall:只创建 python3.12pip3.12,不碰 python3pip3 软链接,更安全。默认用 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 01 2024, 10:45:22) [GCC 11.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>

在解释器里测试几个基本操作:

>>> import sys
>>> print(sys.version)
3.12.3 (main, Apr 01 2024, 10:45:22) [GCC 11.4.0]

>>> import ssl
>>> print(ssl.OPENSSL_VERSION)
OpenSSL 3.0.2 15 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.12

asyncio  collections  concurrent  ctypes  curses  dbm  ...

9.4 验证所有关键模块

# 用这个命令一次性检查所有编译结果
# 如果某个模块出现在"No module named"里,说明编译时依赖缺失
python3.12 -c "
import sys, os, ssl, hashlib, sqlite3, zlib, bz2, lzma, readline, ctypes, uuid
print('核心模块验证通过:')
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 2022
  sqlite3:  3.37.2
  zlib:     1.2.11
  python:   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.12pip3.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

# 永久生效:写入 ~/.bashrc
echo 'export PATH=/usr/local/bin:$PATH' >> ~/.bashrc
source ~/.bashrc

10. pip 配置与国内换源

编译安装完成后,pip 已经自带了(在 make altinstall 阶段安装),但版本可能不是最新的,而且默认源在国内访问慢,需要配置。

10.1 验证 pip 版本

# 查看 pip3.12 的版本和它对应的 Python 解释器
pip3.12 --version

期待输出:

pip 24.0 from /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.conf

global.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/

期待输出:

activate  activate.csh  activate.fish  Activate.ps1
pip  pip3  pip3.12  python  python3  python3.12

11.2 激活和使用

# 激活虚拟环境
source venv/bin/activate

# 激活后提示符变化
# (venv) ubuntu@hostname:~/myproject$

# 确认虚拟环境中的 Python 指向
which python
python --version

期待输出:

/root/myproject/venv/bin/python
Python 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 1
sudo update-alternatives --install /usr/bin/python3 python3 /usr/local/bin/python3.11 2
sudo 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.12     3         auto mode
  1            /usr/bin/python3.10           1         manual mode
  2            /usr/local/bin/python3.11     2         manual mode
  3            /usr/local/bin/python3.12     3         manual mode

Press <enter> to keep the current choice[*], or type selection number:

输入你想要的序号,回车确认。

12.3 各版本独立使用(不改默认版本)

不想改 python3 默认指向?直接用带完整版本号的命令即可:

# 明确指定用哪个版本运行脚本
python3.10 script.py
python3.11 script.py
python3.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.12
sudo rm -f /usr/local/bin/python3.12-config
sudo rm -f /usr/local/bin/pip3.12
sudo rm -f /usr/local/bin/pydoc3.12
sudo rm -f /usr/local/bin/idle3.12
sudo rm -f /usr/local/bin/2to3-3.12

# 删除标准库目录
sudo rm -rf /usr/local/lib/python3.12/

# 删除共享库文件
sudo rm -f /usr/local/lib/libpython3.12.so
sudo 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.pc
sudo 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 / _bz2
sudo 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,装完重新 configure
  • implicit 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.conf
sudo ldconfig

# 验证
ldconfig -p | grep libpython3.12

Q4:make altinstall 完成后,pip3.12 提示 command not found

原因:pip 可能没有随 Python 一起安装(某些配置下会出现)。

解决方法:

# 手动安装 pip
python3.12 -m ensurepip --upgrade

# 如果 ensurepip 也失败,用 get-pip.py
wget https://bootstrap.pypa.io/get-pip.py -O /tmp/get-pip.py
python3.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 /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile

# 编译完成后可以关闭 swap(可选)
sudo swapoff /swapfile
sudo 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.3
sudo make clean

# 3. 重新执行 configure
sudo ./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/python3
sudo ln -sf /usr/local/bin/python3.12 /usr/local/bin/python
sudo ln -sf /usr/local/bin/pip3.12 /usr/local/bin/pip3
sudo 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 10
sudo update-alternatives --config python3

15. 小总结

编译安装 Python 的整体流程,用一张清单来回顾:

第一步:环境确认。cat /etc/os-release 确认发行版,df -h 确保有 2 GB 以上磁盘空间,uname -m 确认架构,whoami 确认权限。

第二步:安装编译依赖。 根据发行版选对应的包管理器安装依赖,核心依赖是 gccmakelibssl-dev(或 openssl-devel)、zlib-devlibffi-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 里乱装包。

遇到问题:_ssl 报错 → 补装 libssl-dev 重新 configure;内存不足 → 减少并行数或加 swap;共享库找不到 → 执行 ldconfig;版本冲突 → 用 update-alternatives 管理。

编译安装学会了,以后不管仓库里有没有你要的版本,都可以自己搞定。

更多推荐