3

I want to add another lib into android-ndk hello-libs example.

In CMakeLists.txt, I add:

# this is from the hello-libs sample code
add_library(lib_gperf SHARED IMPORTED)
set_target_properties(lib_gperf PROPERTIES IMPORTED_LOCATION
        ${distribution_DIR}/gperf/lib/${ANDROID_ABI}/libgperf.so)

########## I add this after the sample code:  ###########
add_library(lib_py SHARED IMPORTED)
set_target_properties(lib_py PROPERTIES IMPORTED_LOCATION
        ${distribution_DIR}/gperf/lib/${ANDROID_ABI}/libpython.so)

And this:

target_link_libraries(
        hello-libs
        android
        lib_gperf

        #### this line ######
        lib_py

        log)

And copy libpython.so in the directory where libgperf.so located:

Also copy the python headers into the include directory:

enter image description here

When I click the run button:

java.lang.UnsatisfiedLinkError: dlopen failed: library "/Users/finn/Downloads/hello-libs/app/src/main/cpp/../../../../distribution/gperf/lib/arm64-v8a/libpython.so" not found
        at java.lang.Runtime.loadLibrary0(Runtime.java:1016)
        at java.lang.System.loadLibrary(System.java:1657)
        at com.example.hellolibs.MainActivity.<clinit>(MainActivity.java:36)
        at java.lang.Class.newInstance(Native Method)
        at android.app.Instrumentation.newActivity(Instrumentation.java:1174)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2747)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2931)
        at android.app.ActivityThread.-wrap11(Unknown Source:0)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1620)
        at android.os.Handler.dispatchMessage(Handler.java:105)
        at android.os.Looper.loop(Looper.java:173)
        at android.app.ActivityThread.main(ActivityThread.java:6698)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:782)

The path exists in my computer, but why the apk use my computer path, but not the android device path?

And I use the Android device file explorer, the lib is in the directory:

enter image description here

Then how can I make the apk use the right path?

Or I miss something to add?

shizhen
  • 12,251
  • 9
  • 52
  • 88
Finn
  • 279
  • 3
  • 8
  • Possible duplicate of [Android NDK: dlopen failed](https://stackoverflow.com/questions/47279824/android-ndk-dlopen-failed) – Dan Albert Jun 14 '19 at 20:31

2 Answers2

1

I encounter the exact same issue and I discovered that when the .so file is built, the library link for the python library is wrong while the link for gperf library is ok.
Link error for python library
Both libraries are imported with the exact same method in the cmake so it doesn't make sense.
I friend of mine told me it is a bug from ninja and they provided me a "turn-around" solution. You have to import the python library as if it was an Android-NDK provided one (like Android or Log).

The library should be put in the NDK libraries, which should be located at <NDK PATH>/toolchains/llvm/prebuilt/<OS_related_folder>/sysroot/usr/lib/<ABI targeted>/<minSdkVersion/

Where:
- NDK path is the location of your NDK folder.
- OS_related_folder is the os_named folder (in my case windows-x86_64).
- ABI targeted is the ABI to which your library is compiled for (arm-linux-androideabi, aarch64-linux-android, etc).
- minSdkVersion is the number of your min SDK version of your project.
This information was found from CMakeCache.txt, in the folder `\app.cxx\cmake\debug\\'. When using find_library for log, the path of the library is shown

Change CMakeLists.txt to only provide library include, and directly link the library by it's name (python2.7 for libpython2.7.so)

cmake_minimum_required(VERSION 3.4.1)

add_library( native-lib SHARED native-lib.cpp)

include_directories( ${CMAKE_CURRENT_LIST_DIR}/../../../libs/python/include/ )

find_library( log-lib log ) # Optional

target_link_libraries( native-lib python2.7 ${log-lib} )

Since the python library isn't natively provided by Android, you will need to pack it to the APK by changing the jnLibs folders (see documentation)

Following these steps should fix the issue Resulting library link in .so file

Obviously, this is not a good solution. I hope my answer will draw more attention on this issue and somebody will provide a real solution to avoid such tweaks

  • I have the same issue and cannot resolve by this approach. Is there any other solutions? Could the problem caused by the .so file itself? – Ali Sadeghi Dec 17 '19 at 07:04
  • 1
    I believe that the location where to put the .so isn't correct. I used to put it in the "ndk-bundle/platforms/android-//usr/lib/" but with a recent update of android update, the location changed. I do not compile the libpython through Android Studio anymore, so I cannot test it myself. Could you try it and report the result? – Paul THOMAS Jan 08 '20 at 16:34
  • 1
    I created a new projet and redo the whole process. The location where to put the file is \\toolchains\llvm\prebuilt\windows-x86_64\sysroot\usr\lib\\ If you are unsure of where to put the library, add log as requirement and check the CMakeCache.txt in the .cxx/cmake/debug/ folder The path of the log library will be provided, this is where you should put your library – Paul THOMAS Jan 08 '20 at 18:22
  • Thank you Paul for your complete explanation. I'll try and report the result. – Ali Sadeghi Jan 11 '20 at 07:36
-1

Assume path /Users/finn/Downloads/hello-libs/app/src/main/cpp/../../../../distribution/gperf/lib is correct, then you can configure your JNI libs like below:

sourceSets {
    release {
        jniLibs.srcDirs += ["/Users/finn/Downloads/hello-libs/app/src/main/cpp/../../../../distribution/gperf/lib"]
    }
    debug {
        jniLibs.srcDirs += ["/Users/finn/Downloads/hello-libs/app/src/main/cpp/../../../../distribution/gperf/lib"]
    }
}    

Try to change /Users/finn/Downloads/hello-libs/app/src/main/cpp/../../../../distribution/gperf/lib if it is not your correct path to the jni libs.

shizhen
  • 12,251
  • 9
  • 52
  • 88