Android NDK and .so.X extensions - android

I'm trying to use the Grantlee library in an Android NDK app.
I can compile Grantlee just fine, and I get libGrantlee_Templates.so, libGrantlee_Templates.so.5, and libGrantlee_Templates.so.5.0.0.
Of these three, I can only install the first one in my Android.mk:
include $(CLEAR_VARS)
LOCAL_MODULE := libgrantlee
LOCAL_SRC_FILES := $(GRANTLEE_PATH)/lib/libGrantlee_Templates.so
include $(PREBUILT_SHARED_LIBRARY)
Because if I try to install either of the other two, then I get:
Android NDK: ERROR:Android.mk:grantlee: LOCAL_SRC_FILES should point to a file ending with ".so"
Android NDK: The following file is unsupported: libGrantlee_Templates.so.5
But then, like a cruel joke, the .so.5 that I can't install is exactly the file that it looks for at runtime:
E/AndroidRuntime(14439): java.lang.UnsatisfiedLinkError: dlopen failed: could not load library "libGrantlee_Templates.so.5"; caused by library "libGrantlee_Templates.so.5" not found
How do I solve this?

When you build a native shared library with NDK standalone toolchain, you must change its make files to get rid of .version suffixes. See for example how this is done for ffmpeg.

I had the same problem when using an external library in my project.
You can also add -avoid-version to the libtool command. This trick saved my day...

If the library is built with an autotools/libtool based build system, update the bundled libtool to libtool 2.4.3 or newer. Those versions know how to deal with these details about android shared libraries, so if you build it with --host=arm-linux-androideabi or similar, it won't add any version numbers to the libraries.
To upgrade the libtool version within a source package, run e.g. autogen.sh or a similar script within the source package, or autoreconf -fi, assuming that you've got a new enough version of libtool installed in the surrounding system.

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.

i can't get opencv to work in android

I'm using eclipse to write android programs and i can successfully run them on adt but recently i had to write a program that uses opencv but i can't get opencv to work with android i got ndk and add it to system variables and also downloaded opencv4android sdk from this link: http://docs.opencv.org/doc/tutorials/introduction/android_binary_package/O4A_SDK.html and i imported all the examples now i get numerous error for any of the examples and when i click project->clean->clean all it comes up with following error :
C:\Documentation_Android\android-ndk-r9d-windows-x86_64\android-ndk-r9d\ndk-build.cmd
Android NDK: WARNING:jni/Android.mk:mixed_sample: non-system libraries
in linker flags: -lopencv_java Android NDK: This is likely to
result in incorrect builds. Try using LOCAL_STATIC_LIBRARIES
Android NDK: or LOCAL_SHARED_LIBRARIES instead to list the library
dependencies of the Android NDK: current module
[armeabi-v7a] Install : libmixed_sample.so =>
libs/armeabi-v7a/libmixed_sample.so
I also tried Fix Project Properties but nothing happened and i tried to change jni/Application.mk and change armeabi-v7a to armeabi and that didn't helped too what should i do now ? is there anything I missing here ?
have you added LOCAL_LDLIBS in android.mk file?
LOCAL_LDLIBS := $(LOCAL_PATH)/jniLibs/libmixed_sample.so //path of .so file
OK i found the answer ! How stupid I am ! i just have to go to opencv library project properties in android tab select project build target as android 4.2.2 and everything worked well

Android NDK Include Path In Eclipse

I have an Android NDK project that builds fine in cygwin using ndk-build.
However, I wanted to have it build in eclipse, so I installed C/C++ Development tools into my ADT version of eclipse and added native support to the project in eclipse. However, after building, I get the following error:
fatal error: timer.h: No such file or directory
In my original Android.mk file, I have the following include that lets it work in cygwin:
LOCAL_C_INCLUDES := /cygdrive/c/ADT/includes/
I tried adding a similar include path (C:\ADT\includes) to Project->Properties->C/C++ General->Paths and Symbols, but still no luck. Any suggestions?
The fix was to use windows paths
LOCAL_C_INCLUDES := C:/ADT/includes/
Note that using the following works as well (per cpu2's answer)
LOCAL_CFLAGS := -IC:/ADT/includes/
Add -I/path/to/includes to your cflags.

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.

Android NDK code analysis not using defined variables

I think this problem started when upgrading to the Juno Eclipse. I believe the C/C++ build environment was probably upgraded as well at the same time. The NDK was not upgraded.
We have a large mass of C code that compiles under several platforms. We are using the crystax-ndk (r6) to compile our C++ code. To know when we are compiling for Android, we have defined the following in the Android.mk
LOCAL_CFLAGS := -DANDROID_NDK \
-DDISABLE_IMPORTGL \
...
Then in some files we will include different headers depending upon the platform
#ifdef ANDROID_NDK
...
Our code compiles just fine and seems to run fine. However, when opening certain files the C/C++ code analyzer will find many errors. This appears to be because the analyzer doesn't know about the ANDROID_NDK defined variable.
Any idea why the code analyzer is not using the same #defines as the compiler? The code is almost uneditable with all the bogus errors the analyzer is reporting.
I saw you're comment about the analyzer you were refering to.
Eclipse CDT (C/C++ Development Toolkit) does not support parsing Android.mk yet neither does the NDK plugin add that functionality at the time of writing this.
Possible (ugly/annoying) workaround: Set up a header file setting the defines you are missing and include that header file to all files.
Use LOCAL_CPPFLAGS for C++ files and LOCAL_CFLAGS for C files in your Android.mk

Categories

Resources