26

假设我有一个独立于任何 Python 机制构建的本机共享库(.dll 或 .so),以及一个使用 ctypes 与库交互的 Python 模块。有没有办法可以将它们构建到 .whl 包中?如果是这样,怎么做?

假设这是可能的,我想我需要安装和使用 wheel 包,python setup.py bdist_wheel但我的 setup.py 需要看起来像什么?

我想这样做,这样我就可以将各种平台的 Wheels 上传到一个私有包索引中,并能够为我所在的平台 pip 安装适当的一个。

4

2 回答 2

41

编辑:按照Thomas D的建议更新了新版本的轮子。

这是一种方法。例如,这使用 libeay32.dll 来公开 md5 包。

项目结构为:

MD5
│   setup.py
│
└───md5
    __init__.py   
    libeay32.dll

setup.py 是:

from setuptools import setup, Distribution


class BinaryDistribution(Distribution):
    def has_ext_modules(foo):
        return True


setup(
    name='md5',
    version='1.0',
    description='MD5 Library',
    packages=['md5'],
    package_data={
        'md5': ['libeay32.dll'],
    },
    distclass=BinaryDistribution
)

有几点需要注意:

  1. DLL 被列为包数据,因此它将包含在轮子中。
  2. 使用了一个自定义的 distclass来表明这个轮子有一个扩展模块,并且由于轮子是在 Windows 上构建的,所以这是一个 win32 轮子。

Python ctypes 代码可以加载相对于自身的 DLL(此代码在 中__init.py__):

lib_path = os.path.join(os.path.dirname(__file__), 'libeay32.dll')
lib = CDLL(lib_path)

用 pip 安装 'wheel' 后,我可以运行python setup.py bdist_wheel生成 dist\md5-1.0-cp34-none-win32.whl。我碰巧使用的是 cpython 3.4,但是如果你想要一个万能轮,你可以像这样添加一个 setup.cfg 。

现在我可以创建并激活一个新的虚拟环境,pip install md5-1.0-cp34-none-win32.whl,并使用我的包:

>>> import md5
>>> md5.digest('hello')
'8d11aa0625ce42cfe9429d5e93b5ab0a'
于 2014-07-17T00:45:32.910 回答
11

尽管在撰写本文时选择的答案是正确的,但此拉取请求破坏了此功能。

我认为这个答案正确地解决了新版本的轮包中的这个问题。

(会将此添加为评论,但缺乏所需的声誉。)

于 2016-11-01T21:30:28.190 回答