web-dev-qa-db-ja.com

Android St​​udioのJNIとGradle

アプリにネイティブコードを追加しようとしています。 Eclipseプロジェクトと同じように、../main/jniにすべてがあります。 ndk.dir=...local.propertiesに追加しました。私はまだ他に何もしていません(実際に他に何が必要なのかわかりません。ビルドしようとすると、次のエラーが表示されます。

Execution failed for task ':app:compileDebugNdk'.
> com.Android.ide.common.internal.LoggedErrorException: Failed to run command:
    /Users/me/Android-ndk-r8e/ndk-build NDK_PROJECT_PATH=null 
APP_BUILD_SCRIPT=/Users/me/Project/app/build/ndk/debug/Android.mk APP_PLATFORM=Android-19 
NDK_OUT=/Users/me/Project/app/build/ndk/debug/obj 
NDK_LIBS_OUT=/Users/me/Project/app/build/ndk/debug/lib APP_ABI=all

  Error Code:
    2
  Output:
    make: *** No rule to make target `/Users/me/Project/webapp/build/ndk/debug//Users/me/Project/app/src/main/jni/jni_part.cpp',
 needed by `/Users/me/Project/app/build/ndk/debug/obj/local/armeabi-v7a/objs/webapp//Users/me/Project/app/src/main/jni/jni_part.o'.  
Stop.

何をする必要がありますか?

Android.mk:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

# OpenCV
OPENCV_CAMERA_MODULES:=on
OPENCV_INSTALL_MODULES:=on
include .../OpenCV-2.4.5-Android-sdk/sdk/native/jni/OpenCV.mk

LOCAL_MODULE    := native_part
LOCAL_SRC_FILES := jni_part.cpp
LOCAL_LDLIBS +=  -llog -ldl

include $(BUILD_SHARED_LIBRARY)

Application.mk:

APP_STL := gnustl_static
APP_CPPFLAGS := -frtti -fexceptions
APP_ABI := armeabi armeabi-v7a
APP_PLATFORM := Android-8
73
fredley

Gradle Build Tools 2.2.0+-NDKが「マジック」と呼ばれるようになった最も近いもの

実験的で率直にNDKとそのすべてのハッカーにうんざりするのを避けるために、Gradle Build Toolsの2.2.xがリリースされ、現在は正常に動作することを嬉しく思います。キーは、externalNativeBuildで、Android.mkndkBuildパス引数を指すか、ndkBuildcmakeに変更し、CMakeLists.txtビルドスクリプトでパス引数を指すことです。

Android {
    compileSdkVersion 19
    buildToolsVersion "25.0.2"

    defaultConfig {
        minSdkVersion 19
        targetSdkVersion 19

        ndk {
            abiFilters 'armeabi', 'armeabi-v7a', 'x86'
        }

        externalNativeBuild {
            cmake {
                cppFlags '-std=c++11'
                arguments '-DANDROID_TOOLCHAIN=clang',
                        '-DANDROID_PLATFORM=Android-19',
                        '-DANDROID_STL=gnustl_static',
                        '-DANDROID_ARM_NEON=TRUE',
                        '-DANDROID_CPP_FEATURES=exceptions rtti'
            }
        }
    }

    externalNativeBuild {
        cmake {
             path 'src/main/jni/CMakeLists.txt'
        }
        //ndkBuild {
        //   path 'src/main/jni/Android.mk'
        //}
    }
}

詳細については、 ネイティブコードの追加に関するGoogleのページ を参照してください。

これが正しくセットアップされたら、./gradlew installDebugを実行してすぐに作業を開始できます。また、Android NDKではgccが廃止されているため、NDKがclangに移行していることにも注意する必要があります。

Android Studio Clean and Build Integration-非推奨

他の回答は、Android.mkファイルの自動作成を防ぐ正しい方法を示していますが、Android St​​udioとの統合を強化するための追加のステップを実行できません。コマンドラインに移動することなく、ソースから実際にクリーンアップしてビルドする機能を追加しました。 local.propertiesファイルにはndk.dir=/path/to/ndkが必要です

apply plugin: 'com.Android.application'

Android {
    compileSdkVersion 14
    buildToolsVersion "20.0.0"

    defaultConfig {
        applicationId "com.example.application"
        minSdkVersion 14
        targetSdkVersion 14

        ndk {
            moduleName "YourModuleName"
        }
    }

    sourceSets.main {
        jni.srcDirs = [] // This prevents the auto generation of Android.mk
        jniLibs.srcDir 'src/main/libs' // This is not necessary unless you have precompiled libraries in your project.
    }

    task buildNative(type: Exec, description: 'Compile JNI source via NDK') {
        def ndkDir = Android.ndkDirectory
        commandLine "$ndkDir/ndk-build",
                '-C', file('src/main/jni').absolutePath, // Change src/main/jni the relative path to your jni source
                '-j', Runtime.runtime.availableProcessors(),
                'all',
                'NDK_DEBUG=1'
    }

    task cleanNative(type: Exec, description: 'Clean JNI object files') {
        def ndkDir = Android.ndkDirectory
        commandLine "$ndkDir/ndk-build",
                '-C', file('src/main/jni').absolutePath, // Change src/main/jni the relative path to your jni source
                'clean'
    }

    clean.dependsOn 'cleanNative'

    tasks.withType(JavaCompile) {
        compileTask -> compileTask.dependsOn buildNative
    }
}

dependencies {
    compile 'com.Android.support:support-v4:20.0.0'
}

src/main/jniディレクトリは、プロジェクトの標準レイアウトを想定しています。このbuild.gradleファイルの場所からjniディレクトリへの相対パスである必要があります。

Gradle-問題がある人向け

これも確認してください Stack Overflow answer

あなたのgradleバージョンと一般的なセットアップが正しいことは本当に重要です。古いプロジェクトがある場合は、最新のAndroid St​​udioで新しいプロジェクトを作成し、Googleが標準プロジェクトと見なすものを確認することを強くお勧めします。また、gradlewを使用します。これにより、開発者はgradleバージョンの不一致から保護されます。最後に、gradleプラグインを正しく構成する必要があります。

そして、あなたはgradleプラグインの最新バージョンは何ですか? ツールページを確認 に応じてバージョンを編集します。

最終製品-/build.gradle

// Top-level build file where you can add configuration options common to all sub-projects/modules.

// Running 'gradle wrapper' will generate gradlew - Getting gradle wrapper working and using it will save you a lot of pain.
task wrapper(type: Wrapper) {
    gradleVersion = '2.2'
}

// Look Google doesn't use Maven Central, they use jcenter now.
buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.Android.tools.build:gradle:1.2.0'

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        jcenter()
    }
}

gradle wrappergradlewファイルとgradle/wrapperサブディレクトリを生成することを確認してください。これは大きな落とし穴です。

ndkDirectory

これは何度も登場しましたが、Android.ndkDirectoryが1.1以降のフォルダーを取得する正しい方法です。 Gradleプロジェクトのバージョン1.0.0への移行 。プラグインの実験的または古いバージョンを使用している場合、走行距離は異なる場合があります。

117

gradleは、ソースへの絶対パスで別のAndroid.mkファイルを生成することにより、ndkコンパイルをサポートします。 NDKは、OSXではr9、Windowsではr9c以降の絶対パスをサポートしているため、NDKをr9 +にアップグレードする必要があります。

GradleによるNDKサポートは暫定的なものであるため、他の問題が発生する可能性があります。その場合、次を設定することにより、gradleからndkコンパイルを無効にできます。

sourceSets.main {
    jni.srcDirs = []
    jniLibs.srcDir 'src/main/libs'
}

自分でndk-buildを呼び出して、libs /からlibsを統合できるようにします。

ところで、x86のコンパイルに問題がありますか? APP_ABIに含まれていないようです。

72
ph0b

私の場合、私はWindowsを使用していますが、上記のCameronの回答に従うと、ndk-buildのフルネームndk-build.cmdを使用した場合にのみ機能します。アプリを動作させる前にプロジェクトのクリーンと再構築、そしてエミュレータの再起動を行う必要があります(実際にサンプルHelloJniをNDKからAndroidにインポートしました) _ Studio)。ただし、NDKへのパスにスペースが含まれていないを確認してください。

最後に、私のbuild.gradleは以下のように完全にリストされています。

apply plugin: 'com.Android.application'

Android {
    compileSdkVersion 21
    buildToolsVersion "21.1.2"

    defaultConfig {
        applicationId "com.example.hellojni"
        minSdkVersion 4
        targetSdkVersion 4

        ndk {
            moduleName "hello-jni"
        }

        testApplicationId "com.example.hellojni.tests"
        testInstrumentationRunner "Android.test.InstrumentationTestRunner"
    }
    sourceSets.main {
        jni.srcDirs = [] // This prevents the auto generation of Android.mk
//        sourceSets.main.jni.srcDirs = []
        jniLibs.srcDir 'src/main/libs' // This is not necessary unless you have precompiled libraries in your project.
    }

    task buildNative(type: Exec, description: 'Compile JNI source via NDK') {
        def ndkDir = Android.plugin.ndkFolder
        commandLine "$ndkDir/ndk-build.cmd",
                '-C', file('src/main/jni').absolutePath, // Change src/main/jni the relative path to your jni source
                '-j', Runtime.runtime.availableProcessors(),
                'all',
                'NDK_DEBUG=1'
    }

    task cleanNative(type: Exec, description: 'Clean JNI object files') {
        def ndkDir = Android.plugin.ndkFolder
        commandLine "$ndkDir/ndk-build.cmd",
                '-C', file('src/main/jni').absolutePath, // Change src/main/jni the relative path to your jni source
                'clean'
    }

    clean.dependsOn 'cleanNative'

    tasks.withType(JavaCompile) {
        compileTask -> compileTask.dependsOn buildNative
    }

}


dependencies {
    compile 'com.Android.support:support-v4:21.0.3'
}
7
Brian Ng

OSXでの私の問題は、gradleバージョンでした。 Gradleは私のAndroid.mkを無視していました。したがって、このオプションをオーバーライドし、代わりに自分のmakeを使用するには、次の行を入力しました。

sourceSets.main.jni.srcDirs = []

build.gradleAndroidタグ内。

私はこれに多くの時間を無駄にしました!

5
Paschalis

Android Studio 2.2は、ndk-buildとcMakeを使用する機能を備えています。ただし、Application.mkのサポートを2.2.3まで待つ必要がありました。私はそれを試しましたが、うまくいきます...しかし、私の変数はデバッガに現れません。ただし、コマンドラインからクエリを実行することはできます。

このようなことをする必要があります:

externalNativeBuild{
   ndkBuild{
        path "Android.mk"
    }
}

defaultConfig {
  externalNativeBuild{
    ndkBuild {
      arguments "NDK_APPLICATION_MK:=Application.mk"
      cFlags "-DTEST_C_FLAG1"  "-DTEST_C_FLAG2"
      cppFlags "-DTEST_CPP_FLAG2"  "-DTEST_CPP_FLAG2"
      abiFilters "armeabi-v7a", "armeabi"
    }
  } 
}

http://tools.Android.com/tech-docs/external-c-builds を参照してください

NB:externalNativeBuild内のdefaultConfigの追加のネストは、Android St​​udio 2.2 Preview 5で導入された重大な変更でした(2016年7月8日) 。上記のリンクのリリースノートを参照してください。

5
Ronnie

モジュールbuild.gradleのタスクフィールドで、以下を使用しない限りエラーが発生します。

def ndkDir = plugins.getPlugin('com.Android.application').sdkHandler.getNdkFolder()

使用している人を見る

def ndkDir = Android.plugin.ndkFolder

そして

def ndkDir = plugins.getPlugin('com.Android.library').sdkHandler.getNdkFolder()

しかし、実際にインポートしていたプラグインに変更するまで、どちらも機能しませんでした。

1
videogameboy76