it-roy-ru.com

Как связать готовую общую библиотеку с проектом Android NDK?

Здесь я использовал этот файл Android.mk в папке jni/.

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.

Так что любое тело, пожалуйста, помогите мне решить эту проблему.

20
user1089679

Вот полный файл 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

и поместите libffmpeg.so в jni/armeabi/libffmpeg.so, jni/armeabi-v7a/libffmpeg.so и т. д.

35
Dan Brough

Вы должны сделать одно из следующих действий:

  1. Вырежьте и вставьте все, кроме LOCAL_PATH: = $ (call my-dir) из вашего второго Android.mk в ваш первый. 

  2. Поместите следующее в конце вашего первого Android.mk:

    $ (call import-module, packext)

    Также убедитесь, что в переменной среды NDK_MODULE_PATH указан путь, по которому можно найти файл Android.mk, определяющий пакетный текст модуля.

Вы также должны изменить LOCAL_SHARED_LIBRARIES так же, как mgiza сказал в первом ответе. Я предполагаю, что packageExtraction, на который вы получили неопределенную ссылку, находится в вашей предварительно собранной библиотеке, поэтому, если у вас нет других проблем со связыванием, это должно решить проблему.

2
Jake

Android NDK официальный hello-libs Пример CMake

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

Просто работал для меня на Ubuntu 17.10 Host, 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

  • расположение lib: 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/app на устройстве, libgperf.so также будет там.

  • Если вы поддерживаете только некоторые архитектуры, см .: только для Gradle Build NDK ARM

В примере git отслеживаются предварительно собранные общие библиотеки, но он также содержит систему сборки, которая фактически собирает их: https://github.com/googlesamples/Android-ndk/tree/840858984e1bb8a7fab37c1b7c571efbe7d6eb75/hello-libs/gen- libs

Посмотрите документацию ndk для сборок:

Android-NDK/Docs/PREBUILTS.html

Вы должны изменить

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

в

LOCAL_SHARED_LIBRARIES := packext

Убедитесь, что ваша папка, содержащая Android.mk для модуля packext, называется packext и находится в вашем NDK_MODULE_PATH.

0
mgiza