android-ndk - using prebuilt static libraries that links with each other - android

I've got 3 prebuilt static libraries I want to use in my shared library.
The problem is when the ndk-build tries to link to the static libraries, I get tons of undefined references thrown at me.
The 'undefined references' originates from when the static libraries tries to call methods in another static library. For example, tinyNET calling a method in tinySAK. The dependencies are this:
tinySAK has no dependencies
tinyNET depends on tinySAK,
tinyHTTP depends on tinyNET and tinySAK
Here's what my Android.mk looks like:
LOCAL_PATH := $(call my-dir)
# TINYSAK
include $(CLEAR_VARS)
LOCAL_MODULE := tinySAK
LOCAL_SRC_FILES := libtinySAK_armv7-a.a
include $(PREBUILT_STATIC_LIBRARY)
# TINYNET
include $(CLEAR_VARS)
LOCAL_MODULE := tinyNET
LOCAL_SRC_FILES := libtinyNET_armv7-a.a
include $(PREBUILT_STATIC_LIBRARY)
# TINYHTTP
include $(CLEAR_VARS)
LOCAL_MODULE := tinyHTTP
LOCAL_SRC_FILES := libtinyHTTP_armv7-a.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := libtest
LOCAL_SRC_FILES := \
/../../testclient.cpp \
/../../main.cpp \
/../../Webservice.cpp
LOCAL_C_INCLUDES := \
$(LOCAL_PATH)/../../includes/ \
$(LOCAL_PATH)/../../../doubango/tinyHTTP/include/ \
$(LOCAL_PATH)/../../../doubango/tinySAK/src/ \
$(LOCAL_PATH)/../../../doubango/tinyNET/src/
LOCAL_STATIC_LIBRARIES := tinySAK tinyNET tinyHTTP
include $(BUILD_SHARED_LIBRARY)
What should I do to fix this?

My god, it was so simple.
To any of you with the same problem, heres how I solved it:
Instead of
LOCAL_STATIC_LIBRARIES := tinySAK tinyNET tinyHTTP
Use
LOCAL_STATIC_LIBRARIES := tinyHTTP tinyNET tinySAK
meaning, the one with the most dependencies first.

Related

How to use shared library without header files in Android?

I have a shared lib (ex. libcrypto.so), but don't have header files.
Can I use this lib in other module?
I tried to use LOCAL_EXPORT_C_INCLUDES to export header files, but It doesn't work.
This is prebuilt module:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := libcrypto
LOCAL_SRC_FILES := prebuilt/$(TARGET_ARCH_ABI)/libcrypto.so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
include $(PREBUILT_SHARED_LIBRARY)
And, this is module used libcrypto:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES += test.c # include "openssl/crypto.h"
LOCAL_C_INCLUDES += $(crypto_PATH)/include
LOCAL_SHARED_LIBRARIES += libcrypto
LOCAL_MODULE := libtest
LOCAL_MODULE_TAGS := optional
LOCAL_ARM_MODE := arm
LOCAL_PRELINK_MODULE := false
include $(BUILD_SHARED_LIBRARY)
This is libcrypto module (boringssl):
LOCAL_PATH := $(call my-dir)
# Target shared library
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE := libcrypto
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/src/include
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk $(LOCAL_PATH)/crypto-sources.mk
LOCAL_SDK_VERSION := 9
LOCAL_CFLAGS += -fvisibility=hidden -DBORINGSSL_SHARED_LIBRARY -DBORINGSSL_IMPLEMENTATION -DOPENSSL_SMALL -Wno-unused-parameter
# sha256-armv4.S does not compile with clang.
LOCAL_CLANG_ASFLAGS_arm += -no-integrated-as
LOCAL_CLANG_ASFLAGS_arm64 += -march=armv8-a+crypto
include $(LOCAL_PATH)/crypto-sources.mk
include $(BUILD_SHARED_LIBRARY)
EDIT: Added boringssl module. I actually used #include "openssl/crypto.h" in test.c
Usually, you find crypto.h under include/openssl. So, in your case, either change the #include statement in test.c
#include "openssl/crypto.h"
Or (less recommended), edit
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include/openssl

How to split my NDK project into lib and app

I have an NDK-based project (written mostly on C++) and I want to split its sources into two parts: "lib" (to be shared with other projects) and "app" (files specific to current project).
Now my Android.mk looks as follows:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := MyProj
MY_LIB_SOURCES := \
libfile1.cpp \
libfile2.cpp
MY_APP_SOURCES := \
appfile1.cpp \
appfile2.cpp
LOCAL_SRC_FILES += $(MY_LIB_SOURCES)
LOCAL_SRC_FILES += $(MY_APP_SOURCES)
LOCAL_STATIC_LIBRARIES := android_native_app_glue
include $(BUILD_SHARED_LIBRARY)
$(call import-module,android/native_app_glue)
The only reason for splitting is that I want to add/remove lib source file once, because now I have to change Android.mk for all projects which need sources from MY_LIB_SOURCES.
Do I have to create a separate project that would produce a shared library? Or should it be a static library? Or maybe it's possible to just #include somehow file that enumerates MY_LIB_SOURCES into Android.mk of each app?
We usually create a separate folder for library sources, e.g.
project
jni
appfile1.cpp
appfile2.cpp
Android.mk (1)
my_lib
libfile1.cpp
libfile2.cpp
Android.mk (2)
This is the first (application) Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := MyProj
MY_APP_SOURCES := \
appfile1.cpp \
appfile2.cpp
LOCAL_SRC_FILES += $(MY_APP_SOURCES)
LOCAL_STATIC_LIBRARIES := android_native_app_glue
LOCAL_STATIC_LIBRARIES += MyLib
include $(BUILD_SHARED_LIBRARY)
include $(LOCAL_PATH)/../../my_lib/Android.mk
$(call import-module,android/native_app_glue)
This is the second (library) Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := MyLib
MY_LIB_SOURCES := \
libfile1.cpp \
libfile2.cpp
LOCAL_SRC_FILES += $(MY_LIB_SOURCES)
include $(BUILD_STATIC_LIBRARY)
Using the Andorid.mk name for MyLib is by convention; you could use some other file name, and change the include statement (line 17 of the first Android.mk file) accordingly.
You could also use the same $(call import-module) syntax, like
$(call import-module,my_lib)
But to do so, you must provide a NDK_MODULE_PATH environment variable that includes $(LOCAL_PATH)/../../.
Your library will be rebuilt anew for each app (project) that includes it - either with the first naïve include method, or with $(call import-module) method. You can provide a prebuilt static library, but this is a different story.
You must divide your android.mk in two sections:
LOCAL_PATH := $(call my-dir)
## The lib ##
include $(CLEAR_VARS)
LOCAL_MODULE := my_lib
SRC_LIB := $(wildcard $(LOCAL_PATH)/*.cpp)
LOCAL_SRC_FILES := $(SRC_LIB:$(LOCAL_PATH)/%=%)
include $(PREBUILT_SHARED_LIBRARY)
## The App ##
include $(CLEAR_VARS)
LOCAL_MODULE := my_app
LOCAL_CPP_EXTENSION := .cxx .cpp .cc
LOCAL_SRC_FILES := \
appfile1.cpp \
appfile2.cpp
LOCAL_STATIC_LIBRARIES := android_native_app_glue
LOCAL_SHARED_LIBRARIES := my_lib
LOCAL_LDLIBS += -landroid
include $(BUILD_EXECUTABLE)
$(call import-module,android/native_app_glue)
If you want static library you have only to change include $(PREBUILT_SHARED_LIBRARY) to include $(PREBUILT_STATIC_LIBRARY) and LOCAL_SHARED_LIBRARIES := my_lib to LOCAL_STATIC_LIBRARIES += my_lib

How to add static c-library (libsrtp) to Android-Project using NDK

so I'm relatively new to Android-NDK and trying to add an uncompiled c-library to android.
I've downloaded the library's source from here and followed these instructions to create a static library (.a-File) from the downloaded files using ndk-build.
So now I have a folder-structure that looks like this:
-srtp
--include (srtp.h, crypto.h)
--srtp (srtp.c...)
--obj
---local
----armeabi
-----libsrtp_static.a
In my Android-project I want to include srtp.h in a c-file inside my /jni/ folder. I've tried to just add the .a-file to the /jni folder but than it says "srtp.h no such file or direcotry". If I add the entire srtp-folder to the project and include the header with "srtp/include/srtp.h" it compiles but fails to link the source as I get the error "Undefined reference to srtp-function-call"
Here's my Android.mk (parts of it copied from Android.mk within the downloaded source):
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_LDLIBS := -llog
LOCAL_MODULE := ndk1 #name of my project
LOCAL_SRC_FILES := native.c #name of the c-source file
include $(BUILD_SHARED_LIBRARY)
LOCAL_PATH:= /home/dev/programing/srtp
common_SRC_FILES := \
srtp/srtp.c \
srtp/ekt.c \
crypto/cipher/cipher.c \
#...more files like that
common_CFLAGS := \
-DPOSIX -iquote$(LOCAL_PATH)/crypto/include \
-Werror \
-Wno-ignored-qualifiers \
-Wno-sign-compare \
-Wno-missing-field-initializers
common_C_INCLUDES = $(LOCAL_PATH)/include
# For the device
# =====================================================
# Device static library
include $(CLEAR_VARS)
ifneq ($(TARGET_ARCH),x86)
LOCAL_NDK_VERSION := 5
LOCAL_SDK_VERSION := 9
endif
LOCAL_SRC_FILES := libsrtp_static.a
LOCAL_CFLAGS += $(common_CFLAGS)
LOCAL_C_INCLUDES += /home/dev/programing/srtp/include
LOCAL_MODULE:= libsrtp_static
LOCAL_MODULE_TAGS := optional
include $(BUILD_STATIC_LIBRARY)
Any help is greatly appreciated! Thank you very much.
You need to add the reference to libsrtp_static from your lib (ndk1) declaration :
LOCAL_STATIC_LIBRARIES := libsrtp_static
Also, you don't need to copy all the strp sources to your project, only add this to your static prebuilt library definition
LOCAL_EXPORT_C_INCLUDES += /home/dev/programing/srtp/include
This path will then be automatically added to the LOCAL_C_INCLUDES of your library that is using the library.
Are you building libsrtp or just using a prebuilt static library ? If you're using a prebuilt (lib*.a), replace BUILD_STATIC_LIBRARY with PREBUILT_STATIC_LIBRARY and set only the .a as SRC_FILE:
In summary, once libstrp_static.a is built, this should work:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_LDLIBS := -llog
LOCAL_MODULE := ndk1 #name of my project
LOCAL_SRC_FILES := native.c #name of the c-source file
LOCAL_STATIC_LIBRARIES := libsrtp_static
include $(BUILD_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := /home/dev/programing/srtp/libsrtp_static.a #check path to libsrtp_static.a
LOCAL_EXPORT_C_INCLUDES += /home/dev/programing/srtp/include
LOCAL_MODULE:= libsrtp_static
LOCAL_MODULE_TAGS := optional
include $(BUILD_STATIC_LIBRARY)

Android NDK: Including boost c++ library

I am trying to use a boost library inside my android application, using the NDK. I have found a couple of success stories here and here, but I can't say the same about me. I am specifically trying to use the library in this link, as well as the boost thread library. In the code below, I am only trying to include the thread library, not the math library. The process I used to build the boost libraries is pretty much the same as the first link I attached.
So far, it seems I have successfully built the boost libraries, but when I run ndk-build, I get the following error:
Prebuilt : libboost_thread.a <= <NDK>/sources/
cp: omitting directory `path/to/ndk/sources/boost'
make: *** [obj/local/armeabi/libboost_thread.a] Error 1
Obviously the cp: omitting directory... is not exactly an error. But the only thing I'm getting other than that is the next line, which doesn't really mean anything. Error 1
Here's my Android.mk file:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_STATIC_LIBRARIES := boost_thread
LOCAL_LDLIBS := lboost_system-gcc-md lboost_thread-gcc-md -lgnustl_static
LOCAL_LDLIBS += lboost_system-gcc-md lboost_thread-gcc-md \
-L$(NDK_ROOT)/sources/cxx-stl/gnu-libstdc++/libs/armeabi \
-lgnustl_static
LOCAL_SRC_FILES := #cpp_sources
LOCAL_MODULE := com_example_ndkFile_CppMethods
include $(BUILD_SHARED_LIBRARY)
$(call import-module,boost)
And there's also an Android.mk file in path/to/ndk/sources/boost/:
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE:= boost_thread
LOCAL_SRC_FILES:= android/lib/libboost_thread.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)
include $(PREBUILT_STATIC_LIBRARY)
And my humble Application.mk file:
APP_ABI := armeabi armeabi-v7a
APP_STL := gnustl_static
APP_CPPFLAGS = -fexceptions
I built the boost libraries using bjam. All of the libboost_###.a files are in the sources/boost/android/lib folder.
What is the error I'm getting?
I built the boost libraries using Boost-for-Android. Then I have in my boost/include/lib directory the android makefile boost.mk
LOCAL_PATH := $(call my-dir)
# boost_date_time
#
include $(CLEAR_VARS)
LOCAL_MODULE := boost_date_time
LOCAL_SRC_FILES := libboost_date_time-gcc-mt-1_53.a
include $(PREBUILT_STATIC_LIBRARY)
# boost_filesystem
#
include $(CLEAR_VARS)
LOCAL_MODULE := boost_filesystem
LOCAL_SRC_FILES := libboost_filesystem-gcc-mt-1_53.a
include $(PREBUILT_STATIC_LIBRARY)
# boost_thread
#
include $(CLEAR_VARS)
LOCAL_MODULE := boost_thread
LOCAL_SRC_FILES := libboost_thread-gcc-mt-1_53.a
include $(PREBUILT_STATIC_LIBRARY)
# boost_system
#
include $(CLEAR_VARS)
LOCAL_MODULE := boost_system
LOCAL_SRC_FILES := libboost_system-gcc-mt-1_53.a
include $(PREBUILT_STATIC_LIBRARY)
# boost_program_options
#
include $(CLEAR_VARS)
LOCAL_MODULE := boost_program_options
LOCAL_SRC_FILES := libboost_program_options-gcc-mt-1_53.a
include $(PREBUILT_STATIC_LIBRARY)
# boost_chrono
#
include $(CLEAR_VARS)
LOCAL_MODULE := boost_chrono
LOCAL_SRC_FILES := libboost_chrono-gcc-mt-1_53.a
include $(PREBUILT_STATIC_LIBRARY)
and my module where i use some of the boost libraries looks like this
LOCAL_PATH := $(call my-dir)
# SignalServer, executable
#
include $(CLEAR_VARS)
LOCAL_CFLAGS := -DTIXML_USE_TICPP
#LOCAL_CFLAGS += -DDEBUG
LOCAL_STATIC_LIBRARIES := boost_thread \
boost_system \
boost_filesystem \
boost_program_options \
boost_chrono \
LOCAL_STATIC_LIBRARIES += ticpp \
tia \
tobicore \
tobiid \
tid \
gdf
LOCAL_MODULE := signalserver
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
LOCAL_C_INCLUDES += $(LOCAL_PATH)/extern/include
LOCAL_C_INCLUDES += $(LOCAL_PATH)/../boost/include/boost-1_53
LOCAL_SRC_FILES := #cpp source
include $(BUILD_EXECUTABLE)
in addition I have an Android.mk where all subdir makefiles are listed
TOP_PATH := $(call my-dir)
include $(TOP_PATH)/boost/lib/boost.mk
include $(TOP_PATH)/signalserver/signalserver.mk
.
.
and my Application.mk:
APP_PLATFORM := android-14
APP_ABI := armeabi-v7a
#APP_OPTIM := debug
#NDK_DEBUG := 1
NDK_TOOLCHAIN_VERSION := 4.6
APP_STL := gnustl_static
APP_CPPFLAGS := -fexceptions -frtti
Here: http://silverglint.com/boost-for-android/ you can find a simple script that lets you build a modern version of boost for android, or simply download prebuilt boost binaries.
Also included is a sample test app that shows you how to include/link the boost headers/binaries

android-ndk Adding static libraries to the android.mk

I have three static libraries from a framework that I want to use in my project. These libraries are called libtinySAK_armv7-a.a, libtinyNET_armv7-a.a and libtinyHTTP_armv7-a.a. I have placed them in the same folder as the Android.mkandApplication.mk.
My native code is dependent on them so I want to include them in my shared library.
From what I've read on stackoverflow and google'd I believe the android.mk is supposed to look something like this:
# TINYSAK
include $(CLEAR_VARS)
LOCAL_MODULE := tinySAK
LOCAL_SRC_FILES := libtinySAK_armv7-a.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/../../../doubango/tinySAK/src/
include $(PREBUILT_STATIC_LIBRARY)
# TINYNET
include $(CLEAR_VARS)
LOCAL_MODULE := tinyNET
LOCAL_SRC_FILES := libtinyNET_armv7-a.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/../../../doubango/tinyNET/src/
include $(PREBUILT_STATIC_LIBRARY)
# TINYHTTP
include $(CLEAR_VARS)
LOCAL_MODULE := tinyHTTP
LOCAL_SRC_FILES := libtinyHTTP_armv7-a.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/../../../doubango/tinyHTTP/include/
include $(PREBUILT_STATIC_LIBRARY)
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := libtest
LOCAL_SRC_FILES := \
../../test/stack.cpp \
../../test/main.cpp
LOCAL_C_INCLUDES := \
$(LOCAL_PATH)/../../test/include/ \
$(LOCAL_PATH)/../../../doubango/tinyHTTP/include/ \
$(LOCAL_PATH)/../../../doubango/tinySAK/src/ \
$(LOCAL_PATH)/../../../doubango/tinyNET/src/
LOCAL_STATIC_LIBRARIES := \
tinySAK \
tinyNET \
tinyHTTP
include $(BUILD_SHARED_LIBRARY)
My Application.mk:
APP_STL := stlport_static
APP_ABI := armeabi-v7a
The error I get upon compilation("ndk-build" from project dir) is
jni/Android.mk:tinySAK: LOCAL_SRC_FILES points to a missing file
And I suppose the other 2 libraries also fail. Why cannot it find them?
Besides that, is there any other errors I've made in the makefile?
Thanks
Nevermind, I solved it.
I declared the "LOCAL_PATH" in the beginning of the make-file only. Otherwise it would look for the libs in the ndk-folders.
Try LOCAL_LDLIBS instead of LOCAL_SRC_FILES.

Categories

Resources