How can I make a Python Wheel from an existing native library?

你离开我真会死。 提交于 2019-11-29 21:48:12
Eric Smith

Edit: Updated for newer versions of wheel as suggested by Thomas D.

Here is a way. For an example, this uses libeay32.dll to expose an md5 package.

The project structure is:

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

The setup.py is:

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
)

A couple of things to note:

  1. The DLL is listed as package data so that it will be included in the wheel.
  2. A custom distclass is used that indicates this wheel has an extension module, and since the wheel is being built on Windows, that this is a win32 wheel.

The Python ctypes code can load the DLL relative to itself (this code is in __init.py__):

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

After having installed 'wheel' with pip, I can run python setup.py bdist_wheel to produce dist\md5-1.0-cp34-none-win32.whl. I happen to be using cpython 3.4, but if you want a universal wheel, you can add a setup.cfg like this one.

Now I can create and activate a new virtual environment, pip install md5-1.0-cp34-none-win32.whl, and use my package:

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

Although the chosen answer was correct at the time of writing, this pull request broke this functionality.

I think this answer correctly solves this problem in newer versions of the wheel package.

(Would have added this as a comment, but lack the reputation needed.)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!