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

Unable to load native library: /data/app-lib/*/lib*.so #446

Open
p0ryae opened this issue Nov 13, 2023 · 3 comments
Open

Unable to load native library: /data/app-lib/*/lib*.so #446

p0ryae opened this issue Nov 13, 2023 · 3 comments

Comments

@p0ryae
Copy link

p0ryae commented Nov 13, 2023

I managed to compile, get the .so file, and then package an apk based on it. However, no matter what I try, I keep getting this error over and over again. It just can't load the native library, even though it's compiled based on the device's architecture (armv6). I use the arm-linux-androideabi target in order to get the final lib .so file.

I use ndk r16b, which is the last ndk to support armeabi.

For compilation of the .so file, I pass through the CARGO_TARGET_ARM_LINUX_ANDROIDEABI_LINKER flag with the value of /home/porya/Android/Sdk/ndk/android-ndk-r16b/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-ld. Furthermore, I also link the libraries in the build.rs:

fn main() {
    println!("cargo:rustc-link-search=/home/porya/Android/Sdk/ndk/android-ndk-r16b/platforms/android-19/arch-arm/usr/lib/");
}

The full error report in adb logcat:

E/AndroidRuntime( 3363): FATAL EXCEPTION: main
E/AndroidRuntime( 3363): Process: org.p0ryae.trs24, PID: 3363
E/AndroidRuntime( 3363): java.lang.RuntimeException: Unable to start activity ComponentInfo{org.p0ryae.trs24/android.app.NativeActivity}: java.lang.IllegalArgumentException: Unable to load native library: /data/app-lib/org.p0ryae.trs24-1/libtrs_24.so
E/AndroidRuntime( 3363): 	at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2212)
E/AndroidRuntime( 3363): 	at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2271)
E/AndroidRuntime( 3363): 	at android.app.ActivityThread.access$800(ActivityThread.java:144)
E/AndroidRuntime( 3363): 	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1205)
E/AndroidRuntime( 3363): 	at android.os.Handler.dispatchMessage(Handler.java:102)
E/AndroidRuntime( 3363): 	at android.os.Looper.loop(Looper.java:136)
E/AndroidRuntime( 3363): 	at android.app.ActivityThread.main(ActivityThread.java:5179)
E/AndroidRuntime( 3363): 	at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime( 3363): 	at java.lang.reflect.Method.invoke(Method.java:515)
E/AndroidRuntime( 3363): 	at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:732)
E/AndroidRuntime( 3363): 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:566)
E/AndroidRuntime( 3363): 	at dalvik.system.NativeStart.main(Native Method)
E/AndroidRuntime( 3363): Caused by: java.lang.IllegalArgumentException: Unable to load native library: /data/app-lib/org.p0ryae.trs24-1/libtrs_24.so
E/AndroidRuntime( 3363): 	at android.app.NativeActivity.onCreate(NativeActivity.java:183)
E/AndroidRuntime( 3363): 	at android.app.Activity.performCreate(Activity.java:5231)
E/AndroidRuntime( 3363): 	at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
E/AndroidRuntime( 3363): 	at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2169)
E/AndroidRuntime( 3363): 	... 11 more
W/ActivityManager( 2138):   Force finishing activity org.p0ryae.trs24/android.app.NativeActivity

I also tried checking the dependencies for libtrs_24.so using readelf and my android system has all of them.

Is there a way to find the root cause? Am I missing something? Any ideas on where to start is appreciated.

@p0ryae
Copy link
Author

p0ryae commented Nov 15, 2023

Update:

After hours and days of researching and going through hell, nothing helped to get anywhere...

UNTIL I decided to manually load the library via android studio (System.loadLibrary("trs_24");) and run it on my armv6 device. Turns out it can't locate the getifaddrs symbol. Full error log:

FATAL EXCEPTION: main
Process: com.example.myapplication, PID: 12794
java.lang.UnsatisfiedLinkError: dlopen failed: cannot locate symbol "getifaddrs" referenced by "libtrs_24.so"...

getifaddrs function (or ifaddrs header) native support exists since android 7.0 (NDK >= 24). For NDKs below 24 (or androids below 7.0), I found this repo for the implementation:

https://github.com/morristech/android-ifaddrs

Not sure exactly how to go from here. Am I supposed to compile the custom c code in rust, so the final built .so file has it (using the cc crate)?

@mrazorvin
Copy link

mrazorvin commented Jan 22, 2024

Hi, I faced same problem,

I'm tried to create rust bindings for https://github.com/effekseer/Effekseer (c++ lib). I started with custom build.rs that compiles static lib with cc from sources (in the same way as luau-sys), it's perfectly works on Linux and Windows. But when I tried to compile my lib with NDK, I got dlopen failed: cannot locate symbol eglGetProcAdressess.

I investigated little bit more and know for sure that I can use following code to call this function inside my lib


#include <iostream>
#include <stdio.h>
#include <string>
#include <dlfcn.h>

using namespace std;

#define DLL_EXPORT extern "C"

typedef void (*GLFWglproc)(void);
typedef GLFWglproc(EGLAPIENTRY *PFN_eglGetProcAddress)(const char *);

struct Pointers
{
  PFN_eglGetProcAddress eglGetProcAddress;
};

DLL_EXPORT void effekseer_version()
{
  std::cout << "v1.0.0" << endl;

#if defined(__ANDROID__)
  auto handle = dlopen("libEGL.so", RTLD_LAZY | RTLD_LOCAL);
  auto ptrs = new Pointers;
  ptrs->eglGetProcAddress = (PFN_eglGetProcAddress)dlsym(handle, "eglGetProcAddress");
  if (ptrs->eglGetProcAddress("glDeleteBuffers") == nullptr)
  {
    std::cout << "glDeleteBuffers --- NOT FOUND ---" << endl;
  }
  else
  {
    std::cout << "glDeleteBuffers +++ FOUND +++" << endl;
    auto glFetString
  }

  std::cout << "Android extension v1.2.0" << endl;
#endif
}

So at this point I knows that only static linking don't work correctly.
Also not sure where to move next I tried following:

  • println!(r"cargo:rustc-link-search=native=libEGL");
  • System.loadLibrary("libEGL");
  • Add native-lib to Android manifest
  • Use ndk from 21 to latest
  • arguments "-DANDROID_STL=c++_shared" in gradle.build

@mrazorvin
Copy link

mrazorvin commented Jan 22, 2024

UPDATE

I forgot to link shared libraries

Following lines were missed in build.rs

println!(r"cargo:rustc-link-lib={}", "EGL");
println!(r"cargo:rustc-link-lib={}", "GLESv3");

*.so dependencies could be checked with xelfviewer (https://github.com/horsicq/XELFViewer)

image

For example on screenshot above GLES3 is missed

P.S

For GLES lib name is different from it namespace, correct lib name could be found there https://developer.android.com/ndk/guides/stable_apis

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

No branches or pull requests

2 participants