什么情况下需要自己编译 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
会开启 PGO
和 LTO
的编译器优化,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 。