含共享库的Python Wheel被标记为none-any平台无关包的问题咨询
问题根源
setuptools 判断 Wheel 是否为平台相关包的核心依据是是否包含 C/C++ Extension 模块。仅通过 package_data 包含预编译的 .so 文件,setuptools 会默认将其识别为纯 Python 包,因此生成后缀为 none-any 的平台无关 Wheel,这直接导致 cibuildwheel 跳过 auditwheel 处理。
常规解决方法
不需要采用非常规的强制标记手段,正确的做法是通过一个空的 Extension 模块让 setuptools 明确识别这是一个平台相关包,具体步骤如下:
1. 添加空 Extension 模块
创建简单的 setup.py 文件(即使大部分配置在 setup.cfg 中):
from setuptools import setup, Extension setup( ext_modules=[Extension('mypackage._dummy', sources=[])], )
这个空的 Extension 不会生成任何实际文件,但会触发 setuptools 生成带有对应平台标签(如 manylinux_x86_64)的 Wheel,而非 none-any。
2. 确保 auditwheel 处理预编译库
由于你的 .so 文件是作为 package data 存在的(而非 Extension 编译生成的),需要让 auditwheel 明确处理这些文件。在 pyproject.toml 的 cibuildwheel 配置中修改 repair-wheel 命令:
[tool.cibuildwheel.linux] before-all = "bash {project}/src/mypackage/before_all.sh" repair-wheel = "auditwheel repair --plat manylinux2014_x86_64 -w {dest_dir} {wheel}"
该命令会强制 auditwheel 处理 Wheel 中的所有二进制文件,包括你预编译的 .so。
3. 验证配置
- 确保
before_all.sh生成的.so符合 manylinux 标准(避免 auditwheel 报错)。 - 打包时检查生成的 Wheel 文件名,确认带有正确的平台标签(如
mypackage-0.1.0-cp39-cp39-manylinux2014_x86_64.whl)。
常见误区
不要尝试仅通过修改 platforms 字段或手动指定 plat-name 来标记平台相关性,这种方式不够灵活,且无法适配 cibuildwheel 多平台构建的场景。空 Extension 是 setuptools 生态中公认的、规范的触发平台相关 Wheel 生成的手段。
内容的提问来源于stack exchange,提问作者user3708067

