How to link a prebuilt shared Library to an Android NDK project?
Here I used this Android.mk
file in jni/
folder.
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
# Here we give our module name and source file(s)
LOCAL_MODULE := offlineDownload
LOCAL_SRC_FILES := offline_download.c
LOCAL_SHARED_LIBRARIES :=../lib/libpackext.so.1.0
LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -llog
include $(BUILD_SHARED_LIBRARY)
And make one lib
folder in project directory and put my prebuilt .so
library and make one Android.mk
file which contains following
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := packext
LOCAL_SRC_FILES := libpackext.so.1.0
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../include
include $(PREBUILT_SHARED_LIBRARY)
And when i use ndk-build -B
command than i got undefined reference to packageExtraction. Here I use my prebuilt library functions means I can't link my prebuilt shared library to my offlinedownload
library.
So any body please help me to solved out this issue.
Solution 1:
Here is a complete Android.mk file for using a 3rd party shared library. The library (libffmpeg.so) is placed in the jni folder. Its "LOCAL_EXPORT_C_INCLUDES" specifies where the header files are kept for the library.
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := ffmpeg
LOCAL_SRC_FILES := libffmpeg.so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/../../ffmpeg/libs/arm-linux-androideabi4.7_1/include
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := ffmpegandroid
LOCAL_SRC_FILES := ffmpegandroid.c
LOCAL_SHARED_LIBRARIES := ffmpeg
include $(BUILD_SHARED_LIBRARY)
If you wanted to support multiple architectures then you could specify:
APP_ABI := armeabi armeabi-v7a x86 mips
in your jni/Application.mk and change the LOCAL_SRC_FILES to something like:
LOCAL_SRC_FILES := $(TARGET_ARCH_ABI)/libffmpeg.so
and place a libffmpeg.so at jni/armeabi/libffmpeg.so, jni/armeabi-v7a/libffmpeg.so etc ..
Solution 2:
Android NDK official hello-libs
CMake example
https://github.com/googlesamples/android-ndk/tree/840858984e1bb8a7fab37c1b7c571efbe7d6eb75/hello-libs
Just worked for me on Ubuntu 17.10 host, Android Studio 3, Android SDK 26, NDK 15.2. so I strongly recommend that you base your project on it.
The shared library is called libgperf
, the key code parts are:
-
hello-libs/app/src/main/cpp/CMakeLists.txt:
// -L add_library(lib_gperf SHARED IMPORTED) set_target_properties(lib_gperf PROPERTIES IMPORTED_LOCATION ${distribution_DIR}/gperf/lib/${ANDROID_ABI}/libgperf.so) // -I target_include_directories(hello-libs PRIVATE ${distribution_DIR}/gperf/include) // -lgperf target_link_libraries(hello-libs lib_gperf)
on C++ code, use:
#include <gperf.h>
header location:
hello-libs/distribution/gperf/include/gperf.h
lib location:
distribution/gperf/lib/arm64-v8a/libgperf.so
-
app/build.gradle:
android { sourceSets { main { // let gradle pack the shared library into apk jniLibs.srcDirs = ['../distribution/gperf/lib']
Then, if you look under
/data/app
on the device,libgperf.so
will be there as well. If you only support some architectures, see: Gradle Build NDK target only ARM
The example git tracks the prebuilt shared libraries, but it also contains the build system to actually build them as well: https://github.com/googlesamples/android-ndk/tree/840858984e1bb8a7fab37c1b7c571efbe7d6eb75/hello-libs/gen-libs
Solution 3:
You have to do either one of the following:
Cut and paste everything except LOCAL_PATH := $(call my-dir) from your second Android.mk into your first.
-
Put the following in the end of your first Android.mk:
$(call import-module,packext)
Also make sure that you set your NDK_MODULE_PATH environment variable to a path where the Android.mk-file defining the module packext can be found.
You also have to change the LOCAL_SHARED_LIBRARIES in the same way mgiza said in the first answer. I suppose the packageExtraction that you got undefined reference to is in your prebuilt library so unless you have other linking problems this should solve the issue.