You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
We currently build libpython separately and out-of-app through Kivy (see relevant commit 9322af3), extract the shared object, and include that in ./distribution/python27/lib/armeabi-v7a (and the Python headers (also from the Kivy build dir) in ./distribution/python27/include) for the rest of our build process.
At some point in time, it would be nice to be able to build libpython directly from our main Gradle conf; more importantly, we need to ensure today that libpython links against a compatible version of the standard libraries.
The issue is that Android doesn't seem to version its system libraries, but their scope changes significantly between versions. A problem I ran into on Lollipop that involved forkpty seemingly has its roots in this mess --- updating to Nougat "fixed" the problem, in that Nougat's libc provides the call that the pre-built libpython2.7.so that I got from this repo requires.
Thus, when rebuilding libpython, we must test on several Android versions! I don't know if emulation works/makes sense/is efficient in this case, or we just grab another couple of phones that we flash to the various versions. (Dual-boot is not really an option. Third-party images can do it, but require root etc., so we'd be looking at non-stock and thus non-representative firmware afterwards.)
For easier reference, I'll reproduce the error message and a few sources that led me to my conclusions below too. It's well possible that other combinations of build and runtime versions give errors for different standard library calls.
W/linker ( 7159): libpython2.7.so: unused DT entry: type 0x6ffffffe arg 0x1143c
W/linker ( 7159): libpython2.7.so: unused DT entry: type 0x6fffffff arg 0x3
E/art ( 7159): dlopen("/data/app/com.sensibility_testbed-1/lib/arm/libpython2.7.so", RTLD_LAZY) failed: dlopen failed: cannot locate symbol "forkpty" referenced by "libpython2.7.so"...
D/AndroidRuntime( 7159): Shutting down VM
E/AndroidRuntime( 7159): FATAL EXCEPTION: main
E/AndroidRuntime( 7159): Process: com.sensibility_testbed, PID: 7159
E/AndroidRuntime( 7159): java.lang.UnsatisfiedLinkError: dlopen failed: cannot locate symbol "forkpty" referenced by "libpython2.7.so"...
E/AndroidRuntime( 7159): at java.lang.Runtime.loadLibrary(Runtime.java:371)
E/AndroidRuntime( 7159): at java.lang.System.loadLibrary(System.java:988)
E/AndroidRuntime( 7159): at com.snakei.PythonInterpreterService.<clinit>(PythonInterpreterService.java:72)
E/AndroidRuntime( 7159): at com.sensibility_testbed.SensibilityActivity$2.onClick(SensibilityActivity.java:203)
E/AndroidRuntime( 7159): at android.view.View.performClick(View.java:4780)
E/AndroidRuntime( 7159): at android.view.View$PerformClick.run(View.java:19866)
E/AndroidRuntime( 7159): at android.os.Handler.handleCallback(Handler.java:739)
E/AndroidRuntime( 7159): at android.os.Handler.dispatchMessage(Handler.java:95)
E/AndroidRuntime( 7159): at android.os.Looper.loop(Looper.java:135)
E/AndroidRuntime( 7159): at android.app.ActivityThread.main(ActivityThread.java:5254)
E/AndroidRuntime( 7159): at java.lang.reflect.Method.invoke(Native Method)
E/AndroidRuntime( 7159): at java.lang.reflect.Method.invoke(Method.java:372)
E/AndroidRuntime( 7159): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
E/AndroidRuntime( 7159): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
W/ActivityManager( 813): Force finishing activity 1 com.sensibility_testbed/.SensibilityActivity
For the forkpty call in libc in particular, API level 23 exposes it, whereas 22 doesn't. I haven't (yet?) found another library on 22 that implements forkpty.
I've rebuilt libpython2.7.so for API level 21, downgraded the Gradle config too, removed SensibilityActivity.java/onRequestPermissionsResult which isn't compatible with that API level, rebuilt the project, and behold, it works on my LG H420 running Android 5.0.1!
TODO: Document that we want backwards compatibility, and figure out how far backwards we can sanely go. Currently, the NDK supports API levels >=21, which covers around 60% of the world's Android population. Other API level pitfalls may lurk about.
We currently build
libpython
separately and out-of-app through Kivy (see relevant commit 9322af3), extract the shared object, and include that in./distribution/python27/lib/armeabi-v7a
(and the Python headers (also from the Kivy build dir) in./distribution/python27/include
) for the rest of our build process.At some point in time, it would be nice to be able to build
libpython
directly from our main Gradle conf; more importantly, we need to ensure today thatlibpython
links against a compatible version of the standard libraries.The issue is that Android doesn't seem to version its system libraries, but their scope changes significantly between versions. A problem I ran into on Lollipop that involved
forkpty
seemingly has its roots in this mess --- updating to Nougat "fixed" the problem, in that Nougat'slibc
provides the call that the pre-builtlibpython2.7.so
that I got from this repo requires.Thus, when rebuilding
libpython
, we must test on several Android versions! I don't know if emulation works/makes sense/is efficient in this case, or we just grab another couple of phones that we flash to the various versions. (Dual-boot is not really an option. Third-party images can do it, but require root etc., so we'd be looking at non-stock and thus non-representative firmware afterwards.)For easier reference, I'll reproduce the error message and a few sources that led me to my conclusions below too. It's well possible that other combinations of build and runtime versions give errors for different standard library calls.
Hints taken from:
libutil
to linker flagslibc
The text was updated successfully, but these errors were encountered: