NDK: How to include Prebuilt Shared Library Regardless of Architecture
This worked...
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := box2D-prebuilt
LOCAL_SRC_FILES := ../Box2D/libs/$(TARGET_ARCH_ABI)/libbox2D.so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/..
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := box2DHello
LOCAL_SRC_FILES := \
$(subst $(LOCAL_PATH)/,, \
$(wildcard $(LOCAL_PATH)/*.cpp))
LOCAL_LDLIBS := -lm -llog
LOCAL_SHARED_LIBRARIES := box2D-prebuilt
include $(BUILD_SHARED_LIBRARY)
Using my own prebuilt shared library in an Android NDK project
In the documentation of Android.mk, check the PREBUILT_SHARED_LIBRARY
script description. Put the .so file in lib
(not libs
) directory and write an Android.mk file next to it that looks something like:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := Myaccessories
LOCAL_SRC_FILES := libMyaccessories.so
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../jni/include
include $(PREBUILT_SHARED_LIBRARY)
How to add prebuilt *.so libraries in android studio?
The issue is mainly related to the nature of libraries. Libraries are dynamic in Android and needs to be linked at runtime.
libindy.so
depends on stl, openssl, libsodium and libzmq.
You will find libgnustl_shared.so
in NDK.
All the other needed prebuilt libraries are also available here.
What you need to do is make sure these libraries are present in the jniLibs folder and load these in order libraries before libindy.
System.loadLibrary("libgnustl_shared");
.
.
System.loadLibrary("indy");
Alternate approach:
There is a subproject in Indy where we are using libindy as dependency and we try to create a one fat dynamic library which has all the dependencies.
Link
If you follow the steps like vcx you dont have to have all the defendant l libraries in jniLibs as they will be already part of final .so file
The command which make one fat dynamic library with all the symbols and dependencies is this (from the link pasted above)
${LIBVCX}/target/${CROSS_COMPILE}/release/libvcx.a \
${TOOLCHAIN_DIR}/sysroot/usr/${NDK_LIB_DIR}/libz.so \
${TOOLCHAIN_DIR}/sysroot/usr/${NDK_LIB_DIR}/libm.a \
${TOOLCHAIN_DIR}/sysroot/usr/${NDK_LIB_DIR}/liblog.so \
${LIBINDY_DIR}/libindy.a \
${TOOLCHAIN_DIR}/${CROSS_COMPILE_DIR}/${NDK_LIB_DIR}/libgnustl_shared.so \
${OPENSSL_DIR}/lib/libssl.a \
${OPENSSL_DIR}/lib/libcrypto.a \
${SODIUM_LIB_DIR}/libsodium.a \
${LIBZMQ_LIB_DIR}/libzmq.a \
${TOOLCHAIN_DIR}/${CROSS_COMPILE_DIR}/${NDK_LIB_DIR}/libgnustl_shared.so -Wl,--no-whole-archive -z muldefs
Using Pre-built Shared Library in Android Studio
I was able to make it work using Android.mk instead of cmake. I am posting configurations and contents of Android.mk and gradle build just in case any one needs it.
Create a folder "jni" under "app". Create another custom folder "yourlibs" and put all your pre-built libs inside this "yourlibs" folder in respective "TARGET_ARCH_ABI" folder. For Example, in my case:
- jni/yourlibs/armeabi/libdynamic.so
- jni/yourlibs/armeabi-v7a/libdynamic.so
- jni/yourlibs/x86/libdynamic.so
- jni/yourlibs/x86_64/libdynamic.so
Now follow these steps:
- Create a "C" file inside the "jni" folder from where you would call the function defined inside the "libdynamic.so". Add neccesary header files to your created "C" file. For me it is "uselib.c" and "header.h"
- Create a file named "Android.mk" inside the "jni" folder
Add following contents in Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := yourlibs/$(TARGET_ARCH_ABI)/libdynamic.so
LOCAL_MODULE := add_prebuilt
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := uselib.c
LOCAL_MODULE := use-lib
LOCAL_SHARED_LIBRARIES := add_prebuilt
include $(BUILD_SHARED_LIBRARY)
Update gradle build (app) file to use "Android.mk" instead of cmake:
Inside "android => defaultConfig"
ndk{
abiFilters 'armeabi', 'armeabi-v7a', 'x86', 'x86_64'
}
Inside "android"
externalNativeBuild {
ndkBuild {
path "jni/Android.mk"
}
}
This will make a library called "use-lib" that uses "libdynamic.so" and it will pack both the libraries inside the lib folder of apk. You can check this using apk analyser (Android Studio => Build => Analyse Apk ...). To use "use-lib" use jni call, like:
static {
System.loadLibrary("use-lib");
}
public native String stringFromJNI();
Note: I removed extern "C" statement from the C code.
Unable to link prebuilt static library with shared library in Android NDK
Your problem is probably because of you mix different STL's (versions)
Most of your "undefined reference" is related to:
std::__1
std::__ndk1
Like:
out/target/product/generic_arm64/obj/STATIC_LIBRARIES/libsecuretest_intermediates/libsecuretest.a(MyUtils.cpp.o):function MyUtils::Int32toHexString(int, int): error: undefined reference to 'std::__ndk1::locale::locale()'
Please try to compile also the "libsecuretest" with the AOSP build (maybe the libc++ versions is different).
NOTE:
I tried to check my AOSP libc++ symbols (PLATFORM_VERSION=6.0.1) and get:
$ nm -DC libc++.so | grep 'locale::locale()'
000682ad T std::__1::locale::locale()
000682ad T std::__1::locale::locale()
Also I get same symbols with libc++ from the phones Pixel2(Android9) S8(Andorid 8.0.0)
adb pull /system/lib/libc++.so
[And check it with the same "nm" command...]
But the symbols of the ndk18 is:
$nm -DC libc++_shared.so | grep 'locale::locale()'
00000000000865b0 T std::__ndk1::locale::locale()
00000000000865b0 T std::__ndk1::locale::locale()
How to add prebuilt *.so library in android studio 2.2
currently need to pack it by the app. it could be something like:
sourceSets {
main {
// let gradle pack the shared library into apk
jniLibs.srcDirs = ['point/to/your/shared-lib']
}
}
one example is: https://github.com/googlesamples/android-ndk/blob/master/hello-libs/app/build.gradle
If your shared lib [yours is inside project path] is close to your project, put relative path of your shared-lib to your CMakeLists.txt would work.
Some background discussion at the bottom of this bug might help:
https://code.google.com/p/android/issues/detail?id=214664&can=8&q=vulkan&colspec=ID%20Status%20Priority%20Owner%20Summary%20Stars%20Reporter%20Opened
Related Topics
How to Show and Hide Actionbar with Appcompat V.7
Getting Nosuchfielderror Instance Org/Apache/Http/Message/Basicheadervalueparser
How Does Native Android Code Written for Arm Run on X86
Android How to Implement Bottom Sheet from Material Design Docs
How to Change Toolbar Home Icon Color
Cordova 3.5.0 Install Error- Please Install Android Target 19
Oauth 2.0 Authorization for Linkedin in Android
Get Image from the Gallery and Show in Imageview
Bring Application to Front After User Clicks on Home Button
Programmatically Add View One Below Other in Relative Layout
Find Current Location Latitude and Longitude in Android
How to Read Contacts in Android Using Realm
Differencebetween System Apps and Privileged Apps on Android