使用Python Stable ABI的包构建标识与兼容性问题咨询
Python C扩展适配Stable ABI的配置问题解答
关于wheel构建参数的问题
- 你对
--py-limited-api=cp34参数的理解基本正确:这个参数就是声明当前wheel使用兼容Python 3.4及以上版本的稳定ABI,生成的cp34-abi3标签会告诉pip等包管理器,所有CPython 3.4以上的版本都可以直接安装这个wheel,不需要重新编译。 - 不要把参数改成
cp3,该参数的合法取值必须是cp加具体的小版本号,不存在cp3这类通用写法,错误的取值会导致包管理器无法识别兼容性。 - 仅配置这个参数是不够的,你当前构建出的共享库命名不符合稳定ABI的规范,会导致高版本Python无法识别导入。
关于共享库命名的问题
- 编译时添加
-DPy_LIMITED_API=0x03040000宏的操作是正确的,这个宏会限制编译器只暴露稳定ABI的符号,确保二进制兼容性。 - 你当前生成的
blooper.cpython-38-x86_64-linux-gnu.so属于版本绑定的扩展命名格式,Python只会在3.8版本下尝试导入该模块,更高版本会直接找不到模块,和你是否用了稳定ABI无关。 - 要解决这个问题,如果你用setuptools的
Extension定义扩展,只需要给Extension新增py_limited_api=True参数,setuptools会自动生成符合PEP 3149规范的稳定ABI命名,也就是blooper.abi3.so,不带具体Python版本号,所有3.4以上的CPython都可以正常识别导入。 - 如果你是手动执行编译命令,直接把生成的so文件重命名为
xxx.abi3.so格式即可。
完整正确的配置流程
只要按以下步骤配置,最终得到的wheel就可以无需重新编译,适配所有CPython 3.4及以上3.x版本:
- 所有C/C++扩展定义时添加
py_limited_api=True参数 - 编译扩展时添加
-DPy_LIMITED_API=0x03040000宏(如果需要兼容更低的3.x版本,修改对应宏值即可,比如3.2对应0x03020000) - 构建wheel时执行命令
python setup.py bdist_wheel --py-limited-api=cp34即可
内容的提问来源于stack exchange,提问作者Jim。
相关产品推荐
相关产品推荐

