Linking with native SO file present in included library project of Android - android

I am working on a project in which it has dependency on another library project. Library project has both java files and native SO files.
Accessing JAVA source files (APIs) from the Android project java source doesn't have any problem. But, my native code is dependent on native SO files present in the included library project of android as well.
Library Project Android Project
--------------- ---------------
src/Java files <-- Java files
libs/.so files <-- libs/.so files
.so files are part of the included library project. How can my current Android project native code try to use .so files of the included library project. Currently I am getting linking error of undefined reference to all the functions which are part of the library/libs/.so files.
Please let me know if any one has faced/resolved similar type of issue.

You probably have both projects imported into your Eclipse. But ndk-build knows nothing about Eclipse. If the library comes with its own .mk file that defines PREBUILT_SHARED_LIBRARY, it would be even better. One such example is OpenCV which includes sdk/native/jni/OpenCV.mk file.
But you can simply add path to the .so files to your Android.mk, e.g. put the following lines in the end of your file:
include $(CLEAR_VARS)
LOCAL_MODULE:=LibraryProjectSO
LOCAL_SRC_FILES:=/LibraryProject/libs/library.so
include $(PREBUILT_SHARED_LIBRARY)
Now you can add LibraryProjectSO to the list of LOCAL_SHARED_LIBRARIES.

Related

Missing opencv core .so library in .aar

I'm currently trying to compile OpenCV using Gradle and integrate it within my Android project, but I'm facing an issue and I don't know how to resolve it.
I have created a native library module within my project and created a few gradle tasks for downloading and unzipping the source code within the project. Then, using the CMakeLists.txt file provided in the OpenCV project, I import it using "add_subdirectory" within my application CMakeList.txt file.
With this, the OpenCV compilation complete correctly and generates the two required libraries, libopencv_core.so and libopencv_imgproc.so in the .cxx/RELEASE/buildHash/arm64-v8a/opencv/lib/arm64-v8a/ folder
However, only my own application .so library and the libopencv_imgproc.so are included in the final .aar file. The libopencv_core.so is missing. If I check in the Gradle build folder, located in build/intermediates/cxx/RELEASE/buildHash/obj/arm64-v8a/, I can see the same issue as in the .aar.
The funny thing is, if I only require to use the libopencv_core.so, it will be integrated within the final .aar correctly, and I don't understand why.
Here is my CMakeList.txt file:
cmake_minimum_required(VERSION 3.18.1)
project("myapp")
add_library(
myapp
SHARED
myapp.cpp )
find_library(
log-lib
log )
# OpenCV source code and CMakeList.txt are located in the opencv folder
add_subdirectory(opencv)
# Library opencv_core and opencv_imgproc are generated by the OpenCV CMakeList.txt
target_link_libraries(myapp opencv_core opencv_imgproc ${log-lib} )
target_include_directories(myapp PUBLIC
opencv/modules/core/include
opencv/modules/imgproc/include
)
include_directories (${CMAKE_BINARY_DIR})
My question is, what am I missing ? Is there something I must specify to force the inclusion of the libopencv_core.so ?
PS: Why I'm not simply integrating the binaries instead of compiling them ? Because the app is targeted for F-Droid, which requires to whole code to be compiled from the sources, so this is not an option for me.
I have finally managed to copy the libopencv_core.so in the correct folder and generate a complete aar.
I just had to add the following to my application CMakeLists.txt:
set_target_properties( opencv_core PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} )
I don't really get why I must add this line, but it's working !

How to include a C++ project in my own in Android

as per the title i want to include a C++ project in my own project in Android Studio.
I tried copying all the files in my /cpp folder and manually including them into my MakeList.txt, but i got numerous compilation errors, because some system library is missing (such as files).
The project i would to include is this.
Is there a method to include it in my app?

Android Eclipse: How to reference library project's NDK library from another project?

I have an Android Eclipse library project "Lib" that contains both Java and C code built with the NDK. I have another project "App", which is dependant on Lib. App also contains both Java and C. My goal is to have multiple Eclipse App-like projects which each use the Lib project.
A Java routine in App calls a Java routine in Lib which calls C code in Lib. This compiles, links, and runs perfectly on the device.
Now I want to add a call from the C code in App to the C code in Lib. My First problem is header files. I need to include a header file, jni/lib-jni,h, from the Lib project:
#include "lib-jni.h"
in a .c file in App. For this #include to work I believe I need to add Lib's jni/ directory to LOCAL_C_INCLUDES in App's jni/Android.mk. I do not want to hard-code this path, I would like to get it from Eclipse if possible. After all, I've told Eclipse that the App project depends on the Lib project and Eclipse knows how to connect Java calls between the two.
I temporarily kludged around the first problem by copying lib-jni.h from Lib's jni/ directory to App's jni/ directory. Now App's C code compiles, but it won't link; it gets an undefined. In App's Android.mk I need to tell the C linker to link against libLib.so. I tried putting -lLib on LOCAL_LDLIBS, but that didn't work. libLib.so is in the Lib project in Lib/libs/armeabi/libLib.so. Eclipse knows to incorporate this .so into the .apk file it builds for App.
Is there a way to cleanly solve these two problems?
Add Lib's jni/ directory to App's LOCAL_C_INCLUDES
Add a reference to libLIb.so to App's LOCAL_LDLIBS
I phrased these problems in terms of possible solutions. I'm open to any solution. For example, if using LOCAL_LDLIBS the wrong way to go, what is the right way?
Note: Because App and Lib are two separate Eclipse projects built at separate times I am pretty sure I can not use LOCAL_EXPORT_C_INCLUDES in Lib's Android.mk to make Lib's jni/ directory available to App's Anroid.mk - I tried it didn't work. But I'm prepared to be educated.
I always set the LOCAL_C_INCLUDES to the original lib, so I think that is not that bad idea. An other solution is to include the external library as a static library in your libs folder, but I'm not sure if it will work.

How to add a new .cpp file to, and then build, a c++ library for Android?

I'm making a Unity3d plugin for this c++ library for Android. Ive gotten it to work in windows by opening the visual studio project the library makers provided, adding a new .cpp file to it with my API code and building to a dll.
I'm wondering now how I can add this new .cpp file to the library and build it for Android.
So far I have installed the Android sdk and ndk on a machine with ubuntu and successfully built the original library using ndk-build (as per these instructions)
I'm guessing it is not as simple as copying my .cpp file into the folder and building as there are AndroidManifest.xml files and so on.
The AndroidManifest.xml file is not pertinent for an NDK build.
You will need to find the appropriate Android.mk file. You may need to add the file name into the LOCAL_SRC_FILES in that make file, although they may have it set up to compile all the .cpp files in the directory or something more intelligent along those lines. It is, after all, a regular make file.
See here for info on the Android.mk file specifics.
Edit:
I suppose I should add that it would be the LOCAL_SRC_FILES preceding the relevant include $(BUILD_SHARED_LIBRARY) for the library you intend to build. Each make file may contain an arbitrary number of targets, although in the simplest case it's usually one make file to build a library.

Creating a product SDK: How do I add a native lib (.so) and a jar with the SDK I am creating?

I am creating a widget that we will provide to developer end users and it consists of a .jar and a native library (.so) built using the NDK. The JAR has a JNI interface to the dynamic library.
It's very clear on how to include an external .jar in a project but not how to include a dependent dynamic library.
How do I package up and build the .jar and .so? What are the best practices here?
I can create the JAR file using the JDK's jar command. Do I need to run dx.bat on the jar to convert to Dalvik bytecode?
I need to create a sample project showing the widget in action. How do I include this .jar and .so in a sample project that demonstrates how to use the widget?
I spent some time on this, and i just can't understand why isn't this written on wikitude documentation.... anyway follow this changes!
go to windows/preferences/android/build
uncheck the first and the second option
extract files from wikitudesdk.jar with winrar as if it is an archive, search libarchitect.so and copy it in /libs/libs/armeabi/
add wikitudesdk.jar to your build path
You should use the standard build tools included with the SDK for this. If you include the .jar files you need in the /lib directory of your project, the ant build process will convert the included class files to Dalvik bytecode format and include them in your classes.dex file for the app. Add a build.properties file to your project root as well, with one line:
external.libs.dir=lib
Depending on the version of your SDK and configuration of it, you may need to place the jar in libs rather than lib.
As for the .so, I presume that it's properly compiled using the Android NDK, or using a build script that uses the proper compiler and compiler flags that are required to successfully link the shared object on Android. If this is the case, you can include the .so file in libs/armeabi and they will be added in the jar as well. Furthermore, the dynamic library loader will know to look in this location in the .jar when you actually try to load the library from Java code.
Using ADT 12, I accomplished this by doing the following:
1) Export JAR from your library with the SO file using Eclipse. Make sure you exclude AndroidManifest.xml. This will include source code and other data, so if you are distributing, you'll want to strip these unnecessary bits out using any ZIP utility.
2) Create a directory in your App's source tree (I use "lib" directory) and copy your library JAR to it.
3) Right-click project in Eclipse and select "Configure Build Path". Add JAR and point it to JAR inside your App source tree.
4) In your Eclipse preferences, select Android/Build section and uncheck "Automatically refresh Resources and Assets folder on build". You will notice an option below that says "Force error when external jars contain native libraries." There is an ADT bug, which will supposedly be fixed in R17, which uses the wrong setting. Once it is fixed, you will use the "Force error" one (make sure it unchecked).
5) Once you build your app APK, you will have a libs/armeabi/libXXXX.so file. This will not be automatically unpacked on install. You will need to write code to extract it from your APK file into your data directory, then use System.load on the .so file in your data directory.
I have bidirectional JNI calls going from the dynamically loaded file, and even use dlopen() on it to do my custom plugin registration stuff.
Add the below lines to android.mk.
include $(BUILD_PACKAGE)
LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := alias:libs/your.jar
include $(BUILD_MULTI_PREBUILT)

Categories

Resources