define LOCAL_SRC_FILES en ndk {} DSL

Me gustaría saber si es posible definir LOCAL_SRC_FILES en el bloque gradle.build ndk {}.

Actualmente estoy usando:

dependencies { classpath 'com.android.tools.build:gradle:1.3.0' } 

en mi archivo gradle.build de nivel superior.

Mi archivo jni gradle.build se ve así:

 apply plugin: 'com.android.library' dependencies { compile fileTree(dir: 'libs', include: '*.jar') } android { compileSdkVersion 11 buildToolsVersion "22.0.1" def jniSrc = System.getProperty("user.home") + "/srcs/jni" defaultConfig { ndk { moduleName "core" stl "gnustl_shared" cFlags "-std=c++11" } } sourceSets { main { manifest.srcFile 'AndroidManifest.xml' java.srcDirs = ['src'] resources.srcDirs = ['src'] aidl.srcDirs = ['src'] renderscript.srcDirs = ['src'] res.srcDirs = ['res'] assets.srcDirs = ['assets'] jniLibs.srcDirs = ['libs'] jni.srcDirs = ["${jniSrc}"] } } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } debug { jniDebuggable true } } productFlavors { x86 { ndk { abiFilter "x86" } } arm { ndk { abiFilter "armeabi-v7a" } } mips { ndk { abiFilter "mips" } } } } 

La razón por la que estoy preguntando es que bajo mis fonts jni hay un código dirigido a diferentes plataformas, no solo Android, sino también iOS y WinRT.

Soy un poco reacio a migrar a ‘com.android.tools.build: gradle-experimental: 0.2.2 experimental’, pero si el módulo antes mencionado resuelve el problema, podría intentarlo.

Tampoco me gustaría usar:

 jni.srcDirs = [] 

y anular la creación de Android.mk y así usar mi propio personalizado, dado que no estoy seguro de si podría depurar C ++ nativamente de Android Studio a partir de entonces (sin embargo, podría estar equivocado, definitivamente no soy un usuario experto de los estudios de Android ndk plugin).

Muchas gracias de antemano,

Manos

Con el plugin experimental 0.4.0, es posible excluir archivos de NDK comstackción por patrón, por ejemplo

 android.sources { main { jni.source { srcDirs = ["~/srcs/jni"] exclude "**/win.cpp" } } } 

¡Gracias a Paul Spark !

PD (gracias a Rajveer ): ¡no te pierdas Build/Clean después de cambiar exclude !

Respuesta anterior

Lamentablemente, esto no es compatible con los complementos gradle actuales. Incluso el complemento “experimental” solo permite agregar directorios. Recomiendo mantener el Android.mk tradicional que hace este trabajo de manera confiable.

También recomiendo no configurar jni.srcDirs = [] , sino mantener ${jniSrc} para permitir que Android Studio muestre estos archivos para facilitar el acceso y destacar la syntax. Si configura cppFlags y cFlags correctamente, también tendrá plena capacidad de referencia cruzada a través de encabezados.

El truco consiste en deshabilitar las tareas normales de comstackción de NDK e inyectar una tarea buildNative lugar:

 def ndkBuild = android.ndkDirectory import org.apache.tools.ant.taskdefs.condition.Os if (Os.isFamily(Os.FAMILY_WINDOWS)) { ndkBuild += '.cmd' } task buildNative(type: Exec, description: 'Compile JNI source via NDK') { commandLine '$ndkBuild', 'NDK_PROJECT_PATH="$jniSrc/..' } task cleanNative(type: Exec, description: 'Clean JNI object files') { commandLine '$ndkBuild', 'clean', 'NDK_PROJECT_PATH="$jniSrc/..' } clean.dependsOn 'cleanNative' tasks.withType(JavaCompile) { compileTask -> compileTask.dependsOn buildNative } tasks.all { task -> if (task.name.contains('compileDebugNdk') || task.name.contains('compileReleaseNdk')) task.enabled = false } 

Un enfoque similar funciona para 'com.android.tools.build:gradle-experimental:0.2.0' , pero la coincidencia de tareas es diferente:

 tasks.all { task -> if (task.name.startsWith('compile') && task.name.contains('MainC')) { task.enabled = false } if (task.name.startsWith('link')) { task.enabled = false } if (task.name.endsWith("SharedLibrary") ) { task.dependsOn buildNative } } 

ACTUALIZAR

buildNative no produce una configuración depurada. Específicamente, cuando se ejecuta la configuración de depuración nativa de Android , Android Studio se queja de que no se pudo ubicar la carpeta que contiene los archivos de objetos con símbolos dentro de la aplicación del módulo .

Sugiero la siguiente solución, que solo probé en el escenario cuando las fonts nativas están divididas en (al menos) dos directorios: los archivos específicos de Android (los llamaré puente JNI ) están en un directorio separado, y el rest están en otra parte. . La solución consiste en crear una biblioteca estática con ndk-build y vincularla con el conjunto mínimo de objetos que extraerá todos los símbolos necesarios de esa biblioteca.

Para simplificar, supongamos que los archivos específicos de Android ( Application.mk , Android.mk y “android-jni.cpp” están en el directorio ~/srcs/jni , mientras que los archivos independientes de la plataforma están en ~/srcs y sus otros subdirectorios.

Aquí está el fragmento relevante de build.gradle :

 def LOCAL_MODULE = "staticLib" def appAbi = "armeabi-v7a" def ndkOut = "build/intermediates/$LOCAL_MODULE" def staticLibPath = "$ndkOut/local/$appAbi/lib${LOCAL_MODULE}.a" task buildStaticLib(type: Exec, description: 'Compile Static lib via NDK') { commandLine "$ndkBuild", "$staticLibPath", "NDK_PROJECT_PATH=~/srcs", "NDK_OUT=$ndkOut", "APP_ABI=$appAbi", "APP_STL=gnustl_static" } tasks.all { task -> if (task.name.startsWith('link')) { task.dependsOn buildStaticLib } } model { android.ndk { moduleName = "hello-jni" abiFilters += "$appAbi".toString() ldFlags += "$staticLib".toString() ldLibs += "log" cppFlags += "-std=c++11" } android.sources { main.jni.source { srcDirs = ["~/srcs/jni"] } } } 

El archivo ~ / srcs / Android.mk puede verse así:

 LOCAL_PATH := $(call my-dir)/.. include $(CLEAR_VARS) LOCAL_MODULE := staticLib LOCAL_SRC_FILES := HelloJni.cpp LOCAL_CPPFLAGS += -std=c++11 include $(BUILD_STATIC_LIBRARY) 

Es importante que LOCAL_MODULE en Android.mk se ajuste al nombre que usa para LOCAL_MODULE en build.gradle .

ACTUALIZACIÓN 2

Todavía es posible, gracias a jforce , ver “¡ Enlace el archivo fuente nativo individual al proyecto Android Studio “!