Android - UnsatisfiedLinkError: unknown failure loading libQt5Core.so - android

This is the first time I decided to write here, but I have long time successfully used stackoverflow, thanks to people who spend his time helping others! :)
Now, I have not found information about this, I am trying to use a library which uses Qt in my android application. The problem is that I am not able to load libQt5Core.so. When running Android throw an unsatisfiedLinkError: unknown failure.
I have tried to load it in two ways.
First one, with its own Android.mk:
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := Qt5Core
LOCAL_SRC_FILES := $(TARGET_ARCH_ABI)/libQt5Core.so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include \
$(LOCAL_PATH)/include/QtCore
include $(PREBUILT_SHARED_LIBRARY)
Second one, adding it manually to lib dir.
I load libraries froma Native.java file in this way:
System.loadLibrary("gnustl_shared");
System.loadLibrary("Qt5Core");
System.loadLibrary("mysharedlibray");
System.loadLibrary("thewholelibrary");
I mysharedlibrary with a Makefile, it's the library which uses Qt.
The whole library includes the jni code and mysharedlibrary, I make it using ndk-build.
I have got libQt5Core.so from the Necessitas package, I suppose I can use it out from the Necessitas system.
I also would like make a "standalone shared library" mysharedlibrary with the Qt "inside" it (since I use no Qt at jni in Android" but it does not let me do that.
Thanks a lot!

To load libQt5Core.so in your android project, you should add dependency to QtAndroid-bundled.jar. You can find the file in the Qt installation directory under the jar directory. After this step you can call System.loadLibrary("Qt5Core"); without UnsatisfiedLinkError.
The reason: QtCore's JNI_OnLoad loads an activity called QtNative when it starts and returns JNI_ERR if it is not found. QtNative is defined in QtAndroid-bundled.jar. I fount anwer here: https://stackoverflow.com/a/25856689/1091536

I've found one solution:
static {
try {
System.loadLibrary("gnustl_shared");
System.loadLibrary("Qt5Core");
}
catch( UnsatisfiedLinkError e ) {
System.err.println("Native code library failed to load.\n" + e);
}
System.loadLibrary("mysharedlibray");
System.loadLibrary("thewholelibrary");
}
If your library uses Qt but just inside itself that works.

Related

Native library not found on android build?

I am getting this error: unable to lookup library path for, native render plugin support disabled when I run my app on android. I think I am building the shared libraries incorrectly.
I am looking to build the source files from this repo. I'll say my build process and perhaps someone can spot a step I'm missing or doing incorrect.
Following this guide, I came up with this:
Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := libhydrogen
LOCAL_SRC_FILES := ..\hydrogen.c
include $(BUILD_SHARED_LIBRARY)
Application.mk
APP_PLATFORM := android-16
APP_OPTIM := release
APP_MODULES := libhydrogen
Next I:
Placed these files in the jni folder.
Called ndk-build.
Copied the .so files from the \libs folder and placed them in their respective folders in Unity (i.e. Hydrogen\Plugins\Android\arm64-v8a).
Made sure their platforms and CPU architectures were correct.
Built my app.
Here is the c# wrapper I am using.
Calling Hydrogen.Library.Initialize(); is then giving me this error.
Here is the full logcat related to this error.
And in the case my build process manages to be correct, and the .so files are fine; what else might cause this to happen?
Edit: I am trying to build for armeabi-v7a and `x86. Here are the .so file details, maybe there is something there that is not right? I am unfamiliar with c and since I haven't heard of anyone building this library for android, I wonder: could there be anything within the c source file that is incompatible with the NDK build process?
Native libraries are loaded by the native linker of the system, in your case, the linux dynamic linker: ld.so (it changes names sometimes, so I used that name, as you can check the man page in the documentation with that name).
For that to happen, in general, you need to provide a LD_LIBRARY_PATH environment variable to the java virtual machine, so it can effectively dlopen(3) it.
Think how different can be your development system to your target one.... and you'll easily get to that.
It was a bug with Unity! For some reason when switching the project's target platform some of my files would get corrupted. Strangely, it only seems to happen in this one project, but in any case the (temporary) solution is to re-import the plugin folder whenever I switch platforms.

How to build lib protobuf along with dynamic library for use in Android application?

I'm trying to compile an open source project (let's say foo) into a libfoo.so native library to use for my android app. However, this project also uses google's protocol buffer library.
So i was able to compile Google's lib protobuf for iOS as follows: https://gist.github.com/BennettSmith/7150245 .
However, this just generates libprotobuf.a file. The problem is that I can't seem to figure out a way to include this libprotobuf.a file to my libfoo.so file for use with my android application. I THOUGHT i had referenced it when i did:
include $(CLEAR_VARS)
LOCAL_MODULE := libprotobuf
LOCAL_SRC_FILES := ./src/lib/libprotobuf.a
LOCAL_EXPORT_C_INCLUDES := ./src/include
include $(PREBUILT_STATIC_LIBRARY)
in my Android.mk file. However, it seems that it is definitely not getting linked properly. Whenever i try to ndk-build the open source project (which depends on using lib protobuf), i get a bunch of undefined references, like:
undefined reference to 'google::protobuf::internal::empty_string_'
so then i thought that maybe i'm not supposed to have the symbols defined here? like maybe i'm supposed to first compile the libfoo.so file, and then somehow link lib protobuf as libprotobuf.a or libprotobuf.so ?? so i ended up using LOCAL_ALLOW_UNDEFINED_SYMBOLS := true to just get my project to generate the libfoo.so file.
but this libfoo.so gives me some load error as soon as i try to use it within my android app:
dlopen failed: cannot locate symbol "_ZN6google8protobuf11MessageLite15ParseFromStringERKSs" referenced by libfoo.so
So I'm wondering:
How do i include this protobuf library in my android app?
Do i try to include this protobuf library into libfoo.so first?
Would it even work if i tried to ignore linker warnings and then tried to generate libprotobuf.so and include that with my application?
is it even possible to generate libprotobuf.so? I can't generate it using the instructions on their github - i get a ton of errors
Note that the only reason i'm even able to get undefined reference errors when trying to generate libfoo.so is because i manually copied all of the *.h in google's lib protobuf.
Any help would be greatly appreciated!!!

Why isn't libgnustl_shared.so being copied from my APK?

I have an android project with a libs folder structure like this:
/libs
/armeabi
libfoo.so
libbar.so
libmystuff.so
libgnustl_shared.so
/armeabi-v7a
libfoo.so
libbar.so
foo and bar are third party libraries, mystuff is my own library from a separate android JNI project which requires gnustl_shared, which is from the same JNI project.
When I build my project in Eclipse, I can view the contents of the generated APK using unzip -l, and it indeed shows that all of these library files have been included.
However, after installing the APK, the /data/data/com.myproject/lib folder contains no libgnustl_shared.so, even though the other libraries are present.
This inevitably leads to the following error:
UnsatisfiedLinkError: Couldn't load gnustl_shared: findLibrary returned null
As a sanity check, I ran adb push ./libs/armeabi/libgnustl_shared.so /data/data/com.myproject/lib and sure enough, the application starts as expected.
I don't see anything in the build log or Eclipse console that suggests there were any issues building or installing the app.
What could be preventing libgnustl_shared.so from being installed with my application?
Where can I go to learn about what happens when an APK is installed?
Please let me know in a comment if there's any specific information I can provide that might help.
I think that, in your JNI project's Android.mk file, most probably, when you build libmystuff.so, you're referencing libgnustl_shared.so like:
LOCAL_LDLIBS += -lgnustl_shared
Maybe you can try to add it as a module (NDK works really focused on modules), something like:
include $(CLEAR_VARS)
LOCAL_MODULE := gnustl_shared
LOCAL_SRC_FILES := libgnustl_shared.so
include $(PREBUILT_SHARED_LIBRARY)
and (in the section you're building libmystuff.so):
LOCAL_SHARED_LIBRARIES := gnustl_shared
And check if it's finally copied
I think your libgnustl_shared.so need under /armeabi-v7a not under /armeabi
Please try copy libgnustl_shared.so to /armeabi-v7a
Look at the answer here: How to link any library in ndk application
The problem is most likely in your Android.mk file. You should have a line like the one on the bottom:
include $(BUILD_SHARED_LIBRARY)
If not, then you're not including your shared library.

Dalvik is looking for .so file with '.0' extension - why?

I have started developing a very simple Android application that consists of three parts:
the Java application itself
a pre-built shared library (we'll call it libfoo)
another shared library that uses the pre-built library (we'll call it libfoowrapper)
The file system looks something like this:
jni
Android.mk
libfoo.so
foowrapper.c
The Android.mk file contains the following contents:
LOCAL_PATH := $(call my-dir)
#==============================
include $(CLEAR_VARS)
LOCAL_MODULE := foo-prebuilt
LOCAL_SRC_FILES := libfoo.so
include $(PREBUILT_SHARED_LIBRARY)
#=========================
include $(CLEAR_VARS)
LOCAL_MODULE := foowrapper
LOCAL_SRC_FILES := foowrapper.c
LOCAL_SHARED_LIBRARIES := foo-prebuilt
include $(BUILD_SHARED_LIBRARY)
When I build the application in Eclipse, things seem to work fine - no errors are reported. However, when I upload the application to my Samsung Discover (running Android 4.0.4), I get the following error in the log:
03-05 21:20:27.859: E/AndroidRuntime(20324): Caused by: java.lang.UnsatisfiedLinkError: Cannot load library: link_image[1936]: 102 could not load needed library 'libfoo.so.0' for 'libfoowrapper.so' (load_library[1091]: Library 'libfoo.so.0' not found)
Why is the Dalvik looking for a .so.0 file instead of a .so file? What changes do I need to make to my app to get rid of this error?
At least in the Linux world, every shared library has a special name called the soname. The soname has the prefix lib, the name of the library, the phrase .so, followed by a period and a version number that is incremented whenever the interface changes (as a special exception, the lowest-level C libraries don't start with lib). A fully-qualified soname includes as a prefix the directory it's in; on a working system a fully-qualified soname is simply a symbolic link to the shared library's real name.
Every shared library also has a real name, which is the filename containing the actual library code. The real name adds to the soname a period, a minor number, another period, and the release number. The last period and release number are optional. The minor number and release number support configuration control by letting you know exactly what version(s) of the library are installed. Note that these numbers might not be the same as the numbers used to describe the library in documentation, although that does make things easier.
Reference: Linux Standard Base
Edit:
It seems this is not an uncommon problem, haven't seen any real solutions to it, but perhaps this will get you started to finding something that works for you.
Problem with LOCAL_SRC_FILES when using PREBUILT_SHARED_LIBRARY
https://groups.google.com/forum/#!topic/android-ndk/_UhNpRJlA1k
Creating non-versioned shared libraries for android
http://www.opengis.ch/2011/11/23/creating-non-versioned-shared-libraries-for-android/
Library 'libproj.so.0' not found
https://groups.google.com/forum/?fromgroups=#!topic/android-ndk/ai3tu0XXs88

android using external shared library

I am facing issues in using an external shared library in my Android application. I created an Android.mk file as given below:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := MyApp
LOCAL_SRC_FILES := myexternallib.so
include $(PREBUILT_SHARED_LIBRARY)
Using ndk-build I am able to generate a local native library and I use this native library in my System.loadLibrary method.
When I run the application I get an error java.lang.UnsatisfiedLinkError: Cannot load library: reloc_library[1486]: 2659 unknown reloc type 19 # ( 4220)
On further search I found a link which recommends to build the shared library using the android toolchain. So I used one of the toolchain arm-eabi-gcc, which is available in the prebuilt/linux_x86/toolchain/arm-eabi-4.4.3/bin directory of the android source code, to build my source files. I get an error arm-eabi-gcc: error trying to exec 'cc1': execvp: No such file or directory. I also noticed that the toolchain folder does not have a file named cc1.
Am I following the right procedure? Is there some other way to reference external shared library in Android code?
It is true that you should use Android toolchain.
Android NDK comes with detailed instructions on using its toolcahin: http://source-android.frandroid.com/ndk/docs/STANDALONE-TOOLCHAIN.html. If you have specific questions about this document, feel free to ask.

Categories

Resources