如何从现有的本机库制作 Python Wheel?

问题描述 投票:0回答:3

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

假设这是可能的,我想我需要安装wheel包并使用

python setup.py bdist_wheel
但是我的setup.py需要是什么样子?

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

python python-wheel
3个回答
48
投票

这里有一个方法。例如,这使用 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
,但如果您想要万向轮,您可以将
options={"bdist_wheel": {"universal": True}}
添加到设置调用中。

现在我可以创建并激活一个新的虚拟环境:

pip install md5-1.0-cp34-none-win32.whl

并使用我的包:

>>> import md5
>>> md5.digest('hello')
'8d11aa0625ce42cfe9429d5e93b5ab0a'

11
投票

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

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

(本可以将其添加为评论,但缺乏所需的声誉。)


1
投票

使用

cibuildwheel
,这是
pypa
背后的团队
pip
的解决方案。

cibuildwheel
可以用原生库构建wheel,它会自动修复像
LD_LIBRARY_PATH
这样的问题,并将dll/so文件合并到bdistwheel中。

© www.soinside.com 2019 - 2024. All rights reserved.