76

アプリにネイティブ コードを追加しようとしています。../main/jniEclipse プロジェクトと同じように、すべてが入っています。に追加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)

アプリケーション.mk:

APP_STL := gnustl_static
APP_CPPFLAGS := -frtti -fexceptions
APP_ABI := armeabi armeabi-v7a
APP_PLATFORM := android-8
4

6 に答える 6

124

Gradle Build Tools 2.2.0+ - NDK が「魔法」と呼ばれるのに最も近いもの

実験的で率直に言って、NDK とそのすべてのハッカーにうんざりしていることを避けようとする中で、Gradle Build Tools の 2.2.x が出てきて、今ではうまく機能することをうれしく思います。重要なのは、ビルド スクリプトのパス引数をor に変更し、パス引数をポイントするexternalNativeBuildand ポインティングndkBuildパス引数です。Android.mkndkBuildcmakeCMakeLists.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 のクリーンとビルドの統合 - 非推奨

他の回答は、ファイルの自動作成を防ぐための正しい方法を指摘していますAndroid.mkが、Android Studio との統合を改善するための追加の手順に進むことができません。コマンドラインに移動する必要なく、ソースから実際にクリーンアップしてビルドする機能を追加しました。あなたの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 - 問題を抱えている人向け

このスタック オーバーフローの回答も確認してください。

Gradle のバージョンと一般的な設定が正しいことが非常に重要です。古いプロジェクトがある場合は、最新の Android Studio で新しいプロジェクトを作成し、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 wrapperが生成されていることを確認してください。これは大きな落とし穴です。gradlewgradle/wrapper

ndkディレクトリ

これは何度も出てきましたが、android.ndkDirectory1.1 以降のフォルダーを取得する正しい方法です。Gradle プロジェクトをバージョン 1.0.0 に移行します。プラグインの実験的または古いバージョンを使用している場合、マイレージは異なる場合があります.

于 2014-11-01T21:18:17.980 に答える
74

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/ からライブラリを統合できるようにします。

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

于 2014-01-14T10:40:19.580 に答える
2

モジュール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()

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

于 2015-06-26T22:10:07.783 に答える