我目前正在使用:
- 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的创建,因此使用我自己的自定义,因为我不确定我是否可以从Android Studio本地调试C(虽然我可能错了,但我绝对不是Android Studios的专家用户ndk插件).
提前谢谢了,
马诺斯
解决方法
- android.sources {
- main {
- jni.source {
- srcDirs = ["~/srcs/jni"]
- exclude "**/win.cpp"
- }
- }
- }
感谢Paul Spark!
附: (感谢rajveer):更改排除后不要错过Build / Clean!
老答案
不幸的是,当前的gradle插件不支持这一点.即使是“实验性”插件也只允许添加目录.我建议保留传统的Android.mk可靠地完成这项工作.
我还建议不要设置jni.srcDirs = [],而是保留${jniSrc}以让Android Studio显示这些文件以便于访问和语法突出显示.如果正确设置cppFlags和cFlags,您也可以完全通过标头交叉引用.
诀窍是禁用常规NDK构建任务,并注入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不会生成可调试的设置.具体来说,当运行Android Native调试配置时,Android Studio会抱怨它无法找到包含模块应用程序内符号的目标文件的文件夹.
我建议采用以下解决方法,我只在场景中测试了本地源分为(至少)两个目录:特定于Android的文件(我将其称为JNI桥)位于一个单独的目录中,其余的在其他地方.解决方法涉及使用ndk-build构建静态库,并将其与最小的对象集链接起来,这些对象将从该库中提取所有必需的符号.
为简单起见,我们假设特定于Android的文件(Application.mk,Android.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非常适合在build.gradle中使用您用于LOCAL_MODULE的名称.
更新2
由于jforce,可能仍然可以看到“Link individual native source file to Android Studio project”!