1. ホーム
  2. android

Android StudioのJNIとGradle

2023-08-30 01:05:30

質問

自分のアプリにネイティブコードを追加しようとしています。私はすべてを ../main/jni にあるように、Eclipse プロジェクトで 私は 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

どのように解決するのですか?

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

実験的なことを避けるために、そして率直に言って NDK とそのすべてのハッカー行為にうんざりしていたところ、Gradle Build Tools の 2.2.x が出てきて、それがちょうど動作するようになったので満足しています。キーとなるのは externalNativeBuild とポインティングすることです。 ndkBuild のパス引数を Android.mk または変更 ndkBuildcmake を指し、path引数を 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 のクリーンアップとビルドの統合 - 非推奨

他の回答は、自動生成された を防ぐための正しい方法を指摘しています。 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 - 問題がある人のために

こちらもご覧ください Stack Overflow の回答 .

あなたの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 wrappergradlew ファイルを生成し gradle/wrapper サブディレクトリの中にあります。これは大きなガッカリです。

ndkDirectory

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