Develop/Compile a lib for an android project - android

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)

Related

Correct way of referencing external header/source files with Android.mk

i'm making a 3D app that needs the GLM lib. My NDK directory contains the GLM lib source code so I try to link it by using :
LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../../../../Android/SDK/ndk-bundle/sources/third_party/vulkan/src/libs
I wanted to do :
LOCAL_C_INCLUDES += Android/SDK/ndk-bundle/sources/third_party/vulkan/src/libs
I found on the Android doc that LOCAL_C_INCLUDES was relative to the NDK root.
link
The documentation is a bit confusing, it mentions the root directory of the NDK but gives an example with the local directory of the app (where your native modules go).
My questions are :
Is there a correct way to reference external files (cpp/hpp) from my
application using Android.mk
Do I have to use all the ../ to keep
relative pathing ?
Do I have to copy all the GLM files into a libs
folder in my application ?
Thank you in advance,
The NDK test for the validation layers shows how to import them: https://android.googlesource.com/platform/ndk/+/ccb50936470af0c6ccf35bc463a0723b637fd1cd/tests/build/vulkan_layers/jni/Android.mk#12
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := vulkan
LOCAL_SRC_FILES := instance.cpp
LOCAL_CFLAGS := -std=c++11 -DVK_PROTOTYPES
LOCAL_LDLIBS := -lvulkan
LOCAL_STATIC_LIBRARIES := shaderc glslang
include $(BUILD_EXECUTABLE)
$(call import-module,third_party/shaderc)
$(call import-module,third_party/vulkan/src/build-android/jni)

Android NDK - Additional Include Directories

I am using the Android NDK to build a shared library. I have include a snippet from my Android.mk file that is causing me a few issues.
LOCAL_PATH := $(call my-dir)
..#other module here
..#other module here
include $(CLEAR_VARS)
LOCAL_MODULE := spatialite
LOCAL_C_INCLUDES := ../../../projects/externalappsdk/include
LOCAL_SRC_FILES := sqlite3.c \
spatialite.c
include $(BUILD_SHARED_LIBRARY)
My spatialite.c file includes some header files that are located in a folder that is external to the application project folder. I have included that folder in LOCAL_C_INCLUDES as shown above, but on running ndk-build, it still cannot locate these includes. What is the correct way of allowing the ndk-build command to identify where these includes are located. Any help will be greatly appreaciated.
UPDATE:
I wanted to add that spatialite itself need not be visible to the Java layer. I will thereafter be building another module which uses spatialite. I am not sure if this makes a difference to the way I declare the module on the Android.mk file.
The compiler output is shown below:
jni/spatialite.c:102:20: fatal error: geos_c.h: No such file or directory
#include
The .h file that is being imported in spatialite.c is located at C:/projects/externalappsdk/include. The spatialite.c and Android.mk are located at C:/mobile/myandroidproject/jni/
The include directive within my spatialite.c file is shown below:
#ifndef OMIT_GEOS /* including GEOS */
#include <geos_c.h>
#endif
ANSWER:
I managed to get this working using help from the answers provided by Chris which I have accepted. However, I had to make one change to the Android.mk file as is shown below:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := spatialite
LOCAL_C_INCLUDES := ../../projects/externalappsdk/include
LOCAL_SRC_FILES := sqlite3.c \
spatialite.c
include $(BUILD_SHARED_LIBRARY)
Note, that the LOCAL_C_INCLUDES goes two levels back instead of three.
Without a
LOCAL_PATH := $(call my-dir)
At the top of the Android.mk, I was unable to build a replica of your project as described, however the error was different than your report - without that directive the compiler was searching for the C source files in an NDK system directory rather in the jni/ folder.
$ cd mobile/myandroidproject/jni
$ ndk-build
Compile thumb : spatialite <= spatialite.c
SharedLibrary : libspatialite.so
Install : libspatialite.so => libs/armeabi/libspatialite.so
File: ./mobile/myandroidproject/jni/Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := spatialite
LOCAL_C_INCLUDES := ../../../projects/externalappsdk/include
LOCAL_SRC_FILES := sqlite3.c \
spatialite.c
include $(BUILD_SHARED_LIBRARY)
File: ./mobile/myandroidproject/jni/spatialite.c
#include <geos_c.h>
File: ./mobile/myandroidproject/jni/sqlite3.c
//empty file
File: ./projects/externalappsdk/include/geos_c.h
//empty file
At minimum you should add the LOCAL_PATH line to your Android.mk
If that does not solve the problem, then please update your question with any differences between your project structure and my recreation of it.
Use LOCAL_EXPORT_C_INCLUDE_DIRS instead of LOCAL_C_INCLUDES

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

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

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)

Avoiding redundant build to make tessaract android library && link tessaract library to c++ NDK

Now I am making an application using on MacOSx with Tessaract and Android NDK.
I use Eclipse as an IDE to develop the program.
I have two questions to ask:
1). I set up tessaract using the most famous example "tess-two" and modified a bit to fit with my existing code. I copied folder "com_googlecode_leptonica_android" and "com_googlecode_tessaract_android" to /jni folder. Then edit Android.mk for setting path to those library folder. Everything works fine! Except one thing.. Every time that I build the project, I need to build both "leptonica" and "tessaract" library again and again..in order to get libtess and liblept.. It takes soooo long. How can I edit android makefile (Android.mk) not to build those libraries.. just compile my code only... thats all.. Here is my Android.mk
LOCAL_PATH := $(call my-dir)
MY_PATH := $(LOCAL_PATH)
TESSERACT_PATH := $(call my-dir)/com_googlecode_tesseract_android
LEPTONICA_PATH := $(call my-dir)/com_googlecode_leptonica_android
include $(call all-subdir-makefiles)
include $(CLEAR_VARS)
include /Applications/eclipse-android/OpenCV-2.4.3-android-sdk/sdk/native/jni/OpenCV.mk
LOCAL_PATH := $(MY_PATH)
LOCAL_MODULE := my_project
LOCAL_SRC_FILES := cppmain.cpp
LOCAL_LDLIBS += -llog -ldl
include $(BUILD_SHARED_LIBRARY)
)
2). I found a lot of examples about using tessaract with Android. However most of them using tessaract with Java (call via JNI) and call JNI from java code (Java -> Tessaract C++ JNI -> Tessaract C++). I cannot find any example that call tessaract from c++ NDK (Java -> my JNI -> my C++ -> Tessract C++). The reason that I want to call tessaract directly from c++ is portability.
Use PREBUILT_STATIC_LIBRARY, something like
LOCAL_PATH = $(MY_PATH)/com_googlecode_tesseract_android/lib
include $(CLEAR_VARS)
LOCAL_MODULE := tesseract
LOCAL_SRC_FILES := libtesseract.a
include $(PREBUILT_STATIC_LIBRARY)
LOCAL_PATH = $(MY_PATH)/com_googlecode_leptonica_android/lib
include $(CLEAR_VARS)
LOCAL_MODULE := leptonica
LOCAL_SRC_FILES := libleptonica.a
include $(PREBUILT_STATIC_LIBRARY)
LOCAL_PATH := $(MY_PATH)
LOCAL_MODULE := my_project
LOCAL_SRC_FILES := cppmain.cpp
LOCAL_LDLIBS += -llog -ldl
LOCAL_LDFLAGS += -ltesseract -lleptonica
include $(BUILD_SHARED_LIBRARY)
The tesseract project does not contain prebuilt libraries, but if you follow the official instructions, these libraries will be built. Using PREBUILT_STATIC_LIBRARY only helps you to avoid unnecessary rebuilds of these libraries all the time. Same approach is recommended for libjpeg and libpng, as long as you don't change these libraries yourself.

Categories

Resources