NDK build - specify linker settings per architecture - android-ndk

My Application.mk is set to build arm as well as x86 shared libraries:
APP_ABI :- armeabi-v7a x86
I have prebuilt openssl static libraries:
libcrypto_v7a.a
libcrypto_x86.a
libssl_v7a.a
libssl_x86.a
These files have been copied to jni/inc directory:
Would appreciate your help in setting up Android.mk such that it picks up proper library to link with:
LOCAL_LDLIBS := -llog -L$(LOCAL_PATH)/inc/ -lcrypto_v7a -lssl_v7a
or
LOCAL_LDLIBS := -llog -L$(LOCAL_PATH)/inc/ -lcrypto_x86 -lssl_x86
Perhaps there is a $(ARCH) kind of variable defined that I could use to my advantage:
LOCAL_LDLIBS := -llog -L$(LOCAL_PATH)/inc/ -lcrypto_$(ARCH) -lssl_$(ARCH)

What about using ifeq and TARGET_ARCH?
LOCAL_LDLIBS := -llog -L$(LOCAL_PATH)/inc/
ifeq ($(TARGET_ARCH),arm)
LOCAL_LDLIBS += -lcrypto_v7a -lssl_v7a
else
ifeq ($(TARGET_ARCH),x86)
LOCAL_LDLIBS += -lcrypto_x86 -lssl_x86
endif
endif

Another alternative is:
MY_LDLIBS_arm := -lcrypto_v7a -lssl_v7a
MY_LDLIBS_x86 := -lcrypto_x86 -lssl_x86
MY_LDLIBS_mips := ...
LOCAL_LDLIBS += $(MY_LDLIBS_$(TARGET_ARCH))
Which is easier to read and write.

Related

Adding two prebuilt static and shared libraries using Android.mk

I am trying to add both Dlib and superpowers libraries to my android project using Android.mk. I included successfully prebuilt shared Dlib library (.so files) using Android.mk, but when I am trying to add the superpower as a static library (the package has .a files and CMakeLists.txt), I am facing issue regarding liking JNI functions with java. I cannot use the JNI functions in java. I would appreciate it if someone can help me. Here is my Android.mk file:
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := libs
LOCAL_SRC_FILES := /[MyProjectAddress]/app/libs/$(TARGET_ARCH_ABI)/libdlib.so
LOCAL_EXPORT_C_INCLUDES := /[MyDLIBFileAddress]/dlib_v19.7/dlib
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := superpoweredLib
LOCAL_SRC_FILES := /[MyProjectAddress]/app/libs/$(TARGET_ARCH_ABI)/libSuperpoweredAndroid$(TARGET_ARCH_ABI).a
LOCAL_EXPORT_C_INCLUDES := /[SuperpoweredFileAddress]/SuperpoweredSDK/Superpowered/AndroidIO/SuperpoweredAndroidAudioIO.cpp \ /[SuperpoweredFileAddress]/SuperpoweredSDK/Superpowered \
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := FrequencyDomain
LOCAL_LDFLAGS := -Wl,--build-id
LOCAL_LDLIBS += -llog -ldl
LOCAL_SRC_FILES := \ /[MyProjectAddress]/app/src/main/jni/FrequencyDomain.cpp \
LOCAL_C_INCLUDES += /[MyProjectAddress]/app/src/debug/jni
LOCAL_C_INCLUDES += /[MyProjectAddress]/app/src/main/jni
LOCAL_SHARED_LIBRARIES := libs
include $(BUILD_SHARED_LIBRARY)
LOCAL_SHARED_LIBRARIES := superpoweredLib
include $(BUILD_SHARED_LIBRARY)

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.

How to build library with the same MODULE name for different ABI from different source file in ndk?

in ndk, I want to build library with the same MODULE name for different ABI from different source file.
I have two sources under dir: armeabi-v7a and arm64-v8a
Here is my Android.mk:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := session
LOCAL_SRC_FILES := armeabi-v7a/libsession.so
TARGET_ARCH_ABI := armeabi-v7a
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := session
LOCAL_SRC_FILES := arm64-v8a/libsession.so
TARGET_ARCH_ABI := arm64-v8a
include $(PREBUILT_SHARED_LIBRARY)
Here is my Application.mk:
APP_STL := gnustl_static
APP_CPPFLAGS := -frtti -fexceptions
APP_ABI := armeabi-v7a arm64-v8a
APP_PLATFORM := android-21
but failes:
Android NDK: Trying to define local module 'session' in jni/Android.mk.
Android NDK: But this module was already defined by jni/Android.mk.
How to achieve that?
The simplest way would be to use the fact that your .so file appear to be located in subdirectories named after the ABI:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := session
LOCAL_SRC_FILES := $(TARGET_ARCH_ABI)/libsession.so
include $(PREBUILT_SHARED_LIBRARY)
If that hadn't been the case you could've checked the value of TARGET_ARCH_ABI and acted accordingly. For example:
ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
LOCAL_SRC_FILES := foo/libfoo.so
else ifeq ($(TARGET_ARCH_ABI),arm64-v8a)
LOCAL_SRC_FILES := bar/libbar.so
endif
There's no need to set TARGET_ARCH_ABI yourself - it's set for you by the build system.

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.

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.

Resources