在ndk {} DSL中定义LOCAL_SRC_FILES

我想知道是否有可能在gradle.build ndk {}块中定义LOCAL_SRC_FILES。

我目前使用:

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

在我的顶级gradle.build文件中。

我的jni模块gradle.build文件看起来像这样:

 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" } } } } 

我问的原因是,在我的jni资源下,有针对不同平台的代码,不仅仅是Android,还有iOS和WinRT。

我有点不情愿迁移到实验“com.android.tools.build:gradle-experimental:0.2.0”,但如果上述模块解决了这个问题,我可以试试看。

我也不想用:

 jni.srcDirs = [] 

并重写Android.mk的创build,并因此使用我自己的自定义的,因为我不知道是否可以从Android Studio本机debuggingC ++(此后我可能是错误的,但我绝对不是Android Studios的专家用户ndk插件)。

提前谢谢了,

马诺斯

使用0.4.0的实验性插件,可以通过模式排除NDK构build的文件,例如

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

感谢Paul Spark !

PS (感谢rajveer ):改变exclude后不要错过Build/Clean

老答案

不幸的是,这不被当前的gradle插件支持。 即使是“实验”插件也只允许添加目录。 我build议保持可靠地完成这项工作的传统Android.mk

我也build议不要设置jni.srcDirs = [] ,而是保留${jniSrc}让Android Studio显示这些文件以方便访问和语法高亮显示。 如果你正确地设置了cppFlagscFlags ,那么你也将拥有通过标题进行交叉引用的全部function。

诀窍是禁用常规的NDK构build任务,并注入一个buildNative任务:

 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 } 

类似的方法适用于'com.android.tools.build:gradle-experimental:0.2.0' ,但是任务匹配是不同的:

 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 } } 

UPDATE

buildNative不会产生可debugging的设置。 具体来说,在运行Android Nativedebuggingconfiguration时,Android Studio会抱怨它无法在模块应用程序中find包含具有符号的目标文件的文件夹

我build议下面的解决方法,我只在本地源被分割(至less)两个目录的场景中testing:Android特定的文件(我将称它们为JNI桥 )在一个单独的目录中,其余的在别处。 解决方法包括使用ndk-build构build一个静态库,并将其与最小的一组对象链接起来,这些对象将从该库中提取所有必需的符号。

为了简单起见,我们假设Android特定的文件( Application.mkAndroid.mk和“android-jni.cpp”在~/srcs/jni目录中,而与平台无关的文件在~/srcs和其他子目录。

这里是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"] } } } 

〜/ srcs / Android.mk文件可能如下所示:

 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) 

对于Android.mk中的LOCAL_MODULE ,使用LOCAL_MODULE中的LOCAL_MODULE名称非常重要。

更新2

这可能仍然有可能,感谢jforce ,请参阅“将各个本地源文件链接到Android Studio项目 ”!