vpelletier / python-libusb1

Python ctype-based wrapper around libusb1
GNU Lesser General Public License v2.1
168 stars 65 forks source link

Add PyInstaller Hook #68

Closed jrast closed 3 years ago

jrast commented 3 years ago

Currently the DLL, which ships with the windows build, is not automatically included if PyInstaller is used to bundle a application. The PyInstaller Documentation recommends to provide the required hooks in the package itself and using a special setuptools entry point in order to make the hook discoverable.

The following hook would be required:

"""
PyInstaller Hook for usb1
"""
from PyInstaller.utils.hooks import collect_dynamic_libs
binaries = collect_dynamic_libs( 'usb1' ) 
vpelletier commented 3 years ago

Hello,

So if I understand correctly, this means putting the code above in a new hook-usb1.py file next to setup.py, making sure it gets added to the source distribution, and that's it ? Or is there something more needed ?

Especially, as you are mentioning the windows wheel, does it need to be included in the wheel, or is PyInstaller only used on a source distribution ?

jrast commented 3 years ago

It needs to be included in the wheel. I will try to create a complete example with all files required! Give me a few days and ping me if I don't provide the example here!

Btw: Thanks so much for including the DLL in the Windows build! This solved our very hacky way to provide the library to the users...

jrast commented 3 years ago

Ok, I took a closer look at this and studied the sample project. Seems like the following adjustements / files are required:

Create a new file usb1/__pyinstaller/__init__.py with the following content:

import os

def get_hook_dirs():
    return [os.path.dirname(__file__)]

def get_PyInstaller_tests():
    return [os.path.dirname(__file__)]

Note that the second function is currently unused as I was not able to find any information about how tests are collected and run with pyinstaller.

Create a new file usb1/__pyinstaller/hook-libusb1.py with the following content:

from PyInstaller.utils.hooks import collect_dynamic_libs
binaries = collect_dynamic_libs( 'usb1' )

Update setup.py to include the required entry_points:

setup(
    ..., # All existing args / kwargs
    entry_points={
        "pyinstaller40": ["hook-dirs=usb1.__pyinstaller:get_hook_dirs"]
    },
)

After these modifications the hook got picked up by pyinstaller when I bundeled my application. Should I create a PR for this?

jrast commented 3 years ago

Another option would be to add the hook to the PyInstaller Hooks Contrib Package: https://github.com/pyinstaller/pyinstaller-hooks-contrib

But I think including the hook in this repo would be better as it's more flexible.

vpelletier commented 3 years ago

Should I create a PR for this?

As you prefer. These changes look good to me (if you confirm they work when used with pyinstaller, as I have not tested them). You have done most of the work, so it would be fair that you have your name on them in the repository history.

jrast commented 3 years ago

See #69

vpelletier commented 3 years ago

Closing as 1.9.3 is now released with the fix. Thanks.