Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Flatten versioned .so.x.y.z files so they can be included in an apk #176

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

marcprux
Copy link
Contributor

@marcprux marcprux commented Oct 1, 2024

The termux library dependencies include various shared object files that utilize the convention of having the base .so link to a version-suffixed file name. This works fine when running command-line executables on an Android device, but embedding the files in an Android apk will fail, both because the Android Gradle Plugin and the ART ignore everything not matching "lib*.so" in the .apk file's JNI libraries.

The error will look something like this when using a native Swift library that uses FoundationNetworking:

java.lang.UnsatisfiedLinkError: dlopen failed: library "libz.so.1" not found: needed by /data/app/~~W13d9DU_6Dw1D9JyCFe4Qg==/skip.droid.app-WSsoFlAqxhPx6In_xOnoGg==/base.apk!/lib/arm64-v8a/libcurl.so in namespace clns-6
    at java.lang.Runtime.loadLibrary0(Runtime.java:1082)
    at java.lang.Runtime.loadLibrary0(Runtime.java:1003)
    at java.lang.System.loadLibrary(System.java:1661)
    at skip.droid.AndroidAppMain.onCreate(Main.kt:78)
    at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1316)
    at android.app.ActivityThread.handleBindApplication(ActivityThread.java:6998)
    at android.app.ActivityThread.-$$Nest$mhandleBindApplication(Unknown Source:0)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2236)
    at android.os.Handler.dispatchMessage(Handler.java:106)
    at android.os.Looper.loopOnce(Looper.java:205)
    at android.os.Looper.loop(Looper.java:294)
    at android.app.ActivityThread.main(ActivityThread.java:8177)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:552)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:971)

This solution walks through each of the termux libraries and identifies which ones are version-suffixed, and moves them to the non-version suffixed base name. It also uses patchelf to update the soname for the renamed files, as well as update the needed sections for any peer libraries so they point to the correct names.

For more information and other approaches, see https://stackoverflow.com/questions/62450784/link-in-android-studio-with-shared-libraries-with-versioning and https://gist.github.com/Sotatek-TuyenLuu/2f89b2a6690989b0550ea7d409d4e9f3.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant