Android NDK - 如何静态地将C ++库与另一个C ++库链接

时间:2011-09-09 20:41:51

标签: android-ndk static-linking

我有一个名为 mylib 的C ++库,使用CYGWIN下的Android NDK r6b的ndk-build编译。生成的库文件名为 libmylib.so

我有一个名为 helloworld 的简单应用,其中包含mylib的.hpp文件,必须与libmylib.so链接。

我能够编译helloworld,告诉链接器查找libmylib.so。 “奇怪”的事实是:

  1. libmylib.so未与libhelloworld.so合并,因此我必须手动将libmylib.so复制到目录helloworld / libs / armeabi
  2. 在java代码中,我必须使用System.loadLibrary显式加载mylib,我必须在加载helloworld库之前加载mylib(即:System.loadLibrary("mylib"); System.loadLibrary("ndkfoo");),否则应用程序崩溃。
  3. 如果我做1和2,该应用程序完美运行(在模拟器和真实设备上都进行了测试)。我想知道如何强制链接器生成与libmylib.so合并的libhelloworld.so,以避免上面提到的1,2和3。

    感谢。

    的PS。

    mylib的Android.mk是:

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

    如果我使用BUILD_SHARED_LIBRARY,我像往常一样得到了libmylib.so。如果我使用BUILD_STATIC_LIBRARY,则ndk-build不会生成.so或.a。我真的希望看到一个简单的教程,解释如何构建一个JNI应用程序(使用JAVA + c ++代码),该应用程序使用用C ++编写的外部库并放在另一个目录中(不是应用程序的jni目录)。

    PSS的。 当我使用BUILD_STATIC_LIBRARY mylib编译时,我获得以下内容(基本上,创建的唯一文件位于dir / mylib / libs / armeabi /下,并且称为gdb.setup和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-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
    

2 个答案:

答案 0 :(得分:0)

将mylib构建为静态库而不是共享对象(.so文件)。然后,在定义helloworld的Android.mk中,将静态库列为依赖项:

LOCAL_STATIC_LIBRARIES := libmylib

答案 1 :(得分:0)

注意到,在您列出的Android.mk文件的末尾有

#include $(BUILD_STATIC_LIBRARY)

代替:

include $(BUILD_STATIC_LIBRARY)

稍后可能是您需要的。请注意,“固定”版本中的哈希标签已被排除。我发现了这个异常,并用google搜索了一个示例android.mk文件。我单击的第一个,果然是关于Hello-World的示例,与您可能想做的类似。希望有帮助。

**编辑: 即使我的回答解决了您的某些问题,仍应听取NuSkooler的建议。他的答案描述了make文件如何“看到” mylib.a文件的名称。相信他,如果您使用libmylib而不是mylib.a它将起作用。我已经在MinCC32等GCC编译器的make文件中完成了此操作。 **

相关问题