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
6 ответов:
Gradle Build Tools 2.2.0+ - самый близкий NDK когда-либо назывался "волшебным"
в попытке избежать экспериментальных и откровенно надоел NDK и все его hackery я рад, что 2.2.x инструментов сборки Gradle вышел, и теперь он просто работает. Ключ-это
externalNativeBuildи указываяndkBuildаргумент пути вAndroid.mkизменитьndkBuildдоcmakeи укажите аргумент path на ACMakeLists.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/ndkapply 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