I am trying to build my Android (native) project using cmake (migrating it from gradle experimental plugin where it used to build and run fine).
I have some native code(will call it 'a') which uses another external prebuilt library code (will call it 'b') and I linked the two like this: (according to https://developer.android.com/studio/projects/configure-cmake)
cmake_minimum_required(VERSION 3.4.1)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -frtti -fno-common -fexceptions")
include_directories(
#a's include files' paths
#b's include files' paths)
file(GLOB_RECURSE A_SOURCES
#a's source files' paths)
add_library(a_lib SHARED ${A_SOURCES})
add_library(b_lib SHARED IMPORTED)
set_target_properties(b_lib PROPERTIES IMPORTED_LOCATION "b's .so path")
target_link_libraries(a_lib b_lib)
I got past the compilation and linking steps and the android studio goes ahead to install the APK on my device. However, after launch, the app freezes with the following in the logcat:
E/ExceptionHandler: Uncaught Exception java.lang.UnsatisfiedLinkError: dlopen failed: library "libb_lib.so" not found
at java.lang.Runtime.loadLibrary0(Runtime.java:989)
at java.lang.System.loadLibrary(System.java:1530)
at com.mm.projectname.model.libloadingclassname.<clinit>(libloadingclassname.java:99)
I know this is happening because b_lib's .so is not there in the apk. And I can see b's symbols along with a's symbols in a's shared library.
So my question is how can I
I searched a lot for similar posts and questions (eg one and two ) but i cant get anything to work. I am really looking for the right way to do this - which wont create problems in the future (like changing the targetSDKversion). I also tried building the prebuilt lib with the latest ndk version.
It's possible that I am doing a very small mistake, and would really appreciate if someone could point it out.
Thanks in advance
jniLibs
folder in your app's main
directory (e.g.: /app/src/main
).A little late, but someone else might be interested (or even the op).
I had the same situation as the op and I tried many different things. One of those was to try and compile the project with an earlier version of NDK (I think r14b, but I am not enitrely sure). I got a different error and managed to track down the issue which is well described here, in sections "Invalid DT_NEEDED Entries" and "Missing SONAME". Additionally, the problem is described in this particular question and has received an adequate answer.
If you cannot recompile the shared library you are using in order to include the SONAME, like in my case, you can do the following thing I did and managed to work:
Header:
private:
typedef uint32_t (*InitX_t)();
typedef uint32_t (*DoX_t)();
typedef uint32_t (*GetX)(uint32_t, char*);
InitX_t InitX;
DoX_t DoX;
GetX_t GetX;
CPP
void *handle = dlopen("libMyLib.so", RTLD_NOW);
if(handle == nullptr)
{
__android_log_print(ANDROID_LOG_INFO, "My Class", "Could not load library");
}
else
{
__android_log_print(ANDROID_LOG_INFO, "My Class", "Library loaded");
}
InitX = (InitX_t)dlsym(handle, "InitX_SYMBOL");
ScanX = (ScanX_t)dlsym(handle, "ScanX_SYMBOL");
GetX = (GetX_t)dlsym(handle, "GetX_SYMBOL");
if(ScanX == nullptr || GetX == nullptr || InitX == nullptr)
{
__android_log_print(ANDROID_LOG_INFO, "My Class", "Could not load functions.");
}
If done correctly, you should be able, now, to use the functions as usual. I understand, though, that it's not the most trivial process to go if you are a beginner.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With