NDK: using user created .so when trying to build another .so - android

I'm trying to link some .so that I generated using the NDK to a new .so I'm trying to create,
as the old .so contains definitions of functions that I want to use in the new .so.
I've tried this Android.mk :
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := prog_test
LOCAL_SRC_FILES := main.c
LOCAL_MODULE_TAGS := optional
LOCAL_SHARED_LIBRARIES += mylib
include $(BUILD_SHARED_LIBRARY)
$(call import-module,<tag>) # with and without
I've also tried this method I found in stackoverflow NDK - How to use a generated .so library in another project but still no succes as I get always :
prebuilt/linux-x86/toolchain/arm-linux-androideabi-4.4.x/bin/../lib/gcc/arm-linux-androideabi/4.4.3/../../../../arm-linux-androideabi/bin/ld: error: cannot find -lmylib.so
I really appreciate any help to solve this issue.
B.R

you have to use include $(PREBUILD_SHARED_LIBRARY) instead of include $(BUILD_SHARED_LIBRARY)

Related

Develop/Compile a lib for an android project

I have some cpp files in a directory (10 cpp files and ten relatives .h files corresponding to 10 classes).
I would like to create my own library with them (let call it libTest.a) in order to put it on an android project using NDK.
I have already :
C++ code
Create and configure the android project with NDK, so basically I have an Android.mk and a cpp file into the jni folder
I spent about 10 hours on the web trying to find someone who can explain how to compile its own lib.a
I found a lot about "how can I put a .a in an android project using ndk" but nothing about how to create a makefile, a config file or whatever in order to correctly compile and make a lib compatible with android.
The one who will give me some advices will made my day!
Thanks a lot
(My Android.mk below)
LOCAL_PATH := $(call my-dir)
# static library info
LOCAL_MODULE := libTest
LOCAL_SRC_FILES := ../prebuild/libTest.a
LOCAL_EXPORT_C_INCLUDES := ../prebuild/include
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_C_INCLUDES += ../prebuild/include
LOCAL_MODULE := mlaudioengine
LOCAL_SRC_FILES := mlaudioengine.cpp
LOCAL_STATIC_LIBRARIES := libTest
include $(BUILD_SHARED_LIBRARY)

Android makefile can't find libs because of extra LOCAL_PATH in path

So I've been scratching my head for quite some time with this: basically, I have two Android makefile, one in my jni folder, and one in another folder that contains my native c++ code.
Thing is, for the following makefile,
LOCAL_PATH := $(call my-dir)
GENERATED_PATH := $(LOCAL_PATH)/../../generated/release/api/Android
############################ Includes ############################
#------------------------------------------------------------------ Assimp
LOCAL_MODULE := Assimp
LOCAL_EXPORT_C_INCLUDES := $(GENERATED_PATH)/assimp/include
LOCAL_SRC_FILES := $(GENERATED_PATH)/assimp/lib/libassimp.a
include $(PREBUILT_STATIC_LIBRARY)
# More Libraries included....
#....
I get the following error:
Android NDK: ERROR:jni/../../../appCommon/Android.mk:Assimp: LOCAL_SRC_FILES points to a missing file
Android NDK: Check that jni/../../../appCommon/jni/../../../appCommon/../../generated/release/api/Android/assimp/lib/libassimp.a exists or that its path is correct
What bugs me is that there's twice the LOCAL_PATH in the path where the ndk searches for the library. I've already read about a few cases like this one (like using the notdir macro) but couldn't find a satisfying solution.
How can I specify correctly (and not manually) the correct directory ?
So it turns out that the problem stems from the PREBUILT_STATIC_LIBRARY script, which looks for the lib in the following path: $(LOCAL_PATH)/$(LOCAL_SRC_FILES)
Thus, a simple workaround that worked is to have separate variables for the directories, like that:
GENERATED_PATH := ../../generated/release/api/Android
GENERATED_INCLUDE_PATH := $(LOCAL_PATH)/$(GENERATED_PATH)
and then use them like that:
LOCAL_MODULE := Assimp
LOCAL_EXPORT_C_INCLUDES := $(GENERATED_INCLUDE_PATH)/assimp/include
LOCAL_SRC_FILES := $(GENERATED_PATH)/assimp/lib/libassimp.a
include $(PREBUILT_STATIC_LIBRARY)

Adding libxml support to android ndk project

Good Day everyone. Still trying to figure out what's wrong with adding xml library.(Previos thread Cannot find libxml2 in android ndk project)
In jni folder: i jave prebuild libxml.so, which i successfully builded, android.mk and start-spice.c. Start-spice.c needs libxml in order to work.
Android.mk:
include $(CLEAR_VARS)
LOCAL_MODULE := libxml
LOCAL_SRC_FILES :=libxml.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := start-spice
LOCAL_SRC_FILES := start-spice.c
LOCAL_LDLIBS := -lxml
LOCAL_SHARED_LIBRARIES= xml
include $(BUILD_SHARED_LIBRARY)
And still it says that cannot find libxml/parser.h
Maybe someone could tell me what's wrong?
The think is that in .ci use libxml methods from linux and here i downloaded libxml2 and builded it - is there any difference?
Are you remembering to add the .h directories of libxml to the list of include directories for the other modules? I don't see any -I flags or LOCAL_C_INCLUDES being set

Native method not found while using .so File in libs Android

I have .so file which i have created using a c library .Now i want to use .so file in another project for call those functions. I don't know how to use that library. How to call any function from that library? I have tried but found error as Native method not found.I am a beginner with Ndk in android.any help on this..??
I have referred many links those were not solved my problem as
Native method not found,
java.lang.UnsatisfiedLinkError: Native method not found,
I am facing the same as this link but it is unanswered. link is
Need NDK Help: How to call a C++ function for shared library from another project that uses C++
My Android.mk file is as follows from which i have created .so file
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := ShairportSample
LOCAL_SRC_FILES := ShairportSample.cpp
APP_PLATFORM := android-19
include $(BUILD_SHARED_LIBRARY)
you can call functions implemented inside the .so you want to reuse from another NDK lib, by setting it as prebuilt shared library your're depending on inside your Android.mk file:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := ShairportSample
LOCAL_SRC_FILES := libs/$(TARGET_CPU_ABI)/libShairportSample.so
LOCAL_EXPORT_C_INCLUDES := PATH_TO_ShairportSample.h
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := yournewlib
LOCAL_SRC_FILES := yournewlib.cpp
LOCAL_SHARED_LIBRARIES += ShairportSample
include $(BUILD_SHARED_LIBRARY)
From your Java code you'll have to load ShairportSample lib from your Java before loading yournewlib.
Otherwise, if you want to reuse your .so directly from Java, you should export a Java library (.jar) that uses it. Then you can reuse this Java lib from your other project.
first of all, you should make sure the .so file being compiled correctly, named it like this libYourLibName.so, put it into libs/armeabi folder.
secondly, make sure you have loaded the .so file from static block
static {
System.loadLibrary("YourLibName");
}
may this will help you

Use external static library in application (NDK)

I have recently started working with NDK and am stuck with a problem. I basically want to use an external static library (.so) into my application. Here's what I've tried till now.
Create a library
1) Add a method in the Java class with native keyword
public native static void FibNR ();
2) In the terminal navigate to the project folder and run the following command
mkdir jni
javah -jni -classpath bin/classes/ -d jni/ com.example.fibonaccinative.FibLib
3) Refresh project and add a C file corresponding to the generated H file.
4) Create a Android.mk file in the JNI folder and add the following code in it
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
OPENCV_LIB_TYPE :=STATIC
LOCAL_SRC_FILES := com_example_fibonaccinative_FibLib.c
LOCAL_MODULE := com_example_fibonaccinative_FibLib
include $(BUILD_SHARED_LIBRARY)
5) Build the code using the following command
/Developer/android-ndk-r9b/ndk-build all
The above steps execute successfully and I'm able to view the results of the c code also. Now I want to create a new application and use the generated .so file (com_example_fibonaccinative_FibLib.so) into it. For this I do the following
Use the library
follow steps 1, 2 and 3 from above for the new application
4) Create a Android.mk file in the JNI folder and add the following code in it
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
OPENCV_LIB_TYPE :=STATIC
LOCAL_SRC_FILES := com_example_usingstaticlibrary_LibraryTest.c
LOCAL_MODULE := com_example_usingstaticlibrary_LibraryTest
LOCAL_SHARED_LIBRARIES :=libcom_example_fibonaccinative_FibLib.so
LOCAL_LDLIBS := -L$(SYSROOT)/usr -llog
include $(BUILD_SHARED_LIBRARY)
5) Build the code using the following command
/Developer/android-ndk-r9b/ndk-build all
I'm not sure what to do next. What I think is I need to call the function of the library into com_example_usingstaticlibrary_LibraryTest.c. But doing so gives me an error saying
'com_example_fibonaccinative_FibLib' undeclared
EDIT 1:
1) In project 2 (where I want to use the Prebuilt Shared Library (.so)) I copied the library into the 'jni' folder
2) Changed the Android.mk file with the below text.
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := libcom_example_fibonaccinative_FibLib
LOCAL_SRC_FILES := libcom_example_fibonaccinative_FibLib.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := com_example_usingstaticlibrary_LibraryTest
LOCAL_SHARED_LIBRARIES := libcom_example_fibonaccinative_FibLib
LOCAL_SRC_FILES := com_example_usingstaticlibrary_LibraryTest.c
include $(BUILD_SHARED_LIBRARY)
3) Added the .h file from the old project (com_example_fibonaccinative_FibLib.h) into the 'jni' folder
4) Changed the source of com_example_usingstaticlibrary_LibraryTest.c to
#include "com_example_usingstaticlibrary_LibraryTest.h"
#include "com_example_fibonaccinative_FibLib.h"
JNIEXPORT jlong JNICALL Java_com_example_usingstaticlibrary_LibraryTest_callLibraryFunction
(JNIEnv *env, jclass class) {
Java_com_example_fibonaccinative_FibLib_fibNR(env, class, 500l);
return -500l;
}
Clean/Build results into the following error
undefined reference to 'Java_com_example_fibonaccinative_FibLib_fibNR'
Edit 2:
With reference to this I've edited the Android.mk as follows
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := com_example_fibonaccinative_FibLib
LOCAL_SRC_FILES := libcom_example_fibonaccinative_FibLib.so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := com_example_usingstaticlibrary_LibraryTest
LOCAL_SRC_FILES := com_example_usingstaticlibrary_LibraryTest.c
LOCAL_SHARED_LIBRARIES := com_example_fibonaccinative_FibLib
include $(BUILD_SHARED_LIBRARY)
The NDK build command compiles the code without error. When trying to load the library it gives the following error
Exception Ljava/lang/UnsatisfiedLinkError; thrown while initializing Lcom/example/usingstaticlibrary/LibraryTest
When I remove LOCAL_SHARED_LIBRARIES := com_example_fibonaccinative_FibLib it works fine but I cannot use any function of the Prebuilt shared library.
Edit 3:
I tried a few more things including the suggestion by #jcm but nothing worked. I'm now attaching the source code. It has both the projects (Cleaned version to reduce size).
FibonacciNative: Contains the first project.
UsingStaticLibrary: Contains the second project. I intend to use the Prebuilt Shared Library of the first project into the second one.
You say you want to include a precompiled static library .a, but the file you reference is a shared library .so. If you still want to include a static library, here comes the solution and explanation:
LOCAL_SHARED_LIBRARIES :=libcom_example_fibonaccinative_FibLib.so
You're trying to include the static library as a shared one, looks like an accidental slip from using the previous shared library entry as reference :).
Upon that, Android makefiles still requires you to actually make a module for the external library.
include $(CLEAR_VARS)
LOCAL_MODULE := com_example_fibonaccinative_FibLib
LOCAL_SRC_FILES := com_example_fibonaccinative_FibLib.a
include $(PREBUILT_STATIC_LIBRARY)
Then you can simply add it as a dependency:
LOCAL_STATIC_LIBRARIES := com_example_fibonaccinative_FibLib
But if you're actually trying to include an external shared library. You would need to change the above to the following:
include $(CLEAR_VARS)
LOCAL_MODULE := com_example_fibonaccinative_FibLib
LOCAL_SRC_FILES := com_example_fibonaccinative_FibLib.so
include $(PREBUILT_SHARED_LIBRARY)
and include it as a shared library.
LOCAL_SHARED_LIBRARIES := com_example_fibonaccinative_FibLib
Hope I helped!
Disclaimer: I have not actually tried to compile an example, simply referencing my knowledge and quick research.
References:
Android NDK: Static library used is different than precompiled library specified
As you're including libcom_example_fibonaccinative_FibLib.so as LibraryTest's shared library, in your java static method, you should load it before loading LibraryTest:
System.loadlibrary(com_example_fibonaccinative_FibLib);
System.loadLibrary(LibraryTest);
Update:
After checking your code, LibraryTest.java should look like:
package com.kochartech.usingstaticlibrary;
public class LibraryTest {
public native static long callLibraryFunction();
static {
System.loadLibrary("com_kochartech_fibonaccinative_FibLib");
System.loadLibrary("com_kochartech_usingstaticlibrary_LibraryTest");
}
}

Categories

Resources