Ich versuche, meiner App nativen Code hinzuzufügen. Ich habe alles so ../main/jni
wie es in meinem Eclipse-Projekt war. Ich habe ndk.dir=...
zu meinem hinzugefügt local.properties
. Ich habe noch nichts anderes getan (ich bin mir nicht sicher, was sonst noch benötigt wird. Wenn ich also etwas verpasst habe, lass es mich wissen). Wenn ich versuche zu bauen, erhalte ich folgende Fehlermeldung:
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.
Was muss ich tun?
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
Antworten:
Gradle Build Tools 2.2.0+ - Das NDK kommt der Bezeichnung "Magie" am nächsten.
Ich bin froh, dass 2.2.x der Gradle Build Tools herausgekommen ist und jetzt einfach funktioniert. Der Schlüssel ist das
externalNativeBuild
und zeigt auf dasndkBuild
Pfadargument auf einAndroid.mk
oder ändertndkBuild
aufcmake
und zeigt auf das Pfadargument auf einCMakeLists.txt
Build-Skript.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' //} } }
Weitere Informationen finden Sie auf der Google-Seite zum Hinzufügen von nativem Code .
Nachdem dies richtig eingerichtet wurde, können
./gradlew installDebug
Sie loslegen. Sie müssen sich auch darüber im Klaren sein, dass sich das NDK in Clang bewegt, da gcc im Android-NDK jetzt veraltet ist.Integration und Bereinigung von Android Studio - DEPRECATED
Die anderen Antworten zeigen den richtigen Weg auf, um die automatische Erstellung von
Android.mk
Dateien zu verhindern , aber sie gehen nicht den zusätzlichen Schritt einer besseren Integration in Android Studio. Ich habe die Möglichkeit hinzugefügt, tatsächlich von der Quelle zu bereinigen und zu erstellen, ohne zur Befehlszeile gehen zu müssen. Ihrelocal.properties
Datei muss habenndk.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' }
Das
src/main/jni
Verzeichnis nimmt ein Standardlayout des Projekts an. Es sollte der Verwandte von diesembuild.gradle
Dateispeicherort zumjni
Verzeichnis sein.Gradle - für diejenigen, die Probleme haben
Überprüfen Sie auch diese Antwort zum Stapelüberlauf .
Es ist wirklich wichtig, dass Ihre Gradle-Version und das allgemeine Setup korrekt sind. Wenn Sie ein älteres Projekt haben, empfehle ich dringend, ein neues mit dem neuesten Android Studio zu erstellen und zu sehen, was Google als Standardprojekt betrachtet. Verwenden Sie auch
gradlew
. Dies schützt den Entwickler vor einer Nichtübereinstimmung der Gradle-Version. Schließlich muss das Gradle-Plugin korrekt konfiguriert sein.Und Sie fragen, was ist die neueste Version des Gradle-Plugins? Überprüfen Sie die Tools-Seite und bearbeiten Sie die Version entsprechend.
Endprodukt - /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() } }
Stellen Sie sicher
gradle wrapper
, dass diegradlew
Datei und dasgradle/wrapper
Unterverzeichnis generiert werden . Das ist eine große Sache.ndkDirectory
Dies ist einige Male aufgetreten,
android.ndkDirectory
ist jedoch der richtige Weg, um den Ordner nach 1.1 abzurufen. Gradle-Projekte auf Version 1.0.0 migrieren . Wenn Sie eine experimentelle oder alte Version des Plugins verwenden, kann Ihr Kilometerstand variieren.quelle
def ndkDir = android.plugin.ndkFolder
eine einfachere Möglichkeit verwenden, um einen Verweis auf das Android-Plugin zu erhalten.def ndkDir = plugins.getPlugin('com.android.application').sdkHandler.ndkFolder
damit es funktioniertgradle unterstützt die ndk-Kompilierung, indem eine weitere Android.mk-Datei mit absoluten Pfaden zu Ihren Quellen generiert wird. NDK unterstützt absolute Pfade seit r9 unter OSX, r9c unter Windows, daher müssen Sie Ihr NDK auf r9 + aktualisieren.
Möglicherweise treten andere Probleme auf, da die NDK-Unterstützung durch gradle vorläufig ist. In diesem Fall können Sie die ndk-Kompilierung von gradle deaktivieren, indem Sie Folgendes einstellen:
sourceSets.main { jni.srcDirs = [] jniLibs.srcDir 'src/main/libs' }
um ndk-build selbst aufrufen und libs von libs / integrieren zu können.
Übrigens, haben Sie Probleme beim Kompilieren für x86? Ich sehe, dass Sie es nicht in Ihren APP_ABI aufgenommen haben.
quelle
android { }
In meinem Fall bin ich unter Windows und das Befolgen der obigen Antwort von Cameron funktioniert nur, wenn Sie den vollständigen Namen des ndk-build verwenden, der ndk-build.cmd lautet . Ich muss das Projekt bereinigen und neu erstellen und dann den Emulator neu starten, bevor die App funktioniert (eigentlich habe ich das Beispiel HelloJni aus NDK in Android Studio importiert). Stellen Sie jedoch sicher, dass der Pfad zum NDK keinen Speicherplatz enthält .
Schließlich ist mein build.gradle wie folgt vollständig aufgelistet:
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' }
quelle
src/main/libs
? Was ist, wenn es ein anderes Unterverzeichnis wie armeabi istNDK_ROOT_DIRCTORY
. Wenn Android Studio den Wert ignoriert, sollten Sie einen Fehlerbericht einreichen.Android Studio 2.2 bietet die Möglichkeit, ndk-build und cMake zu verwenden. Wir mussten jedoch bis 2.2.3 auf die Application.mk-Unterstützung warten. Ich habe es versucht, es funktioniert ... obwohl meine Variablen nicht im Debugger angezeigt werden. Ich kann sie trotzdem über die Kommandozeile abfragen.
Sie müssen so etwas tun:
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" } } }
Siehe http://tools.android.com/tech-docs/external-c-builds
NB: Die zusätzliche Verschachtelung von
externalNativeBuild
innendefaultConfig
war eine bahnbrechende Änderung, die mit Android Studio 2.2 Preview 5 (8. Juli 2016) eingeführt wurde. Siehe die Versionshinweise unter dem obigen Link.quelle
Mein Problem unter OSX war die Gradle-Version. Gradle ignorierte mein Android.mk. Um diese Option zu überschreiben und stattdessen mein Make zu verwenden, habe ich folgende Zeile eingegeben:
innerhalb des
android
Tags inbuild.gradle
.Ich habe viel Zeit damit verschwendet!
quelle
sourceSets.main { jni.srcDirs = [] }
anders alssourceSets.main.jni.srcDirs = []
? Ich glaube, Ihr Problem war woanders und Sie haben es versehentlich behoben.Im Modul build.gradle im Aufgabenfeld wird eine Fehlermeldung angezeigt, es sei denn, ich verwende:
def ndkDir = plugins.getPlugin('com.android.application').sdkHandler.getNdkFolder()
Ich sehe Leute benutzen
def ndkDir = android.plugin.ndkFolder
und
def ndkDir = plugins.getPlugin('com.android.library').sdkHandler.getNdkFolder()
Aber keines davon funktionierte, bis ich es in das Plugin änderte, das ich tatsächlich importierte.
quelle
NDK_ROOT_DIRCTORY
. Wenn Android Studio den Wert ignoriert, sollten Sie einen Fehlerbericht einreichen.