问题背景

最近在 CentOS 7 上编译安装 Python 3.9,按照官方推荐的方式执行:

./configure --prefix=/usr/local/python3 --enable-optimizations
make -j$(nproc)
sudo make install

结果编译到一半,突然报错:

Could not import runpy module
Traceback (most recent call last):
  File "/opt/Python-3.10.0/Lib/runpy.py", line 15, in <module>
    import importlib.util
  File "/opt/Python-3.10.0/Lib/importlib/util.py", line 14, in <module>
    from contextlib import contextmanager
  File "/opt/Python-3.10.0/Lib/contextlib.py", line 4, in <module>
    import _collections_abc
SystemError: <built-in function compile> returned NULL without setting an exception
generate-posix-vars failed
make: *** [pybuilddir.txt] Error 1

折腾了半天,最终发现 --enable-optimizations 是罪魁祸首!删掉这个参数后,编译顺利通过。


为什么 --enable-optimizations 会导致编译失败?

--enable-optimizations 是 Python 官方推荐的编译选项,用于启用 PGO(Profile-Guided Optimization)优化,让 Python 运行更快。但它在某些旧系统(如 CentOS 7)上可能会引发问题,原因包括:

  1. GCC 版本过低
    CentOS 7 默认的 GCC 4.8.5 对 PGO 支持不完善,而 Python 3.9+ 的优化编译需要更高版本 GCC(建议 ≥ 8)。
  2. 依赖库不兼容
    PGO 优化会额外编译测试用例,如果系统缺少某些依赖(如 zlib-devellibffi-devel),可能导致 runpy 等核心模块编译失败。
  3. 内存不足
    PGO 优化会占用更多内存,如果服务器内存较小(< 2GB),可能导致编译崩溃。

正确编译 Python 3.9 的步骤

1. 安装编译依赖

sudo yum install -y gcc make openssl-devel bzip2-devel libffi-devel zlib-devel \
ncurses-devel sqlite-devel readline-devel tk-devel gdbm-devel xz-devel

2. 下载 Python 3.9 源码

wget https://www.python.org/ftp/python/3.9.16/Python-3.9.16.tgz
tar xzf Python-3.9.16.tgz
cd Python-3.9.16

3. 配置编译选项(关键!不要加 --enable-optimizations

./configure --prefix=/usr/local/python3  # 不加 --enable-optimizations

4. 编译并安装

make -j$(nproc)        # 并行编译加速
sudo make install      # 安装到 /usr/local/python3

5. 验证安装

/usr/local/python3/bin/python3 --version
# 应输出: Python 3.9.16

如果仍想启用 PGO 优化怎么办?

如果确实需要优化性能,可以尝试以下方法:

方案 1:升级 GCC

sudo yum install centos-release-scl
sudo yum install devtoolset-9
scl enable devtoolset-9 bash
gcc --version  # 确认版本 ≥ 9

然后重新编译:

./configure --prefix=/usr/local/python3 --enable-optimizations
make -j$(nproc)

方案 2:改用 --enable-shared

如果 PGO 仍然失败,可以改用动态链接库优化:

./configure --prefix=/usr/local/python3 --enable-shared
make -j$(nproc)

总结

编译选项适用场景风险
--prefix=/usr/local/python3默认编译,兼容性最好✅ 推荐
--enable-shared支持动态链接库⚠️ 需设置 LD_LIBRARY_PATH
--enable-optimizations高性能优化(PGO)❌ 旧系统易失败

最终建议

  • 生产环境 → 直接去掉 --enable-optimizations,优先保证稳定性。
  • 开发环境 → 可尝试升级 GCC 后再启用 PGO。

希望这篇踩坑记录能帮你少走弯路!如果有其他问题,欢迎留言讨论。 🚀

标签: none

评论已关闭