JNI и Gradle в Android Studio



Я пытаюсь добавить машинный код в мое приложение. У меня есть все в ../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)


Application.mk:



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

6 ответов:

Gradle Build Tools 2.2.0+ - самый близкий NDK когда-либо назывался "волшебным"

в попытке избежать экспериментальных и откровенно надоел NDK и все его hackery я рад, что 2.2.x инструментов сборки Gradle вышел, и теперь он просто работает. Ключ-это externalNativeBuild и указывая ndkBuild аргумент пути в Android.mk изменить ndkBuild до cmake и укажите аргумент path на A 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 и вперед. Вам также нужно будет знать, что NDK перемещается в clang, так как gcc теперь устарел в Android NDK.

Android-студия "очистить и построить" интеграция - устаревший

другие ответы указывают на правильный способ предотвращения автоматического создания 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'
}

The src/main/jni каталог предполагает стандартную компоновку проекта. Он должен быть родственником от этого build.gradle расположение файла

gradle поддерживает компиляцию ndk путем создания другого Android.mk файл с абсолютными путями к вашим источникам. NDK поддерживает абсолютные пути с r9 на OSX, r9c на Windows, поэтому вам нужно обновить NDK до r9+.

вы можете столкнуться с другими проблемами, поскольку поддержка NDK от gradle является предварительной. Если это так, вы можете отключить компиляцию ndk из gradle, установив:

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

чтобы иметь возможность вызывать ndk-построить себя и интегрировать библиотеки из libs/.

BtW, вы есть ли проблемы с компиляцией для x86 ? Я вижу, вы не включили его в свой APP_ABI.

в моем случае я нахожусь в Windows и следую ответу Кэмерона выше, только если вы используете полное имя ndk-build, которое ndk-build.cmd. Я должен очистить и перестроить проект, потом перезапустить эмулятор перед началом работы приложения (на самом деле я импортировал образец HelloJni из NDK, в Android Studio). Однако, убедитесь путь к NDK не содержит пробел.

наконец, моя сборка.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'
}

моя проблема на OSX это была версия gradle. Gradle в не обращает внимания на мой Андроид.МК. Итак, чтобы переопределить эту опцию и использовать мой make вместо этого, я ввел эту строку:

исходные наборы.главный.средой JNI.srcDirs = []

внутри android тег build.gradle.

Я потратил много времени на это!

Android Studio 2.2 вышла с возможностью использования ndk-build и cMake. Хотя, мы должны были ждать до 2.2.3 для Application.mk поддержка. Я пробовал, это работает...хотя, мои переменные не отображаются в отладчике. Я все еще могу запросить их через командную строку, хотя.

вам нужно сделать что-то вроде этого:

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

Примечание: дополнительная вложенность externalNativeBuild внутри defaultConfig было резкое изменение введено с Android Studio 2.2 Preview 5 (8 июля 2016 года). См. примечания к выпуску по ссылке выше.

в сборке модуля.gradle, в поле задачи, я получаю сообщение об ошибке, если я не использую:

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

Я вижу, что люди используют

def ndkDir = android.plugin.ndkFolder

и

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

но ни один из них не работал, пока я не изменил его на плагин, который я фактически импортировал.

Comments

    Ничего не найдено.