kivy / kivy-ios

Toolchain for compiling Python / Kivy / other libraries for iOS
https://kivy.org/docs/guide/packaging-ios.html
MIT License
777 stars 240 forks source link

pyzbar depends on dynamic loading of libzbar, but recipe builds static library #681

Open RobertFlatt opened 2 years ago

RobertFlatt commented 2 years ago

Versions

Describe the bug Issue was found with a load time error when pyzbar loads libzbar, see log below.

The fail is due to ctypes.util.py invoking subprocess to run /sbin/ldconfig.

I think the error message is misleading, because ctypes/util.py contains blocks of platform specific code, and is executing the catchall. The catchall because there is one earlier block for 'darwin' but no block for 'ios'.

There are two 'darwin' specific blocks (both assume posix, does iOS claim posix?) https://github.com/python/cpython/blob/main/Lib/ctypes/util.py#L70 https://github.com/python/cpython/blob/main/Lib/ctypes/util.py#L349

Hopefully these 'darwin' cases also cover 'ios'

Logs

   File "/private/var/containers/Bundle/Application/05C29F5B-4C28-4B05-BC61-614E42E25916/qr6.app/lib/python3.9/site-packages/pyzbar/pyzbar.py", line 7, in <module>

     from .wrapper import (

   File "/private/var/containers/Bundle/Application/05C29F5B-4C28-4B05-BC61-614E42E25916/qr6.app/lib/python3.9/site-packages/pyzbar/wrapper.py", line 139, in <module>

     zbar_version = zbar_function(

   File "/private/var/containers/Bundle/Application/05C29F5B-4C28-4B05-BC61-614E42E25916/qr6.app/lib/python3.9/site-packages/pyzbar/wrapper.py", line 136, in zbar_function

     return prototype((fname, load_libzbar()))

   File "/private/var/containers/Bundle/Application/05C29F5B-4C28-4B05-BC61-614E42E25916/qr6.app/lib/python3.9/site-packages/pyzbar/wrapper.py", line 115, in load_libzbar

     libzbar, dependencies = zbar_library.load()

   File "/private/var/containers/Bundle/Application/05C29F5B-4C28-4B05-BC61-614E42E25916/qr6.app/lib/python3.9/site-packages/pyzbar/zbar_library.py", line 63, in load

     path = find_library('zbar')

>   File "/private/var/containers/Bundle/Application/05C29F5B-4C28-4B05-BC61-614E42E25916/qr6.app/lib/python39.zip/ctypes/util.py", line 329, in find_library

   File "/private/var/containers/Bundle/Application/05C29F5B-4C28-4B05-BC61-614E42E25916/qr6.app/lib/python39.zip/ctypes/util.py", line 289, in _findSoname_ldconfig

 AttributeError: module 'subprocess' has no attribute 'Popen'

2022-03-11 14:51:02.535669-1000 qr6[1324:654347] Application quit abnormally!

2022-03-11 14:51:02.552869-1000 qr6[1324:654347] Leaving

Additional context

1) Obviously the issue is more general to Python code than pyzbar loading libzbar.

2) As to other cases, a grep -R \"darwin\" of cpython finds 48 matches, but very few that look like they might be worth checking.

RobertFlatt commented 2 years ago

Turns out kivy-ios needs to use the classic posix find_library() approach to find libc and libm. So the 'darwin' to 'ios' proposal above won't work. But the posix approach does not find a libname.a built by a kivy-ios recipe.

Current hypothesis is a patch something like this:

--- Python-3.9.9.orig/Lib/ctypes/util.py    2022-04-07 15:30:26.000000000 -1000
+++ Python-3.9.9/Lib/ctypes/util.py 2022-04-07 15:28:49.000000000 -1000
@@ -325,10 +325,23 @@
             return result

         def find_library(name):
-            # See issue #9998
-            return _findSoname_ldconfig(name) or \
-                   _get_soname(_findLib_gcc(name)) or _get_soname(_findLib_ld(name))
-
+            if name in ('c', 'm'):
+                # See issue #9998
+                return _findSoname_ldconfig(name) or \
+                    _get_soname(_findLib_gcc(name)) or \
+                    _get_soname(_findLib_ld(name))
+            else:
+                 # >>>Here need to find 'libname.a' <<<<  
 ################################################################
 # test code

@misl6 Where do I look to get the path to the app libs directory on iOS device?

RobertFlatt commented 2 years ago

Copying the mach-o file to the project, and patching the loader results in:

./libzbar.a' (file does not start with MH_MAGIC[_64], 
file does not start with MH_MAGIC[_64], 
fat file, but missing compatible architecture 
(have 'x86_64,arm64', need 'arm64e'))

Perhaps the recipe has to build a .dylib ?