Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Link shared library under Android NDK

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?

like image 776
Jack Avatar asked Jun 03 '12 22:06

Jack


People also ask

Where is libc ++_ shared so?

Note: libc++ is not a system library. If you use libc++_shared.so , it must be included in your app. If you're building your application with Gradle this is handled automatically. The LLVM Project is under the Apache License v2.

Where do I specify Ndkversion?

Install a specific version of the NDK Click the SDK Tools tab. Select the Show Package Details checkbox. Select the NDK (Side by side) checkbox and the checkboxes below it that correspond to the NDK versions you want to install. Android Studio installs all versions of the NDK in the android-sdk /ndk/ directory.

What is LIBC in Android?

The Android platform uses libc++ for the C++ standard library (releases up to and including Lollipop used stlport). The NDK historically offered stlport and GNU libstdc++, but those were removed as of NDK r18. Note that if any native code in an Android app uses C++, all the C++ must use the same STL.


3 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.

like image 170
Suvam Roy Avatar answered Oct 07 '22 00:10

Suvam Roy


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

like image 35
Sattar Hummatli Avatar answered Oct 06 '22 22:10

Sattar Hummatli


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).

like image 2
FooF Avatar answered Oct 07 '22 00:10

FooF