ndk-build using amadillo (blas lapack) and vlfeat lib - android-ndk

I am trying to compile c++ code written using armadillo that I have uncomment blas lapack in config.hpp and also vlfeat (vl.so) in Andriod make file.
In Jni folder I have the following Andriod.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
PRODUCT_PACKAGES += \libblas
PRODUCT_PACKAGES += \liblapack
PRODUCT_PACKAGES += \libvl
include $(CLEAR_VARS)
LOCAL_MODULE+=mjni
LOCAL_SRC_FILES+=HelloJNI.cpp
LOCAL_SRC_FILES+=featureExtraction.cpp
LOCAL_C_INCLUDES:=$(LOCAL_PATH)/include
LOCAL_C_INCLUDES+=$(LOCAL_PATH)/include/externalInclude/
LOCAL_C_INCLUDES+=$(LOCAL_PATH)/include/externalInclude/armadillo_bits
#LOCAL_SHARED_LIBRARIES := blas lapack
LOCAL_LDLIBS += -llog -ldl
LOCAL_CPP_FEATURES += exceptions
LOCAL_CPPFLAGS += -fexceptions
include $(BUILD_SHARED_LIBRARY)
for each module blas, lapack, and vlfeat I used .so libraries as follows:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := libvl
MY_LIBRARY_NAME := libvl
### export include path
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/../include/vl
LOCAL_EXPORT_C_INCLUDES += $(LOCAL_PATH)/../include/src
### path to library
LOCAL_SRC_FILES := libvl.so
### export dependency on the library
LOCAL_EXPORT_LDLIBS += -l$(MY_LIBRARY_NAME)
include $(PREBUILT_SHARED_LIBRARY)
and
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := libblas
MY_LIBRARY_NAME := libblas
### export include path
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/../include/OpenBLAS/include
### path to library
LOCAL_SRC_FILES := libblas.so
### export dependency on the library
LOCAL_EXPORT_LDLIBS += -l$(MY_LIBRARY_NAME)
include $(PREBUILT_SHARED_LIBRARY)
I have got the following errors when I use ndk-build command:
jni/include/externalInclude/armadillo_bits/blas_wrapper.hpp:172: error: undefined reference to 'sdot_'
jni/include/externalInclude/armadillo_bits/blas_wrapper.hpp:98: error: undefined reference to 'ssyrk_'
jni/include/externalInclude/armadillo_bits/blas_wrapper.hpp:28: error: undefined reference to 'sgemv_'
jni/include/externalInclude/armadillo_bits/blas_wrapper.hpp:63: error: undefined reference to 'sgemm_'
error: undefined reference to 'vl_sift_new'
error: undefined reference to 'vl_sift_process_first_octave'
error: undefined reference to 'vl_sift_delete'
error: undefined reference to 'vl_sift_detect'
error: undefined reference to 'vl_sift_calc_keypoint_orientations'
error: undefined reference to 'vl_sift_calc_keypoint_descriptor'
error: undefined reference to 'vl_sift_process_next_octave'

i had the same problem and after some struggleing i found a sulotion
go to http://danilogiulianelli.blogspot.co.il/2013/02/how-to-build-gcc-fortran-cross-compiler.html and build the gcc cross compiler . i did it for ndk-8d.
make sure that after running the script you can see the 2 folders that the script created in
android-ndk-r8d\toolchains\arm-linux-androideabi-4.8.0
android-ndk-r8b\android-ndk-r8d\toolchains\x86-4.8.
download blas lib and update the following field in blas make.in:
instead of
FORTRAN = gfortran
FORTRAN = $(yourPath)/android-ndk-r8d/toolchains/x86-4.8.0/prebuilt/linux-x86/bin/i686-linux-android-gfortran
run the makefile.
add in you android.mk and add the following localflags
LOCAL_LDFLAGS := $(OPT) $(PROF) -lblas -llapack -lstdc++ -lgfortran
run ndk-build
i had problem with ndk-8d that had missing files of gcc 4.8, in order to solve it i copied the missing files from ndk-9 and it works.

Related

ndk-build for jsoncpp always giving one error

Pre-requisites : I am using Android Studio 2.1.2
I have downloaded source of jsoncpp from following link
https://github.com/open-source-parsers/jsoncpp
I have already checked following SO thread , not getting proper solutions :
LOCAL_MODULE_FILENAME should not include file extensions i get this error each time i run ndk-build in terminal
Using JsonCpp on X-Cross platform library
My common Android.mk is as follows:
LOCAL_PATH := $(call my-dir)
#JsonCpp lib
include $(CLEAR_VARS)
LOCAL_MODULE := jsoncpplib
include $(LOCAL_PATH)/jsnlib/Android.mk
LOCAL_STATIC_LIBRARIES := jsnlib
LOCAL_LDLIBS += -llog -ldl
include $(BUILD_SHARED_LIBRARY)
With code for building some other libraries too , which is working fine.
My jsoncpp's Android.mk is as follows
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_C_INCLUDES := $(LOCAL_PATH)/jsnlib/include/json/*.h
FILE_LIST += $(wildcard $(LOCAL_PATH)/jsnlib/src/lib_json/*.cpp)
LOCAL_SRC_FILES := $(FILE_LIST:$(LOCAL_PATH)/%=%)
LOCAL_MODULE := jsnlib
LOCAL_MODULE_FILENAME:= libjsnlib
include $(BUILD_STATIC_LIBRARY)
When I do ndk-build always getting following error
Android NDK: jni/jsnlib/Android.mk:jsnlib: LOCAL_MODULE_FILENAME should not include file extensions
Android NDK: jni/jsnlib/Android.mk:jsnlib: LOCAL_MODULE_FILENAME must not contain a file extension
What happens here is that while you're in the middle of defining your jsoncpplib module you include another makefile, which contains its own module definition:
include $(CLEAR_VARS)
LOCAL_MODULE := jsoncpplib
include $(LOCAL_PATH)/jsnlib/Android.mk
LOCAL_STATIC_LIBRARIES := jsnlib
LOCAL_LDLIBS += -llog -ldl
include $(BUILD_SHARED_LIBRARY)
You should move the inclusion of the other makefile to above the where you're doing CLEAR_VARS:
include $(LOCAL_PATH)/jsnlib/Android.mk
include $(CLEAR_VARS)
LOCAL_MODULE := jsoncpplib
LOCAL_STATIC_LIBRARIES := jsnlib
LOCAL_LDLIBS += -llog -ldl
include $(BUILD_SHARED_LIBRARY)
Also, LOCAL_MODULE_FILENAME:= libjsnlib seems redundant, since LOCAL_MODULE := jsnlib should result in the same library name.

Warning : Overriding commands for target Android Makefile

I've got an issue building my C++ code using NDK r9d, since I try to compile C files using C++ compiler (G++) I've got this warnings :
C:/Android/ndk/build/core/build-binary.mk:393: warning: overriding commands for target
C:/Android/ndk/build/core/build-binary.mk:391: warning: ignoring old commands for target
Before I didn't need to compile with C++ 11 and my C files was compiled with GCC, I had no problems, but since I had LOCAL_CPP_EXTENSION := .cpp .c, this warnings appears (only for C files).
I found that someone else had the same problem (Overriding commands for target Android Makefile) but didn't get any answer.
Here is my files :
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
MY_INC_PATH := ../../..
LOCAL_MODULE := test
LOCAL_CFLAGS := -Werror
LOCAL_CPPFLAGS := -std=c++11
LOCAL_LDLIBS := -ldl -llog -lGLESv1_CM
LOCAL_C_INCLUDES := \
$(MY_INC_PATH)
MY_SRC_PATH := ../../../..
LOCAL_CPP_EXTENSION := .cpp .c
LOCAL_SRC_FILES := \
$(MY_SRC_PATH)/XXX.c \
$(MY_SRC_PATH)/YYY.cpp \
$(MY_SRC_PATH)/ZZZ.cpp
include $(BUILD_SHARED_LIBRARY)
I use NDK r9d and compile with G++ 4.8 and C++ 11 activated. Thanks for your help.
As of r9d, NDK does not provide methods to unassociate .c files from C compiler. You can redefine $$(TARGET_CC), and also set LOCAL_CFLAGS += -std=c++11, and not set LOCAL_CPP_EXTENSION to include .c, but that would be a hack, anyways. So if you cannot rename the files, and do not want to hack your NDK, the cleanest solution would be to simply ignore the warning.

Android link many static libraries into shared library

i have 4 static libraries libavcodec.a libavutil.a libswscale.a libx264.a
I want to link it with libmytest.so
I tried below Android.mk script
LOCAL_PATH := $(call my-dir)
INITIAL_PATH := $(LOCAL_PATH)
include $(CLEAR_VARS)
LOCAL_MODULE := mytest
LOCAL_SRC_FILES := mytest.c
LOCAL_LDLIBS += -llog
LOCAL_WHOLE_STATIC_LIBRARIES := libavutil libavcodec libswscale libx264
include $(BUILD_SHARED_LIBRARY)
mytest.c calls many functions from those libraries. The 4 libraries are placed inside PROJECTPATH\jni\.
But i get undefined reference to all functions from those libraries.
I tried giving LOCAL_ALLOW_UNDEFINED_SYMBOLS := truewhich allowed me to create shared library, but when i launch the app, i get
01-22 07:15:15.650: E/AndroidRuntime(9655): Caused by: java.lang.UnsatisfiedLinkError: Cannot load library: reloc_library[1285]: 1868 cannot locate 'avcodec_register_all'...
01-22 07:15:15.650: E/AndroidRuntime(9655): at java.lang.Runtime.loadLibrary(Runtime.java:370)
01-22 07:15:15.650: E/AndroidRuntime(9655): at java.lang.System.loadLibrary(System.java:535)
You need to define a PREBUILT_STATIC_LIBRARY for each one of your libraries if you do not build them from source, e.g.
include $(CLEAR_VARS)
LOCAL_MODULE := avutil
LOCAL_SRC_FILES := $(LOCAL_PATH)/jni/libavutil.a
include $(PREBUILT_STATIC_LIBRARY)
...
[repeat for other prebuilt libraries].
LOCAL_STATIC_LIBRARIES only understands module names, i.e. names of stuff that have been declared through their own ndk-build module definition. I'm surprised it didn't provide a warning about missing modules though, but it's the most likely explanation corresponding to your problem.

Problems loading dependent .SO in Android NDK

I have the following Android.mk...
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := Box2D-local
LOCAL_SRC_FILES := $(LOCAL_PATH)/../Box2D/libs/$(TARGET_ARCH_ABI)/libbox2D.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := openbox
LOCAL_C_INCLUDES := $(LOCAL_PATH)/.. $(LOCAL_PATH)
NDK_OUT :=../../
LOCAL_SRC_FILES := \
$(subst $(LOCAL_PATH)/,, \
$(wildcard $(LOCAL_PATH)/*.cpp) \
$(wildcard $(LOCAL_PATH)/Collision/Shapes/*.cpp))
LOCAL_LDLIBS := -lm -llog -ldl -lGLESv1_CM
LOCAL_SHARED_LIBRARIES := Box2D-local
include $(BUILD_SHARED_LIBRARY)
Everything compiles fine but when I run the application I see....
D/dalvikvm(14851): Trying to load lib /data/app-lib/com.lmdig.android.tutorial.oglbox2dbasics-1/libopenbox.so 0x40ce7138
E/dalvikvm(14851): dlopen("/data/app-lib/com.lmdig.android.tutorial.oglbox2dbasics-1/libopenbox.so") failed: Cannot load library: soinfo_link_image(linker.cpp:1635): could not load library "libbox2D.so" needed by "libopenbox.so"; caused by load_library(linker.cpp:745): library "libbox2D.so" not found
But when I ls the /data/app-lib/com.lmdig.android.tutorial.oglbox2dbasics-1/ folder on the device I see...
root#android:/ # ls /data/app-lib/com.lmdig.android.tutorial.oglbox2dbasics-1/
libbox2D.so
libopenbox.so
Is my LOCAL_SRC_FILES wrong or something?
Looks like I thought when I loaded it in another class it would be used for this one. That assumption was incorrect and I had to load both libraries in the class.

Adding libpng in android ndk project

I've searched a lot of topics about linking libpng to my android ndk project but I've found right answer for my problem and I hope somebody will help me.
This is hierarchy of my project:
jni
different_cpp_files
different_hpp_files
Android.mk
libpng
different_cpp_files
different_hpp_files
Android.mk
Android.mk in libpng folder:
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LS_C=$(subst $(1)/,,$(wildcard $(1)/*.c))
LOCAL_MODULE := png
LOCAL_SRC_FILES := \
$(filter-out example.c pngtest.c,$(call LS_C,$(LOCAL_PATH)))
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)
LOCAL_EXPORT_LDLIBS := -lz
include $(BUILD_STATIC_LIBRARY)
I suppose that everything is right here..
Android.mk in jni folder:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LS_CPP=$(subst $(1)/,,$(wildcard $(1)/*.cpp))
LOCAL_MODULE := pacman
LOCAL_CFLAGS := -Wno-psabi
LOCAL_SRC_FILES := $(call LS_CPP,$(LOCAL_PATH))
LOCAL_LDLIBS := -landroid -llog -lEGL -lGLESv1_CM -lOpenSLES
LOCAL_STATIC_LIBRARIES := android_native_app_glue png
include $(BUILD_SHARED_LIBRARY)
$(call import-module,android/native_app_glue)
$(call import-module,libpng)
The last line shows that I got libpng like native_app_glue lib(in the directory of android-ndk sources) Now I want to compile libpng from my project. What I need to change in Android.mk file?
i've got another way for you:
Download all files from here and paste it into a new folder anywhere on your system:
https://github.com/julienr/libpng-android
go into the folder and run:
./build.sh
You will get an libpng.a file in [YOUR_FOLDER]/obj/local/armeabi/libpng.a
Copy this file into:
[YOUR_ANDROID_NDK_FOLDER]/platforms/[ALL_FOLDERS_IN_HERE]/arch-arm/usr/lib/
now you can use libpng in all your projects with the simple line:
LOCAL_LDLIBS += -lpng
you only have to include this in your cpp's:
#include <png.h>
Have fun!

Resources