'pip setup.py bdist_wheel'不再构build强制的非纯车轮

我有一个在Linux上编译C扩展的项目,但在Windows上没有。 当我第一次用python setup.py bdist_wheel在Windows上生成轮子文件时,它们变得普遍了,我不能将它们上传到PyPI,因为这些通用轮子是由pip首选的.tar.gz上传( python setup.py sdist的结果python setup.py sdist )。

这个技巧是在setup.py指定的:

 Distribution.is_pure = lambda *args: False 

或通过子类Distribution

 class BinaryDistribution(Distribution): def is_pure(self): return False 

并使用extra关键字参数distclass=BinaryDistribution,调用setup.py中的setup()

这在运行Windows XP 64的虚拟机上运行得很好,它具有32位和64位版本的Python 2.6 / 2.7 / 3.3 / 3.4和pypy,仅用于此目的。 一个简单的batch file给我:

 dist/pkg-1.0-cp26-none-win32.whl dist/pkg-1.0-cp26-none-win_amd64.whl dist/pkg-1.0-cp27-none-win32.whl dist/pkg-1.0-cp27-none-win_amd64.whl dist/pkg-1.0-cp33-none-win32.whl dist/pkg-1.0-cp33-none-win_amd64.whl dist/pkg-1.0-cp34-none-win32.whl dist/pkg-1.0-cp34-none-win_amd64.whl 

当你在Windows上运行pip在Linux上运行pip时,相应的软件包会被下载并通过pip安装,

 pkg-1.0.tar.gz 

其中包含安装期间编译的C源代码。

问题始于我没有备用的Windows 7许可机器,我可以安装Python 3.5(它不安装在EOL XP上)。 所以我调查了Appveyor并创build了appveyor.yml

 environment: matrix: - PYTHON: C:\Python27 - PYTHON: C:\Python33 - PYTHON: C:\Python34 - PYTHON: C:\Python35 - PYTHON: C:\Python27-x64 - PYTHON: C:\Python33-x64 DISTUTILS_USE_SDK: '1' - PYTHON: 'C:\Python34-x64' DISTUTILS_USE_SDK: '1' - PYTHON: 'C:\Python35-x64' install: - | %PYTHON%\python.exe -m pip install --upgrade pip %PYTHON%\python.exe -m pip install wheel build: off test_script: - echo Skipped for now after_test: - | %PYTHON%\python.exe setup.py bdist_wheel artifacts: - path: dist\* 

上面八个调用python setup.py bdist_wheel是一样的:

 pkg-1.0-py2-none-any.whl pkg-1.0-py3-none-any.whl 

如果你将这些file upload到PyPI,那么Linux会比.tar.gz更喜欢它们,导致不包含C扩展代码。

是什么原因造成的,我怎样才能使用Appveyor构build我的.whl文件(或者至less是Python 3.5的文件?

我刚刚在Windows 7 x64上使用Python v2.7和wheel v0.29.0来处理这个问题,在那里我用一些预编译的扩展(带有SWIG和外部DLL的复杂VisualStudio设置)构建了一个Python包。

在检查源代码后,我发现覆盖Distribution.has_ext_modules作品(自动包含平台名称和ABI标签):

 from setuptools import setup from setuptools.dist import Distribution DISTNAME = "packagename" DESCRIPTION = "" MAINTAINER = "" MAINTAINER_EMAIL = "" URL = "" LICENSE = "" DOWNLOAD_URL = "" VERSION = '1.2' PYTHON_VERSION = (2, 7) # Tested with wheel v0.29.0 class BinaryDistribution(Distribution): """Distribution which always forces a binary package with platform name""" def has_ext_modules(foo): return True setup(name=DISTNAME, description=DESCRIPTION, maintainer=MAINTAINER, maintainer_email=MAINTAINER_EMAIL, url=URL, license=LICENSE, download_url=DOWNLOAD_URL, version=VERSION, packages=["packagename"], # Include pre-compiled extension package_data={"packagename": ["_precompiled_extension.pyd"]}, distclass=BinaryDistribution) 

当然,差异是在环境中,正确工作的Win XP中安装了一个较旧版本的wheel包(0.24.0),而在Appveyor上安装了wheel的最新和最大(和破碎)的0.26版本0.25也被打破)。

更改YAML文件中的安装节以修复轮子版本:

 install: - | %PYTHON%\python.exe -m pip install --upgrade pip %PYTHON%\python.exe -m pip install wheel==0.24 

足以让这个快速工作。

但是,您应该将您的Linux机箱上的wheel包升级到0.28版,然后使用新的命令行选项--plat-name

 python setup.py sdist python2 setup.py bdist_wheel --plat-name win32 python2 setup.py bdist_wheel --plat-name win_amd64 python3 setup.py bdist_wheel --plat-name win32 python3 setup.py bdist_wheel --plat-name win_amd64 

这将产生:

 pkg-1.1.tar.gz dist/pkg-1.1-py2-none-win32.whl dist/pkg-1.1-py2-none-win32.whl dist/pkg-1.1-py3-none-win_amd64.whl dist/pkg-1.1-py3-none-win32.whl dist/pkg-1.0-cp34-none-win_amd64.whl 

您可以将其上载到PyPI,并在Linux上正确( .tar.gz )文件下载,并在Windows上正确下载。 通过确保如果指定了--plat-name win... ,那么使用ext_modules=None调用setup() 。 由此产生的wheel文件在3个文件和它们的SHA256SUM中都有次要的(行尾),但是在Windows上正常安装。

这样你就不再需要在Windows机器上构建这些基本上是纯软件包的软件包

对于我来说, Nate Coraor的这个改变将我的总体构建时间从15分钟缩短到了大约7