I have just compiled the OpenSSL for Android. I have the libcrypto.so and libssl.so shared libraries. I created a sample Android Application called TrialApp. The idea is to use some native functions that would call the libssl and libcrypto shared libraries. Therefore, under my jni directory,I have a TrialApp.cpp which includes a simple SHA1 example.Here is the tree structure of my NDK Application directory on Eclipse:
TrialApp
|
|-->Activity.java
|
|-->TrialApp.java(which includes System.LoadLibrary calls)
|
|-->jni
|-->TrialApp.cpp
|
|-->Android.mk
|
|-->includes
| |
| |-->openssl (dir containing *.h files)
|
|-->precompiled
|-->libssl.so
|-->libcrypto.so
Here is the Android.mk file
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := TrialApp
LOCAL_SRC_FILES := TrialApp.cpp
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/includes/openssl
LOCAL_LDLIBS := -llog
LOCAL_LDLIBS += $(LOCAL_PATH)/precompiled/libssl.so
LOCAL_LDLIBS += $(LOCAL_PATH)/precompiled/libcrypto.so
LOCAL_STATIC_LIBRARIES := sslx cryptox
include $(BUILD_SHARED_LIBRARY)
But then the openssl headers in TrialApp,.cpp cannot be found by the compiler.
The error I get:
fatal error: openssl/evp.h: No such file or directory
Can someone tell me how to resolve it?
Thanks.
Include dirs are set up in compiler flag -I: so, set up LOCAL_CFLAGS variable with appropriate key and header location like this: LOCAL_CFLAGS += $(cf_includes) where cf_includes is defined like cf_includes:= includes/openssl + cf_includes := $(addprefix -Ijni/,$(cf_includes))
In other words you have to defile LOCAL_CFLAGS like this:LOCAL_CFLAGS += -Ijni/includes/openssl
Try to replace your android.mk with
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
c_includes := $(LOCAL_PATH)
cf_includes:= includes/openssl
cf_includes := $(addprefix -Ijni/,$(cf_includes))
export_c_includes := $(c_includes)
LOCAL_MODULE := TrialApp
LOCAL_SRC_FILES := TrialApp.cpp
LOCAL_CFLAGS += $(cf_includes)
LOCAL_EXPORT_C_INCLUDES := $(export_c_includes)
LOCAL_LDLIBS := -llog
LOCAL_LDLIBS += $(LOCAL_PATH)/precompiled/libssl.so
LOCAL_LDLIBS += $(LOCAL_PATH)/precompiled/libcrypto.so
LOCAL_STATIC_LIBRARIES := sslx cryptox
include $(BUILD_SHARED_LIBRARY)
Hope it helps
Related
I am trying to use some c shared libraries in my android application.
The project structure is like:
project
|
|---app->main.cpp, Android.mk
|
|---lib->|->Android.mk
|
|---include----|
| |---mylib->a.h, b.h ...
|
|---libs-> libX.so, libY.so, libZ.so
In the main.cpp, I use the header files like:
#include <mylib/a.h>
#include <mylib/b.h>
In the /project/app/Android.mk, I have
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := my_application
LOCAL_SHARED_LIBRARIES := the_libX_1_0_0 the_libY_1_0_0 the_libZ_0_0_9
LOCAL_SRC_FILES := main.cpp
include $(BUILD_SHARED_LIBRARY)
In the /project/lib/Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := the_libX_1_0_0
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
LOCAL_SRC_FILES := $(LOCAL_PATH)/libs/libX.so
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
include $(BUILD_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := the_libY_1_0_0
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
LOCAL_SRC_FILES := $(LOCAL_PATH)/libs/libY.so
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
include $(BUILD_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := the_libZ_0_0_9
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
LOCAL_SRC_FILES := $(LOCAL_PATH)/libs/libZ.so
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
include $(BUILD_SHARED_LIBRARY)
[The build error]
When I try to make the application, the error I had:
including ./Android.mk ...
build/core/binary.mk:1345: *** project/lib/Android.mk: the_libX_1_0_0: Unused source files: project/lib/libs/the_libX_1_0_0.so.
build/core/ninja.mk:155: recipe for target 'out/build-aosp_arm.ninja' failed
make: *** [out/build-aosp_arm.ninja] Error 1
AOSP environment:
PLATFORM_VERSION := 6.0.1
PLATFORM_SDK_VERSION := 23
PLATFORM_JACK_MIN_SDK_VERSION := 24
Development environment:
Ubuntu 16.04 LTS
GCC 5.4
A bit more background about the question:
Actually, the library libX, libY and libZ are libcrypto.so, libssl.so and libc.so. Google uses a shrunk version of OpenSSL, I am working on an application requires the OpenSSL. So I am trying to use pre-built OpenSSL libraries here.
References:
https://developer.android.com/ndk/guides/prebuilts.html#dm
Android NDK/JNI: Building a shared library that depends on other shared libraries
http://www.scriptscoop3.com/t/84e1c84496bc/android-difference-between-local-export-c-includes-and-local-c-includes.html
Right now I am working on a native Android project and I want to use DevIL.
I don't want to put all the NDK code into one file, since DevIL needs multiple other libraries (libpng/libjpeg/...) and the Android.mk would end up being bloated.
I created a sub directory called Devil in my jni directory. I put all the code needed for DevIl (+ the libraries) in this directory. I also created an extra Android.mk file in this directory. In my "main" Android.mk file I added$(call import-module,DevIL) as well as: LOCAL_SHARED_LIBRARIES += libdevil. In the DevIL Android.mk I created an libdevil module and I used LOCAL_EXPORT_C_INCLUDES to link to the DevIL header files. When I put #include into my main.cpp file the ndk-build fails and complains "No such file or directory" in regards to the included header. If I don't put the #include into the code, the code compiles fine and all the shared libraries are created and put into the libs folder. What am I doing wrong?
My Main Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
include cflags.mk
LOCAL_MODULE := arm
LOCAL_SRC_FILES := main.cpp
LOCAL_SHARED_LIBRARIES += libdevil
include $(BUILD_SHARED_LIBRARY)
$(call import-module,DevIL)
The Android.mk used for DevIl
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
include cflags.mk
JPEG_SRC_PATH := Libjpeg/
DEVIL_SRC_PATH := DevIL/
#many more
#libjpeg
include $(CLEAR_VARS)
LOCAL_MODULE := libjpeg
LOCAL_C_INCLUDES := ${JPEG_SRC_PATH}
FILE_LIST := $(wildcard $(LOCAL_PATH)/JPEG_SRC_PATH/*.c)
LOCAL_SRC_FILES := $(FILE_LIST:$(LOCAL_PATH)/%=%)
include $(BUILD_SHARED_LIBRARY)
#many other libraries; basically the same as libjpeg
#libdevil
include $(CLEAR_VARS)
LOCAL_MODULE := libdevil
LOCAL_EXPORT_C_INCLUDES := \
${DEVIL_SRC_PATH}include \
${DEVIL_SRC_PATH}src-IL/include \
#many more
FILE_LIST := $(wildcard $(LOCAL_PATH)/DEVIL_SRC_PATHsrc-IL/src/*.c)
LOCAL_SRC_FILES := $(FILE_LIST:$(LOCAL_PATH)/%=%)
LOCAL_STATIC_LIBRARIES := \
libjpeg \
#many more
LOCAL_LDLIBS += -lz
include $(BUILD_SHARED_LIBRARY)
The cflags.mk file
LOCAL_CFLAGS := -DANDROID_NDK
LOCAL_CFLAGS += -Werror
LOCAL_CFLAGS += -Wall
LOCAL_CFLAGS += -Wextra
LOCAL_CFLAGS += -Wno-strict-aliasing
LOCAL_CFLAGS += -Wno-unused-parameter
LOCAL_CFLAGS += -Wno-missing-field-initializers
LOCAL_CFLAGS += -Wno-multichar
LOCAL_CPPFLAGS := -Wno-type-limits
LOCAL_CPPFLAGS += -Wno-invalid-offsetof
LOCAL_CPPFLAGS += -std=c++11
LOCAL_CFLAGS += -std=c++11
LOCAL_CFLAGS += -fexceptions
LOCAL_CFLAGS += -Wno-error=deprecated-declarations
LOCAL_ARM_MODE := arm
Structure of the Directories
jni
|
+-- main.cpp
+-- Android.mk <- main Android
+-- Application.mk
+-- cflags.mk
|
+--DevIL
|
+-- Android.mk <- the Android.mk for DevIL
+-- cflags.mk
+--DevIL <-Directory containing DevIL source code
+--Libjpeg <-Directory containing code of specific DevIL dependency
+--...<-Directory containing code of specific DevIL dependency
Edit:
I noticed that I did not add my Application.mk, thus my Application.mk
Application.mk
APP_PLATFORM := android-19
APP_ABI := armeabi-v7a
APP_STL:=c++_static
APP_LDFLAGS := -Wl,--build-id
NDK_TOOLCHAIN_VERSION := 4.9
ROOT_DIR := $(patsubst %/,%,$(dir $(lastword $(MAKEFILE_LIST))))
NDK_MODULE_PATH := $(ROOT_DIR)
This does not answer the question, but if you are here from a search engine and happen to be having issues with LOCAL_EXPORT_C_INCLUDES on an AOSP module (not an NDK project!), Google's documentation at https://developer.android.com/ndk/guides/android_mk.html applies only to NDK projects.
For AOSP modules, the variable name is LOCAL_EXPORT_C_INCLUDE_DIRS, not LOCAL_EXPORT_C_INCLUDES.
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
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)
I have an Android application project that depends on two native libraries, libA and libB. libA depends on libB, and both libraries are built using APP_STL:=gnustl_shared. The problem then arises when trying to build the APK:
[2014-09-30 14:31:47 - Appname] Error generating final archive: Found duplicate file for APK: lib/armeabi/libgnustl_shared.so
Origin 1: /libA/libs/armeabi/libgnustl_shared.so
Origin 2: /libB/libs/armeabi/libgnustl_shared.so
How do I configure these libraries to build/link properly while using a common shared library such as libgnustl_shared.so?
EDIT:
I have tried many alternative makefile settings, so it's hard to know what to post here, but I'll try. Both Application.mk files in libA/jni and libB/jni contain:
APP_STL := gnustl_shared
APP_OPTIM := release
APP_ABI := armeabi-v7a armeabi
APP_PLATFORM := android-15
In libA/jni, the Android.mk file contains:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := MyBase
LOCAL_SRC_FILES := libs/$(TARGET_ARCH_ABI)/libMyBase.so
LOCAL_PRELINK_MODULE := true
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := Base
LOCAL_SRC_FILES := Base.cpp
LOCAL_C_INCLUDES := ../../../../LIBS/MyBase/pub/include
LOCAL_LDLIBS := -llog -ljnigraphics
LOCAL_SHARED_LIBRARIES := MyBase
LOCAL_CPP_FEATURES += rtti
LOCAL_CPP_FEATURES += exceptions
include $(BUILD_SHARED_LIBRARY)
In libB/jni, the Android.mk file contains:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := MyMedia
LOCAL_SRC_FILES := libs/$(TARGET_ARCH_ABI)/libMyMedia.so
LOCAL_PRELINK_MODULE := true
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := Media
LOCAL_SRC_FILES := Media.cpp media_jni.cpp
LOCAL_C_INCLUDES := ../../../../LIBS/MyBase/pub/include \
../../../../LIBS/MyMedia/pub/include
LOCAL_LDLIBS := -llog -ljnigraphics
LOCAL_SHARED_LIBRARIES := MyBase MyMedia
LOCAL_CPP_FEATURES += rtti
LOCAL_CPP_FEATURES += exceptions
include $(BUILD_SHARED_LIBRARY)
$(call import-module,LIBS/MyBase/jni)
MyBase and MyMedia are two native libraries written in C++ and are not Java/JNI aware. MyMedia is dependent on MyBase. Both libraries are dependent on a robust C++ library such as gnustl_shared.