开发者

Android NDK - how to link a C++ library statically with another C++library

I have a C++ lib called mylib, compiled with ndk-build of Android NDK r6b under CYGWIN. The resulting library file is called libmylib.so.

I have a simple app called helloworld that includes the .hpp files of mylib and have to be linked with libmylib.so.

I am able to compile helloworld, telling the linker to look for libmylib.so. The "strange" facts are:

  1. libmylib.so is not merged with libhelloworld.so, so i have to copy libmylib.so into the directory helloworld/libs/armeabi manually
  2. in the java code, i have to load explicitly mylib with System.loadLibrary and i have to load mylib BEFORE i load helloworld library (that is: System.loadLibrary("mylib"); System.loadLibrary("ndkfoo");), otherwise the app crashes.

If i do 1 and 2, the app works perfectly (tested both on the emulator and on a real device). I would like to know how can to force the linker to produce a libhelloworld.so merged with libmylib.so, so to avoid 1,2 and 3 as mentioned above.

Thanks.

Ps.

The Android.mk of mylib is:

LOCAL_PATH := $(call my-dir) 
include $(CLEAR_VARS)
LOCAL_MODULE    := mylib
LOCAL_SRC_FILES := mylib.cpp 
include $(BUILD_SHARED_LIBRARY)
#include $(BUILD_STATIC_LIBRARY)

If i use BUILD_SHARED_LIBRARY, i got libmylib.so as usual. If i use, instead, BUILD_STATIC_LIBRARY, no .so or .a is generated by ndk-build. I really would like to see a simple tutorial which explains how to build a JNI app (with JAVA + c++ code) that uses an external library written in C++ and placed in another directory (not the jni directory of the app).

Pss. When i compile with BUILD_STATIC_LIBRARY mylib, i obtain the following (basically, the only file created are under the dir /mylib/libs/armeabi/ and are called gdb.setup and gdbserver):

$ /cygdrive/d/android/android-ndk-r6b/ndk-build NDK_LOG=1 V=1 -B
Android NDK: NDK installation path auto-detected: '/cygdrive/d/android/android-n
dk-r6b'
Android NDK: GNU Make version 3.81 detected
Android NDK: Host OS was auto-开发者_JS百科detected: windows
Android NDK: Host CPU was auto-detected: x86
Android NDK: HOST_TAG set to windows
Android NDK: Host awk tool was auto-detected: awk
Android NDK: Host awk test returned: Pass
Android NDK:  Probing for 'cygpath' program
Android NDK:  'cygpath' found as: /usr/bin/cygpath
Using cygwin substitution rules:
/cygdrive/d => D:
/cygdrive/c => C:
/cygdrive/D => D:
/cygdrive/C => C:
/usr/lib => C:/cygwin/lib
/usr/bin => C:/cygwin/bin
/ => C:/cygwin
Android NDK:  This NDK supports the following toolchains and target ABIs:
Android NDK:    arm-linux-androideabi-4.4.3:  armeabi armeabi-v7a
Android NDK:    x86-4.4.3:  x86
Android NDK: Found platform root directory: /cygdrive/d/android/android-ndk-r6b/
platforms
Android NDK: Found supported platforms: android-3 android-4 android-5 android-8
android-9
Android NDK: PLATFORM android-3 supports: arm x86
Android NDK:   ABI arm sysroot is: /cygdrive/d/android/android-ndk-r6b/platforms
/android-3/arch-arm
Android NDK:   ABI x86 sysroot is: /cygdrive/d/android/android-ndk-r6b/platforms
/android-3/arch-x86
Android NDK: PLATFORM android-4 supports: arm x86
Android NDK:   ABI arm sysroot is: /cygdrive/d/android/android-ndk-r6b/platforms
/android-4/arch-arm
Android NDK:   ABI x86 sysroot is: /cygdrive/d/android/android-ndk-r6b/platforms
/android-4/arch-x86
Android NDK: PLATFORM android-5 supports: arm x86
Android NDK:   ABI arm sysroot is: /cygdrive/d/android/android-ndk-r6b/platforms
/android-5/arch-arm
Android NDK:   ABI x86 sysroot is: /cygdrive/d/android/android-ndk-r6b/platforms
/android-5/arch-x86
Android NDK: PLATFORM android-8 supports: arm x86
Android NDK:   ABI arm sysroot is: /cygdrive/d/android/android-ndk-r6b/platforms
/android-8/arch-arm
Android NDK:   ABI x86 sysroot is: /cygdrive/d/android/android-ndk-r6b/platforms
/android-8/arch-x86
Android NDK: PLATFORM android-9 supports: arm x86
Android NDK:   ABI arm sysroot is: /cygdrive/d/android/android-ndk-r6b/platforms
/android-9/arch-arm
Android NDK:   ABI x86 sysroot is: /cygdrive/d/android/android-ndk-r6b/platforms
/android-9/arch-x86
Android NDK: Found stable platform levels: 3 4 5 8 9
Android NDK: Found max platform level: 9
Android NDK: Looking for AndroidManifest.xml in /cygdrive/d/android/workspace/my
lib/jni
Android NDK: Looking for AndroidManifest.xml in /cygdrive/d/android/workspace/my
lib
Android NDK:     Found it !
Android NDK: Found project path: /cygdrive/d/android/workspace/mylib
Android NDK: Parsing /cygdrive/d/android/workspace/mylib/jni/Application.mk
Android NDK:   Found APP_PLATFORM=android-9 in /cygdrive/d/android/workspace/myl
ib/default.properties
Android NDK:   Defaulted to APP_BUILD_SCRIPT=/cygdrive/d/android/workspace/mylib
/jni/Android.mk
Android NDK: Application 'local' *is* debuggable
Android NDK: Selecting debug optimization mode (app is debuggable)
Android NDK: Adding import directory: /cygdrive/d/android/android-ndk-r6b/source
s
Android NDK: Building application 'local' for ABI 'armeabi'
Android NDK: Using target toolchain 'arm-linux-androideabi-4.4.3' for 'armeabi'
ABI
Android NDK: Looking for imported module with tag 'cxx-stl/system'
Android NDK:   Probing /cygdrive/d/android/android-ndk-r6b/sources/cxx-stl/syste
m/Android.mk
Android NDK:     Found in /cygdrive/d/android/android-ndk-r6b/sources/cxx-stl/sy
stem
Android NDK: Module 'mylib' has C++ sources
rm -f /cygdrive/d/android/workspace/mylib/libs/armeabi/lib*.so /cygdrive/d/andro
id/workspace/mylib/libs/armeabi-v7a/lib*.so /cygdrive/d/android/workspace/mylib/
libs/x86/lib*.so
rm -f /cygdrive/d/android/workspace/mylib/libs/armeabi/gdbserver /cygdrive/d/and
roid/workspace/mylib/libs/armeabi-v7a/gdbserver /cygdrive/d/android/workspace/my
lib/libs/x86/gdbserver
rm -f /cygdrive/d/android/workspace/mylib/libs/armeabi/gdb.setup /cygdrive/d/and
roid/workspace/mylib/libs/armeabi-v7a/gdb.setup /cygdrive/d/android/workspace/my
lib/libs/x86/gdb.setup
Gdbserver      : [arm-linux-androideabi-4.4.3] libs/armeabi/gdbserver
mkdir -p /cygdrive/d/android/workspace/mylib/libs/armeabi
install -p /cygdrive/d/android/android-ndk-r6b/toolchains/arm-linux-androideabi-
4.4.3/prebuilt/gdbserver /cygdrive/d/android/workspace/mylib/libs/armeabi/gdbser
ver
Gdbsetup       : libs/armeabi/gdb.setup
mkdir -p /cygdrive/d/android/workspace/mylib/libs/armeabi
echo "set solib-search-path D:/android/workspace/mylib/obj/local/armeabi" > /cyg
drive/d/android/workspace/mylib/libs/armeabi/gdb.setup
echo "directory D:/android/android-ndk-r6b/platforms/android-9/arch-arm/usr/incl
ude D:/android/android-ndk-r6b/sources/cxx-stl/system/include D:/android/workspa
ce/mylib/jni" >> /cygdrive/d/android/workspace/mylib/libs/armeabi/gdb.setup


Build mylib as a static library instead of a Shared Object (a .so file). Then, in your Android.mk which defines helloworld, list the static library as a dependency:

LOCAL_STATIC_LIBRARIES := libmylib


Noticed that in what you listed for your Android.mk file you have at the very end:

#include $(BUILD_STATIC_LIBRARY)

instead of:

include $(BUILD_STATIC_LIBRARY)

The later is probably what you need. Notice the exclusion of the hash-tag in the 'fixed' version. I found this anomaly and googled for an example android.mk file. The first one I clicked and sure enough, it was for a Hello-World example similar to what you are probably trying to do. Hope that helps.

**Edit: Even if my answer fixes some of your issues, still heed the advice from NuSkooler. His answer describes how the make files "sees" the name of your mylib.a file. Trust him, if you put libmylib instead of mylib.a it will work. I've done it in make files for GCC compilers such as MinGW32. **

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜