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.
Related
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.
I'm struggling with this for several days now. At the moment i'm just testing it with a simple C++ project (1 .h & 1 .cpp file) and a minimalistic App including the ndk helloJNI sample code (which worked perfect easily):
Target
Import existing C/C++ files (project) to Android Studio
Approach
After trying out some of the (dozens) of different possibilities, i think/thought the following steps would be the best solution for my purpose:
Create the shared library (Calculator.so) from Visual Studios 2015 "Create shared library for Android" (or something) [successful]
Create jniLibs folder in src/main/ with its subfolders (x86 the relevant one in my case)
Add the Android.mk file in src/main/jniLibs which has to be placed there (?)
Include statement: System.loadLibrary("Calculator") without "lib" and ".so" in MainActivity
The library is listed in Android Studio in its folder jniLibs as like the Android.mk. Moreover if i build the apk, the library is successfully packed (verified by unzipping) and i dont get any errors.
BUT: how can i call the methods in the library? I tried the different solutions offered in other threads, but i think i missed something in my .mk or my steps described above.
Tried
Different #include <myLib> statements in native-lib.cpp, like s
Different Android.mk settings (but i'm new to make files so not even tutorials helped me much with my specific problem ::) )
Other locations for the libCalculator.so like in the subfolder x86
and many others - simply not reminding atm (wasntme)
Your help is highly appreciated!
Android.mk
LOCAL_PATH := $(call my-dir)
APP_ABI := x86
# library info
include $(CLEAR_VARS)
LOCAL_MODULE := Calculator
LOCAL_SRC_FILES := $(TARGET_ARCH_ABI)/Calculator.so
LOCAL_EXPORT_C_INCLUDES := ..../Visual Studio 2015/Projects/SO_Library/SO_Library
include $(BUILD_SHARED_LIBRARY)
There are lots of things, you can do in Android NDK. For example, Camera hardware is one of the heaviest hardware in Android OS. Detecting faces, things, giving effects and for thousands of features NDK is the best.
Some helps for your steps:
You can built and prebuilt shared(.so) and static(.a) libraries in Android Studio also. Not need Visual Studio.
Don't create jniLibs folder in main folder. When you build your project via gradle, it already creates this folder and put your target libraries. If you want prebuilt any libraries, put these libraries in main/jni/libs folder and prebuilt then with Android.mk.
Don't add the Android.mk file in jnilibs folder. Create this file in main/jni folder. Also Application.mk file.
Call your libraries, in any activity, where you need, in static method. Like this:
static { System.loadLibrary("my_library") }
Without "lib" and ".so" extensions.
When you want to call your native methods, just use "native" keyword. For example:
private native int nGetNumberFromNativeSide();
Just call this method, where you want, and get result. But for ndk building in gradle side, look at this answer. For building library in Android.mk, these sample lines maybe help you:
include $(CLEAR_VARS)
ifneq (,$(filter $(TARGET_ARCH_ABI), armeabi-v7a x86 arm64-v8a x86_64))
LOCAL_MODULE := my_library
LOCAL_SRC_FILES := $(LOCAL_SRC_LOCATION)/native1.cpp native2.cpp
include $(BUILD_SHARED_LIBRARY)
You can put name anything you want, but dont add lib and .so extensions. Ndk is already doing it.
I have already gave Android.mk example.
When you build Android.mk file, it locates your libraries appropriate folder. Like main/libs/x86/libmy_library.so.
I guess this answer will help you. If you have more questions, add to comment, i'll edit my answer and add answers.
I've created an Application that works perfectly in Android Studio. If I generate an AAR and APK and use these files they again work fine. I can install the APK on several devices and it works flawlessly. Now when I install the APK inside of an AOSP build I keep getting an java.lang.UnsatisfiedLinkError: which points to the very first line of code that's calling my native method. I used this link as a reference Add .apk files in aosp. When I run the emulator and click my application it crashes and produces that UnsatisfiedLinkError. The same thing happens if I generate an APK using my AAR file. Just to clarify again this only happens in AOSP it does not happen when using the AAR inside Android Studio doing other builds and the APK always works regardless of the device I install it on. Any advice as to why this is happening would be great!
which points to the very first line of code that's calling my native method.
Sounds like you are building your application with native libraries included and the .APK you created has only bundled some architecture types into it. If you have native libraries, make sure to include all architecture types (usually x86 and armv7 does the job, but always consult your compatibility checklist first) and make sure if you do ABI splitting that you are using the right APK.
Please consule the following guide to make sure you have the NDK integration set up correctly.
AOSP was trying to find the .so that my APK uses from either the system/lib or vendor/lib folders and since it wasn't there it was causing the UnsatisfiedLinkError. So by adding the .so object file directory to those locations the APK started up fine inside the emulator after that. This could also be accomplished by modifying the Android.mk as well by adding these lines to the file.
include $(CLEAR_VARS)
LOCAL_MODULE := myfile
LOCAL_SRC_FILES := lib/myfile.so # or wherever your .so is located
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_SUFFIX := .so
LOCAL_MODULE_CLASS := SHARED_LIBRARIES
include $(BUILD_PREBUILT)
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!!!
I just fetched all the source code from AOSP and have recursively copied external/openssl/* to myproject/jni/libopenssl/. Next, I added the following lines in Android.mk:
#build libcrypto.a
include $(CLEAR_VARS)
include $(LOCAL_PATH)/libopenssl/Crypto.mk
...
LOCAL_STATIC_LIBRARIES := libcrypto_static
However, this creates a bunch of errors.
I am wondering if anyone has clear steps to build libcrypto_static from AOSP. I noticed that there are many forks on github for openssl. However, I would prefer to use the one from AOSP as it seems to have optimizations for arm as well as x86. Regards.