web-dev-qa-db-ja.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フォルダを1つ作成し、ビルド済みの.soライブラリを配置して、以下を含むAndroid.mkファイルを1つ作成します。

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ライブラリにリンクできません。

だから、どんな体でもこの問題を解決するのを助けてください。

23
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

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)
    
  • 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 target only ARM

サンプルのgitはビルド済みの共有ライブラリを追跡しますが、実際にそれらをビルドするためのビルドシステムも含まれています : libs/gen-libs

次のいずれかを実行する必要があります。

  1. 2番目のAndroid.mkからLOCAL_PATH:= $(call my-dir)を除くすべてを最初のAndroid.mkにカットアンドペーストします。

  2. 最初のAndroid.mkの最後に以下を配置します。

    $(call import-module、packext)

    また、NDK_MODULE_PATH環境変数を、モジュールpackextを定義するAndroid.mkファイルが見つかるパスに設定していることを確認してください。

Mgizaが最初の回答で言ったのと同じ方法で、LOCAL_SHARED_LIBRARIESも変更する必要があります。未定義の参照を取得したpackageExtractionは、ビルド済みのライブラリにあると考えられるため、他のリンクの問題がない限り、これで問題を解決できます。

2
Jake

ビルド済みの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にあることを確認してください。

0
mgiza