Suppose I have a native shared library (.dll or .so), built independently of any Python mechanism, and a Python module using ctypes to interface to the library. Is there a way that I can build those into a .whl package? If so, how?
Assuming this is possible, I think I'd need the wheel package installed and to use python setup.py bdist_wheel
but what would my setup.py need to look like?
I'd like to do this so I can upload Wheels for various platforms into a private package index and be able to pip install the appropriate one for the platform I'm on.
You can easily build a single cross-platform, cross-Python wheel that just works. You just need to add "[bdist_wheel] universal=1" to your setup. cfg and write your code in a cross-Python style enabled by six and future (https://pypi.python.org/pypi/future).
Most wheels are pure-Python, which means that they only contain Python source code.
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:
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 options={"bdist_wheel": {"universal": True}}
into the setup call.
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'
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.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With