web-dev-qa-db-ja.com

NDKを使用してコンパイル済みの静的ライブラリを含める

Android Studio NDKプロジェクトに事前コンパイルされた静的ライブラリを含めます。Android Studio 1.0.1を使用しています。 SO=でこの問題を試すことは時代遅れであるように見えます(または、ライブラリプロジェクトの作成とそれを含むことを含みます)。

構造は次のとおりです。

app
/--src
/--main
/--Java
+--jni
+--jniLibs
   /--armeabi
       /--libpng.a
    --armeabiv7
       /--libpng.a
    ...(for each abi)

ライブラリlibpngを含めようとしています。 ph0b (素晴らしいガイド、btw)に従ってjniLibsを作成して、それぞれのABIフォルダーにlibpng.aを追加してみました。これでもエラーが発生します-が見つかりません-llibpng以下のコードでコンパイルしようとすると:

ndk {
        moduleName "game" 
        cFlags "-std=c++11 -fexceptions -DANDROID -I${project.buildDir}/../src/main/jni/include \
                -I${project.buildDir}/../src/main/jni/include/png"
        ldLibs "EGL", "GLESv3", "dl", "log", "Android", "libpng"
        stl "gnustl_static"
}
18
zmartin

これは、実験的なプラグインを介して正しく動作するようになりました。

完全な説明については、 この優れた記事全体 を参照してください。これは私がこれを取得した場所ですが、私自身も使用しており、動作します。

これは私の build.gradle-私の場合はライブラリプロジェクト用であり、共有ではなく静的リンクを使用していることに注意してください。

buildscript {
    dependencies
            {
                classpath "com.Android.tools.build:gradle-experimental:0.7.0-alpha3"
            }
}
apply plugin: 'com.Android.model.library'

model {
    repositories {
        libs(PrebuiltLibraries) {
            v8_base {
                binaries.withType(StaticLibraryBinary) {
                    staticLibraryFile = file("src/main/jni/libs/${targetPlatform.getName()}/libv8_base.a")
                }
            }
            v8_libbase {
                binaries.withType(StaticLibraryBinary) {
                    staticLibraryFile = file("src/main/jni/libs/${targetPlatform.getName()}/libv8_libbase.a")
                }
            }
            v8_libplatform {
                binaries.withType(StaticLibraryBinary) {
                    staticLibraryFile = file("src/main/jni/libs/${targetPlatform.getName()}/libv8_libplatform.a")
                }
            }
            v8_nosnapshot {
                binaries.withType(StaticLibraryBinary) {
                    staticLibraryFile = file("src/main/jni/libs/${targetPlatform.getName()}/libv8_nosnapshot.a")
                }
            }
        }
    }

    Android {

        compileSdkVersion 23
        buildToolsVersion "23.0.2"

        sources {
            main {
                jni {
                    source {
                        srcDir "src/main/jni"
                    }
                    dependencies {
                        library "v8_base" linkage "static"
                        library "v8_libbase" linkage "static"
                        library "v8_libplatform" linkage "static"
                        library "v8_nosnapshot" linkage "static"
                    }
                }
            }
        }

        ndk {
            moduleName "v8example"
            cppFlags.add("-std=c++11")
            cppFlags.add("-I${file("src/main/jni/include")}".toString())
            cppFlags.add("-fexceptions")
            ldLibs.add("log")
            stl "stlport_static"
            abiFilters.add("armeabi armeabi-v7a x86")
        }
    }
}

別の方法は、ndkBuildを自分で呼び出すという古いGradleアプローチを使用することです。つまり、.mkファイル。これも問題なく機能しますが、Android Studioとの統合が失われます。たとえば、jniファイルが適切に表示されます。

3
Rob Pridham

.soファイルだけを含めることはできません。これらの.soファイルのメソッドにアクセスするためのインターフェースを実際に提供するsrcフォルダーも必要です。その方法でプロジェクトをライブラリに結合しないことをお勧めします。

最善の方法は、Android studioからライブラリモジュールとしてインクルードし、jniフォルダーを破棄してndkbuildを無効にし、次のbuild.gradleファイルにjlibを/ libsフォルダーにポイントさせることです。

jni.srcDirs = [] //disable automatic ndk-build call
jniLibs.srcDirs = [ 'libs' ] //no need to copy the .so files from /libs to /jniLibs folder

(libsディレクトリもAndroid studio with .soファイル)によって正しくインポートされていることを確認してください)

ライブラリをモジュールとしてインポートすると、自動的に次の処理が行われます

a)yourlibraryプロジェクトフォルダー内のライブラリフォルダーであり、gradle規則に従って再構成されているb)プロジェクトをインポートした(settings.gradleに ':yourlibrary'を含める)および
c)作成された依存関係(「ファイル->プロジェクト構造->左側のサブウィンドウからメインアプリモジュールを選択->依存関係(最後のタブ)->右側にある緑色の「+」を押します-> yourlibrary as Module Dependency-> OK”)

1
Aavaas

Android Studio 1.0.2に.soライブラリを追加する

  1. 「src/main /」内に「jniLibs」フォルダを作成します
  2. すべての.soライブラリを「src/main/jniLibs」フォルダ内に配置します
  3. フォルダ構造は次のようになります
    |-アプリ:
    | --src:
    |-|-| --main
    |-|-|-| --jniLibs
    |-|-|-|-| --armeabi
    |-|-|-|-|-|-。soファイル
  4. プロジェクトを同期してアプリケーションを実行するだけで、追加のコードは不要です。

    参照
    ---(https://github.com/commonsguy/sqlcipher-gradle/tree/master/src/main
1
Vasanth

NdkのサポートはGradleで制限されているため、異なるabiの静的ライブラリに対してこれを試すことができます。

    ndk {
        moduleName "game" 
        ....
        ldLibs ..., file(projectDir).absolutePath+"/src/main/jniLibs/\$(TARGET_Arch_ABI)/libpng.a"
        ....
    }
1
user4958329

これは本当に醜いですが、うまくいきます! Gradleをだまして、生成されたAndroid.mkファイルにコードを挿入することができます。

    ndk {
        abiFilter "armeabi-v7a"

        // We need to inject the static library into the
        // NDK build, and Gradle doesn't offer a way to directly
        // modify the Android.mk file... So we hack it!
        //
        // You can see the end result at:
        //   build/intermediates/ndk/debug/Android.mk

        moduleName "This_is_a_terrible_Gradle_hack\n" +

        "include \$(CLEAR_VARS)\n" +

        "LOCAL_MODULE := mystaticlib_prebuilt\n" +
        "LOCAL_EXPORT_C_INCLUDES := mystaticlib/include\n" +
        "LOCAL_SRC_FILES := mystaticlib/libmystaticlib.a\n" +

        "include \$(PREBUILT_STATIC_LIBRARY)\n" +

        "include \$(CLEAR_VARS)\n" +
        "LOCAL_MODULE := MyActualModule\n" +
        "LOCAL_STATIC_LIBRARIES += mystaticlib_prebuilt"

        cFlags "-std=c++11 -fexceptions -frtti -pthread"
        stl "gnustl_shared"
        ldLibs "log", "OpenSLES", "z"
    }
0
Keith