Search code examples
pythonpython-packagingzipapp

How to load a C dynamic library embedded in a python package with ctypes


I have a python app that, using ctypes, loads and calls a dynamic C library.

I want to create a zipapp with this application, but I don't know how to obtain the path to the library from within the app. The directory tree is:

mypackage/
├── __init__.py
├── __main__.py
└── lib
    └── libmylyb.so

and __main__.py is:

#!/usr/bin/env python3
from ctypes import *
h = cdll.LoadLibrary("./lib/libmylib.so")
...

I create the zipapp by doing:

python3 -m zipapp mypackage

but when I try to execute it, I get an error because the above library is not found.

I'm aware that pkgutil.get_data can be used to read the file content, and I guess that I could read the library binary data, write it in a temp file and the load it, but is there any better way to do what I want?


Solution

  • zipapp does not support compiled binaries only python code. you can pack .pyd, .so, and .dll files in your application’s file but you won’t be able to use them unless you unzip them into your file system.

    If you need to run it without unzipping, You’ll find tools such as PyInstaller, py2exe, py2app, Nuitka, and more can do that.

    I did stumble upon this app that gives the functionality you need or at least helps zipapp to achieve it: https://github.com/ClericPy/zipapps

    There is also https://shiv.readthedocs.io/en/latest/