【问题标题】:How to link a prebuilt shared Library to an Android NDK project?如何将预构建的共享库链接到 Android NDK 项目?
【发布时间】:2012-04-09 20:33:46
【问题描述】:

这里我使用了jni/文件夹中的Android.mk文件。

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

# Here we give our module name and source file(s)
LOCAL_MODULE    := offlineDownload
LOCAL_SRC_FILES := offline_download.c

LOCAL_SHARED_LIBRARIES :=../lib/libpackext.so.1.0
LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -llog

include $(BUILD_SHARED_LIBRARY)

并在项目目录中创建一个lib 文件夹并将我的预构建.so 库放入一个包含以下内容的Android.mk 文件

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := packext
LOCAL_SRC_FILES := libpackext.so.1.0
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../include

include $(PREBUILT_SHARED_LIBRARY)

当我使用ndk-build -B 命令时,我得到了对 packageExtraction 的未定义引用。在这里,我使用我的预建库函数意味着我无法将我的预建共享库链接到我的 offlinedownload 库。

所以请任何人帮我解决这个问题。

【问题讨论】:

  • 你能详细解释一下你的问题吗?

标签: android c android-ndk


【解决方案1】:

Android NDK 官方hello-libsCMake 示例

https://github.com/googlesamples/android-ndk/tree/840858984e1bb8a7fab37c1b7c571efbe7d6eb75/hello-libs

刚刚在 Ubuntu 17.10 主机、Android Studio 3、Android SDK 26、NDK 15.2 上为我工作。所以我强烈建议你以它为基础。

共享库名为libgperf,关键代码部分为:

  • hello-libs/app/src/main/cpp/CMakeLists.txt

    // -L
    add_library(lib_gperf SHARED IMPORTED)
    set_target_properties(lib_gperf PROPERTIES IMPORTED_LOCATION
              ${distribution_DIR}/gperf/lib/${ANDROID_ABI}/libgperf.so)
    
    // -I
    target_include_directories(hello-libs PRIVATE
                               ${distribution_DIR}/gperf/include)
    // -lgperf
    target_link_libraries(hello-libs
                          lib_gperf)
    
  • 在 C++ 代码上,使用:#include <gperf.h>

  • 标头位置:hello-libs/distribution/gperf/include/gperf.h

  • 库位置:distribution/gperf/lib/arm64-v8a/libgperf.so

  • app/build.gradle:

    android {
        sourceSets {
            main {
                // let gradle pack the shared library into apk
                jniLibs.srcDirs = ['../distribution/gperf/lib']
    

    然后,如果您在设备上查看/data/applibgperf.so 也会在那里。

  • 如果您只支持某些架构,请参阅:Gradle Build NDK target only ARM

示例 git 跟踪预构建的共享库,但它也包含构建系统以实际构建它们:https://github.com/googlesamples/android-ndk/tree/840858984e1bb8a7fab37c1b7c571efbe7d6eb75/hello-libs/gen-libs

【讨论】:

    【解决方案2】:

    这是一个完整的 Android.mk 文件,用于使用 3rd 方共享库。 库 (libffmpeg.so) 放在 jni 文件夹中。 它的“LOCAL_EXPORT_C_INCLUDES”指定了为库保存头文件的位置。

    LOCAL_PATH := $(call my-dir)
    
    include $(CLEAR_VARS)
    LOCAL_MODULE := ffmpeg
    LOCAL_SRC_FILES := libffmpeg.so
    LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/../../ffmpeg/libs/arm-linux-androideabi4.7_1/include
    include $(PREBUILT_SHARED_LIBRARY)
    
    
    include $(CLEAR_VARS)
    LOCAL_MODULE    := ffmpegandroid
    LOCAL_SRC_FILES := ffmpegandroid.c
    LOCAL_SHARED_LIBRARIES := ffmpeg
    include $(BUILD_SHARED_LIBRARY)
    

    如果您想支持多种架构,那么您可以指定:

    APP_ABI := armeabi armeabi-v7a x86 mips
    

    在您的 jni/Application.mk 中并将 LOCAL_SRC_FILES 更改为:

    LOCAL_SRC_FILES := $(TARGET_ARCH_ABI)/libffmpeg.so
    

    并在 jni/armeabi/libffmpeg.so、jni/armeabi-v7a/libffmpeg.so 等处放置一个 libffmpeg.so ..

    【讨论】:

    • 为什么 libffmpeg.so 需要在 jni 文件夹中?有了所有的架构,如何让它变得更容易?
    • 我修改了这个例子来展示如何支持多种架构。
    • @danbrough 我需要你的帮助
    • 也可以将外部库放在jniLibs/... 并使用:LOCAL_SRC_FILES := ..\jniLibs\$(TARGET_ARCH_ABI)\libffmpeg.so
    • 查看github.com/danbrough/andrudio 以获取为android 编译ffmpeg(或libav)的示例。
    【解决方案3】:

    您必须执行以下任一操作:

    1. 将除 LOCAL_PATH := $(call my-dir) 之外的所有内容从您的第二个 Android.mk 剪切并粘贴到您的第一个。

    2. 将以下内容放在您的第一个 Android.mk 的末尾:

      $(调用 import-module,packext)

      还要确保将 NDK_MODULE_PATH 环境变量设置为可以找到定义模块 packext 的 Android.mk 文件的路径。

    您还必须按照 mgiza 在第一个答案中所说的方式更改 LOCAL_SHARED_LIBRARIES。我想您未定义引用的 packageExtraction 位于您的预建库中,因此除非您有其他链接问题,否则这应该可以解决问题。

    【讨论】:

      【解决方案4】:

      查看预构建的 ndk 文档:

      android-ndk/docs/PREBUILTS.html

      你必须改变

      LOCAL_SHARED_LIBRARIES :=../lib/libpackext.so.1.0
      

      LOCAL_SHARED_LIBRARIES := packext
      

      确保包含 packext 模块的 Android.mk 的文件夹命名为 packext,并且可以在 NDK_MODULE_PATH 中找到。

      【讨论】:

      • 这里我将我的 Android.mk 和 libpackext.so.1.0 放在 lib 文件夹中。这个 lib 文件夹在项目目录路径中。我在哪里创建 jni 文件夹
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-28
      • 2011-08-08
      • 2011-09-04
      • 2015-04-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多