我正在开发一个python2包,其中setup.py
包含一些自定义安装命令。这些命令实际上构建了一些Rust代码并输出了一些移动到python包中的.dylib
文件。
重要的一点是Rust代码在python包之外。
如果python包是纯python或特定于平台(如果它包含一些C扩展),则应该自动检测 setuptools
。
在我的例子中,当我运行python setup.py bdist_wheel
时,生成的轮子被标记为纯python轮:<package_name>-<version>-py2-none-any.whl
。
这是有问题的,因为我需要在不同的平台上运行此代码,因此我需要为每个平台生成一个轮子。
在构建方向盘时,是否有办法强制构建特定于平台?
答案 0 :(得分:13)
这是我通常从uwsgi
查看的代码基本方法是:
# ...
try:
from wheel.bdist_wheel import bdist_wheel as _bdist_wheel
class bdist_wheel(_bdist_wheel):
def finalize_options(self):
_bdist_wheel.finalize_options(self)
self.root_is_pure = False
except ImportError:
bdist_wheel = None
setup(
# ...
cmdclass={'bdist_wheel': bdist_wheel},
)
root_is_pure
位告诉车轮机械构建一个非purelib(pyX-none-any
)轮。您还可以通过说二进制特定于平台的组件但没有 cpython abi 特定组件来获取fancier。
答案 1 :(得分:3)
root_is_pure技巧和空的ext_modules技巧都不适合我,但是经过大量搜索后,我终于在'pip setup.py bdist_wheel' no longer builds forced non-pure wheels中找到了可行的解决方案
基本上,您可以在Distribution类中覆盖“ has_ext_modules”函数,并将distclass设置为指向该覆盖的类。到那时,setup.py将相信您具有二进制发行版,并将使用特定版本的python,ABI和当前体系结构创建一个转轮。根据{{3}}的建议:
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)
答案 2 :(得分:2)
模块setuptools
,distutils
和wheel
通过检查是否具有ext_modules
来确定python发行版是否纯。
如果您自己构建外部模块,仍然可以在ext_modules
中列出它,以便构建工具知道它的存在。诀窍是提供一个空的源列表,以便setuptools
和distutils
不会尝试构建它。例如,
setup(
...,
ext_modules=[
setuptools.Extension(
name='your.external.module',
sources=[]
)
]
)
对我来说,此解决方案比修补bdist_wheel
命令更好。原因是bdist_wheel
在内部调用install
命令,并且该命令再次检查ext_modules
是否存在,以决定在purelib
还是platlib
安装之间进行。如果未列出外部模块,则最终会在转盘内的purelib
子文件夹中安装lib。使用auditwheel repair
时会导致问题,抱怨安装在purelib
文件夹中的扩展名。
答案 3 :(得分:2)
您还可以通过指定--plat-name
来指定/欺骗特定的平台名称:
python setup.py bdist_wheel --plat-name=manylinux1_x86_64