如何将一个预编译的共享库链接到 Android NDK 项目?

24

我在 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命令时,我收到了"undefined reference to packageExtraction"的错误。这里我使用了预编译库函数,也就是说我无法将我的预编译共享库链接到我的offlinedownload库。

所以请帮我解决这个问题,谢谢!


请您详细解释一下您的问题好吗? - Nimit
4个回答

37
这是一个完整的Android.mk文件,用于使用第三方共享库。 该库(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文件。


1
我修改了示例以展示如何支持多种架构。 - Dan Brough
@danbrough 我需要你的帮助。 - Neha Shukla
还可以将外部库放在 jniLibs/... 中并使用:LOCAL_SRC_FILES := ..\jniLibs\$(TARGET_ARCH_ABI)\libffmpeg.so - Francois
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Dan Brough
最终应该把共享库添加到哪里?!PREBUILT_SHARED_LIBRARY?LOCAL_JNI_SHARED_LIBRARIES?LOCAL_SHARED_LIBRARIES? - Dr.jacky
显示剩余2条评论

9
Android NDK官方hello-libs CMake示例

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)
    
  • on C++ code, use: #include <gperf.h>

  • header location: hello-libs/distribution/gperf/include/gperf.h

  • lib location: 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']
    

    Then, if you look under /data/app on the device, libgperf.so will be there as well.

  • If you only support some architectures, see: Gradle Build NDK target only ARM

该示例 Git 跟踪预构建的共享库,但它还包含了实际构建这些库的构建系统:https://github.com/googlesamples/android-ndk/tree/840858984e1bb8a7fab37c1b7c571efbe7d6eb75/hello-libs/gen-libs

2
您需要执行以下操作之一:
  1. 从第二个 Android.mk 中除了 LOCAL_PATH := $(call my-dir) 以外的所有内容复制并粘贴到您的第一个文件中。

  2. 在第一个 Android.mk 的末尾添加以下内容:

    $(call import-module,packext)

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

您还需要按照 mgiza 在第一个答案中提到的方式更改 LOCAL_SHARED_LIBRARIES。我假设您得到 undefined reference to packageExtraction 的错误是因为预构建库中缺少链接问题,所以这应该可以解决该问题。


0

请查看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文件夹。 - user1089679

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接