什么情况下需要自己编译 CPython

大多数操作系统都提供了编译好的 CPython 版本,一般直接通过包管理器安装就能满足需求,但是某些情况下,就需要自己编译 CPython 来满足特定需求了:

  • 操作系统提供的 Python 版本太低,并且 Python 官网、系统包管理源没有提供预编译的新版本 Python

  • 预编译版本不符合性能、扩展等方面的要求,比如没有开启编译器优化、OpenSSL/SQLite 版本不满足要求等

  • 参与 CPython 开发或者尝鲜,尝试 Alpha/Beta/RC 等版本的 Python


低版本 Linux 发行版上编译 CPython 时的注意事项

OpenSSL

因为 CentOS 6 官方源中的 OpenSSL 版本过低,不满足 Python 3.7 及之后的要求,所以直接 configure & make 会报错,解决办法:

参考 Python 3.7 on CentOS 6 , 提前编译 OpenSSL, 编译 CPython 时修改 Modules/Setup 文件,并且指定环境变量 LDFLAGS="-Wl,-rpath=/usr/local/openssl11/lib" , 指定参数 -with-openssl=/usr/local/openssl11

SQLite

Jupyter 等软件依赖 SQLite, 所以编译 CPython 时不仅要注意 SQLite 版本,也要开启 --enable-loadable-sqlite-extensions , 参考:How to use enable_load_extension from sqlite3?


影响性能的编译参数

–enable-optimizations

根据 StackOverflow 这个问题:what does –enable-optimizations do while compiling python?

enable-optimizations 会开启 PGOLTO 的编译器优化,PGO会进行两次编译,首次编译后再运行 benchmark 测试,根据测试指导第二次优化编译,

优点是会编译出更有效的 CPython 二进制版本,

缺点是一是对编译器版本有要求,低版本 GCC PGO 编译时会报错,二是编译时间会大大增加,多了 benchmark 和二次编译的时间,所以 make 时可以考虑加上 -j 参数,利用机器多核减少编译时间。

-march

指定CPU架构也可能影响编译后 CPython 的性能,扩展阅读: Compile-time Optimisations on Python 3

-fno-semantic-interposition

参考 Red Hat Enterprise Linux 8.2 brings faster Python 3.8 run speeds

GCC 编译时增加 -fno-semantic-interposition 选项,在 Red Hat / Federa 发行版上,禁用 Semantic interposition ,带来最高 30% 的性能提升。

当然,以上编译参数都和特定发行版、编译器版本相关,不能简单认为适用于所有环境,评估性能的最佳方式还是做 benchmark 。