Home » Android » Link shared library under Android NDK

Link shared library under Android NDK

Posted by: admin June 15, 2020 Leave a comment

Questions:

I with success compile library LibXtract to shared object libxtract.so and want to use is in second project.

In mention project I try to compile it on simple function:

#include <com_androidnative1_NativeClass.h>
#include <android/log.h>
#include "libxtract.h"

JNIEXPORT void JNICALL Java_com_androidnative1_NativeClass_showText
(JNIEnv *env, jclass clazz)
{

    float mean = 0, vector[] = {.1, .2, .3, .4, -.5, -.4, -.3, -.2, -.1}, spectrum[10];
    int n, N = 9;
    float argf[4];

    argf[0] = 8000.f;
    argf[1] = XTRACT_MAGNITUDE_SPECTRUM;
    argf[2] = 0.f;
    argf[3] = 0.f;

    xtract[XTRACT_MEAN]((void *)&vector, N, 0, (void *)&mean);
    __android_log_print(ANDROID_LOG_DEBUG, "LIbXtract", "Button pushe2");
}

I have flat structure:

  • jni/com_androidnative1_NativeClass.c
  • jni/com_androidnative1_NativeClass.hjni/libxtract.h
  • jni/other *.h files from libxtract interface
  • jni/Android.mk
  • jni/Applicatoin.mk

library libxtract.so I put in mainproject/lib folder

my Android.mk file looks like:

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := com_androidnative1_NativeClass.c 
LOCAL_MODULE := com_androidnative1_NativeClass
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/
LOCAL_LDLIBS += -llog
LOCAL_SHARE_LIBRARIES := libxtract
NDK_MODULE_PATH += $(LOCAL_PATH)/../lib/
include $(BUILD_SHARED_LIBRARY)

and I still got error:

Compile thumb  : com_androidnative1_NativeClass <= com_androidnative1_NativeClass.c
SharedLibrary  : libcom_androidnative1_NativeClass.so./obj/local/armeabi/objs/com_androidnative1_NativeClass/com_androidnative1_Nativ    eClass.o: In function `Java_com_androidnative1_NativeClass_showText':
/home/jack/Projects/AndroidNative1/jni/com_androidnative1_NativeClass.c:20: undefined reference to `xtract'
collect2: ld returned 1 exit status
make: *** [obj/local/armeabi/libcom_androidnative1_NativeClass.so] Error 1

Code came form example of LibXtract and under C++ compile without problems, any ideas?

How to&Answers:

Your Android make file should be …

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LIB_PATH := $(LOCAL_PATH)/../lib
LOCAL_SRC_FILES := com_androidnative1_NativeClass.c 
LOCAL_MODULE := com_androidnative1_NativeClass
LOCAL_LDLIBS += -llog


LOCAL_LDLIBS += $(LIB_PATH) -lxtract

LOCAL_SHARE_LIBRARIES := libxtract
include $(BUILD_SHARED_LIBRARY)

Try this make file in your second project, and you can successfully build your code without having any error.

Answer:

In the above answer all is right but exept one.

When we want to link lib we must add -L before LOCAL_LDLIBS dir as below.

LIB_PATH := $(LOCAL_PATH)/../lib

LOCAL_LDLIBS += **-L**$(LIB_PATH) -lxtract

Else it will give error as below

cannot open XXX/../lib: Permission denied

Answer:

You need to tell Android NDK build scripts about your shared library. Check ${NDK}/doc/PREBUILTS.html for instructions how this can be done. They advise to add Android.mk in the same directory where you have your libXtract.so:

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := libXtract
LOCAL_SRC_FILES := libXtract.so
include $(PREBUILT_SHARED_LIBRARY)

Debugging tip: I guess you are using ndk-build to build your “second project”. Try running ndk-build with V=99 (try V=99 ndk-build or ndk-build V=99 – my memory failing). This will show you the the exact failing linking command. You should likely have options -lXtract and -L/path/to/libXtract/library. (Sometimes it is convenient to just copy and paste the linking command to run it manually to find the right options for successful linking, before actually fixing the build settings.)

Update: I now see @codetiger’s comment seems to point to a same sort of answer (without mentioning the NDK document which is good reading – so I am not deleting this answer).