android – 在ndk {} DSL中定义LOCAL_SRC_FILES

前端之家收集整理的这篇文章主要介绍了android – 在ndk {} DSL中定义LOCAL_SRC_FILES前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我想知道是否可以在gradle.build ndk {}块中定义LOCAL_SRC_FILES.

我目前正在使用:

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

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

我的jni模块gradle.build文件如下所示:

  1. apply plugin: 'com.android.library'
  2.  
  3. dependencies {
  4. compile fileTree(dir: 'libs',include: '*.jar')
  5. }
  6.  
  7. android {
  8. compileSdkVersion 11
  9. buildToolsVersion "22.0.1"
  10.  
  11. def jniSrc = System.getProperty("user.home") + "/srcs/jni"
  12.  
  13. defaultConfig {
  14. ndk {
  15. moduleName "core"
  16. stl "gnustl_shared"
  17. cFlags "-std=c++11"
  18. }
  19. }
  20.  
  21. sourceSets {
  22. main {
  23. manifest.srcFile 'AndroidManifest.xml'
  24. java.srcDirs = ['src']
  25. resources.srcDirs = ['src']
  26. aidl.srcDirs = ['src']
  27. renderscript.srcDirs = ['src']
  28. res.srcDirs = ['res']
  29. assets.srcDirs = ['assets']
  30. jniLibs.srcDirs = ['libs']
  31. jni.srcDirs = ["${jniSrc}"]
  32. }
  33. }
  34.  
  35. buildTypes {
  36. release {
  37. minifyEnabled false
  38. proguardFiles getDefaultProguardFile('proguard-android.txt'),'proguard-rules.pro'
  39. }
  40. debug {
  41. jniDebuggable true
  42. }
  43. }
  44.  
  45. productFlavors {
  46. x86 {
  47. ndk {
  48. abiFilter "x86"
  49. }
  50. }
  51. arm {
  52. ndk {
  53. abiFilter "armeabi-v7a"
  54. }
  55. }
  56. mips {
  57. ndk {
  58. abiFilter "mips"
  59. }
  60. }
  61. }
  62. }

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

我有点不愿意迁移到实验性的’com.android.tools.build:gradle-experimental:0.2.0′,但如果前面提到的模块解决了这个问题,我可以尝试一下.

我也不想用:

  1. jni.srcDirs = []

并覆盖Android.mk的创建,因此使用我自己的自定义,因为我不确定我是否可以从Android Studio本地调试C(虽然我可能错了,但我绝对不是Android Studios的专家用户ndk插件).

提前谢谢了,

马诺斯

解决方法

使用实验性插件0.4.0,可以通过模式从NDK构建中排除文件,例如
  1. android.sources {
  2. main {
  3. jni.source {
  4. srcDirs = ["~/srcs/jni"]
  5. exclude "**/win.cpp"
  6. }
  7. }
  8. }

感谢Paul Spark

附: (感谢rajveer):更改排除后不要错过Build / Clean!

老答案

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

我还建议不要设置jni.srcDirs = [],而是保留${jniSrc}以让Android Studio显示这些文件以便于访问和语法突出显示.如果正确设置cppFlags和cFlags,您也可以完全通过标头交叉引用.

诀窍是禁用常规NDK构建任务,并注入buildNative任务:

  1. def ndkBuild = android.ndkDirectory
  2. import org.apache.tools.ant.taskdefs.condition.Os
  3. if (Os.isFamily(Os.FAMILY_WINDOWS)) {
  4. ndkBuild += '.cmd'
  5. }
  6.  
  7. task buildNative(type: Exec,description: 'Compile JNI source via NDK') {
  8. commandLine '$ndkBuild','NDK_PROJECT_PATH="$jniSrc/..'
  9. }
  10.  
  11. task cleanNative(type: Exec,description: 'Clean JNI object files') {
  12. commandLine '$ndkBuild','clean','NDK_PROJECT_PATH="$jniSrc/..'
  13. }
  14.  
  15. clean.dependsOn 'cleanNative'
  16.  
  17. tasks.withType(JavaCompile) {
  18. compileTask -> compileTask.dependsOn buildNative
  19. }
  20.  
  21. tasks.all {
  22. task -> if (task.name.contains('compileDebugNdk') || task.name.contains('compileReleaseNdk')) task.enabled = false
  23. }

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

  1. tasks.all {
  2. task ->
  3. if (task.name.startsWith('compile') && task.name.contains('MainC')) {
  4. task.enabled = false
  5. }
  6. if (task.name.startsWith('link')) {
  7. task.enabled = false
  8. }
  9. if (task.name.endsWith("SharedLibrary") ) {
  10. task.dependsOn buildNative
  11. }
  12. }

UPDATE

buildNative不会生成可调试的设置.具体来说,当运行Android Native调试配置时,Android Studio会抱怨它无法找到包含模块应用程序内符号的目标文件文件夹.

我建议采用以下解决方法,我只在场​​景中测试了本地源分为(至少)两个目录:特定于Android的文件(我将其称为JNI桥)位于一个单独的目录中,其余的在其他地方.解决方法涉及使用ndk-build构建静态库,并将其与最小的对象集链接起来,这些对象将从该库中提取所有必需的符号.

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

这是build.gradle的相关片段:

  1. def LOCAL_MODULE = "staticLib"
  2. def appAbi = "armeabi-v7a"
  3. def ndkOut = "build/intermediates/$LOCAL_MODULE"
  4. def staticLibPath = "$ndkOut/local/$appAbi/lib${LOCAL_MODULE}.a"
  5. task buildStaticLib(type: Exec,description: 'Compile Static lib via NDK') {
  6. commandLine "$ndkBuild","$staticLibPath","NDK_PROJECT_PATH=~/srcs","NDK_OUT=$ndkOut","APP_ABI=$appAbi","APP_STL=gnustl_static"
  7. }
  8.  
  9. tasks.all {
  10. task ->
  11. if (task.name.startsWith('link')) {
  12. task.dependsOn buildStaticLib
  13. }
  14. }
  15.  
  16. model {
  17. android.ndk {
  18. moduleName = "hello-jni"
  19. abiFilters += "$appAbi".toString()
  20. ldFlags += "$staticLib".toString()
  21. ldLibs += "log"
  22. cppFlags += "-std=c++11"
  23. }
  24.  
  25. android.sources {
  26. main.jni.source {
  27. srcDirs = ["~/srcs/jni"]
  28. }
  29. }
  30. }

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

  1. LOCAL_PATH := $(call my-dir)/..
  2.  
  3. include $(CLEAR_VARS)
  4.  
  5. LOCAL_MODULE := staticLib
  6. LOCAL_SRC_FILES := HelloJni.cpp
  7.  
  8. LOCAL_CPPFLAGS += -std=c++11
  9.  
  10. include $(BUILD_STATIC_LIBRARY)

Android.mk中的LOCAL_MODULE非常适合在build.gradle中使用您用于LOCAL_MODULE的名称.

更新2

由于jforce,可能仍然可以看到“Link individual native source file to Android Studio project”!

猜你在找的Android相关文章