Android : link prebuilt shared library (.so) within jar file in NDK - android

I've a static java library compiled as a jar file.
This jar loads a .so library using System.loadLibrary.
Then another Android application project links statically the jar file.
Everything is compiled using an Android.mk file in the NDK...how can I make the shared native library being included and correctly loaded from my final application (and "seen" from the jar code)?

Ok I solved the problem by using these instructions in Android.mk:
$(shell cp $(wildcard $(LOCAL_PATH)/libs/armeabi/*.so) $(TARGET_OUT_INTERMEDIATE_LIBRARIES))
LOCAL_JNI_SHARED_LIBRARIES:= libMyLib
just before
include $(BUILD_PACKAGE)

Related

Call shared library (.so) methods within Android Studios C files

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.

fluidsynth library file compilation to .so file in android

I am trying to compile the files from https://bitbucket.org/kunstmusik/fluidsynth-android to .so file. The files from this site are .c and .h which have the include files. I have installed ndk, configured it.
I have created a new project in eclipse
created the jni folder and copied the files from the web site to this folder
in command prompt in the jni folder, I issued the command ndk-build NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=./Android.mk. This ran without error
In the /obj/local/ folder, files were created with .o and .d in the fluidsynth-andriod folder. There is also a .a file in armeabi and aremabi-v7a. I assume the .a is a static library. Do I need to create a .so file? Do i need to link the c/c++ to java. If so how do I do this.
Please help...
I was running into this same issue myself. The Android.mk file included in the fluidsynth-android code contains the line
include $(BUILD_STATIC_LIBRARY)
This is what causes the .a files to be generated.
If you change this to
include $(BUILD_SHARED_LIBRARY)
you will get .so files instead of .a files.

SharedLib dependency # Mixed mode APK

I am building a mixed mode Android project, the project is using the native ffmpeg
The Libs are
2.1. libavutil.so -> libavutil.so.51
2.2. libavcodec.so -> libavcodec.so.54
2.3. libavformat.so -> libavformat.so.54
My Java code include the following JNI section to load the native libs:
static {
     System.loadLibrary("avutil");
     System.loadLibrary("avcodec");
     System.loadLibrary("avformat");
}
'libavcodec.so' depends on 'libavutil.so.51' AND NOT on 'libavutil.so'.
When running my activity  System.loadLibrary("avcodec"); excepts with "could not load needed library 'libavutil.so.51' for 'libavcodec.so' (Library 'libavutil.so.51' not found)"
On my Android.mk I have the following section to have the native libs added to the APK:
include $(CLEAR_VARS)
LOCAL_MODULE := mylib
LOCAL_SRC_FILES := ../../../mylib/libmylib.so
include $(PREBUILT_SHARED_LIBRARY)
replacing libmylib.so with libmylib.so.%some number% cause the build to fail with [LOCAL_SRC_FILES should point to a file ending with ".so"]
Having the above in mind, how can I have libavcodec loading w/o the dependency problem ?
Can I fix libavcodec.so dependency to point to libavutil.so and not to libavutil.so.51 ?
Can I change Android.mk so it will be able to pack libavutil.so.51 ( non .SO extention ) ? will it then be loadable using 'System.loadLibrary' ?.
Any help will be appreciated!!!
Nadav at Sophin
Work-around was simply to use the static libs rather than the dynamic libs, this however, is a temporary work-around as due to LGPL limitations the SharedLibs are mandatory for commercial use.

Android native project referencing shared library from c++ library project

I have 2 projects:
1 - Android Native project
2 - C/C++ Project
I'm building my shared library files (.so) in a C/C++ project and want to use those .so files in Android Native project.
I don't want to copy and paste these library files from one project to another.
First of all is it possible to use those .so files from my native Android project by using some reference etc to C++ library project?
Would it be easier to find a way to automatically copy the .so files from the C++ library project to the Android native project?
Well you'll need to re-compile your libs for ARM first. You can use the ndk's "standalone toolchain" functionality for that. There's a doc explaining more about it in the ndk dir (docs/STANDALONE-TOOLCHAIN.html). I needed to use libexpat in a project so I whipped up a bash file to compile expat using the standalone toolchain like so:
NDK_PATH=/android-ndk-r7
NDK_GCC=${NDK_PATH}/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc
export CC="${NDK_GCC} --sysroot=${NDK_PATH}/platforms/android-8/arch-arm"
export CFLAGS='-mthumb'
export LDFLAGS='-Wl,--fix-cortex-a8'
./configure --host=arm-eabi
make
Then you can copy the so wherever you want and reference it from Android.mk:
LOCAL_LDLIBS := \
-Lvendor/expat/sdk/lib/android \
-lexpat
Note that I built expat and linked it statically so I didn't have to worry about copying the resulting so

Eclipse does not create shared library file in the mixed project (NDK and Java)

I have a project in Eclipse which mixes native and Java code using CDT and ADT. It is really simple - demo project, just as in the android-ndk-r7/ samples/hello-jni
My Android.mk (in the /jni folder) is:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_LDLIBS := -llog
LOCAL_MODULE := hlsdrm
LOCAL_SRC_FILES := hlsdrm.cpp
include $(BUILD_SHARED_LIBRARY)
Everything compiles fine, I can load hlsdrm library by
System.loadLibrary("hlsdrm");
and call the native functions. But where is the library file placed? There is no libhlsdrm.so shared library in any of the project folders. As I could read, it should create a folder "libs" and place the resulting library in it.
Also, when I try to list libraries which is used by the application process by calling:
PackageManager pm = getPackageManager();
String applicationPackage = this.getApplicationInfo().packageName;
ApplicationInfo ai = pm.getApplicationInfo(applicationPackage, PackageManager.GET_SHARED_LIBRARY_FILES);
String[] soFiles = ai.sharedLibraryFiles;
then the soFiles variable is empty...
I have tried to specify the library by uses-library value in the application section of the manifest, but after then Android OS refuses to install that application and shows INSTALL_FAILED_MISSING_SHARED_LIBRARY error.
Can anybody explain me how can I get my shared library - the physical .so file?
Why the sharedLibraryFiles is empty even though the library loads and the native method can be called?
How can I install the application that requires custom shared library?
First of all, you should create libs folder and set up your project.
Refer to following article to do that:
http://maxters.net/2011/02/android-ndk-builder-for-eclipse-in-windows/
Regarding the library: it should be installed in /data/data/com.company.yourApp/lib/libhlsdrm.so
Btw: soFiles is not supposed to contain native libraries (.so files), but .jar files. For example if you specify in you manifest <uses-library android:name="com.google.android.maps" /> your soFiles variable will contain /system/framework/com.google.android.maps.jar

Categories

Resources