配置:

用的版本号是AS1.5(也能够尝试更高版本号)。 Gradle地址是distributionUrl=https\://services.gradle.org/distributions/gradle-2.8-all.zip

NDK用的是CrystaX NDK

有參考:https://github.com/TsinStudio/AndroidDev/blob/master/Android%20NDK%20C%2B%2B%20开发利器:Android%20Studio.md





常见问题:

1.我在mk的NDK配置和gradle的NDK配置间切换时,突然不能debug进C++代码了。然后通过

清空main/jni/android.mk文件,

点击build->clean,

在debug界面右键tab标题(如 ctbManager Native)->close tab(关闭全部debug的tab)后又能debug进去了,

不知道是哪一步fix了问题。假设遇到编译成功但不能debug C++文件,尝试这几个步骤吧。同一时候不建议mk和gradle配置之间切换。

2.假设C文件报错。考虑能否改动C文件,比解决报错要简单



gradle代码:

  1. import org.apache.tools.ant.taskdefs.condition.Os
  2. import org.gradle.internal.os.OperatingSystem;
  3.  
  4. apply plugin: 'com.android.model.application'
  5.  
  6. final APP_ABIS = ["armeabi", "armeabi-v7a","arm64-v8a"]
  7. final BOOST_SHARED_LIBS = ["boost_serialization","boost_system","boost_filesystem","boost_thread"]
  8.  
  9. model {
  10.  
  11. android {
  12. compileSdkVersion = 23
  13. buildToolsVersion = "23.0.2"
  14. defaultConfig.with {
  15. applicationId = "com.duotin.ctblib"
  16. minSdkVersion.apiLevel = 15
  17. targetSdkVersion.apiLevel = compileSdkVersion.asType(Integer)
  18. versionCode = 1
  19. versionName = "1.0"
  20. }
  21. }
  22.  
  23. android.ndk {
  24. toolchain = "gcc"
  25. toolchainVersion = "4.9"
  26. moduleName = "ctblib"
  27. cppFlags.add("-std=c++11")
  28. cppFlags.add("-fexceptions")
  29. cppFlags.add("-frtti")
  30. cppFlags.add("-I" + getBoostIncDir())
  31. cppFlags.addAll(["-fvisibility=hidden", "-Wno-error=format-security",
  32. "-I${file("src/main/jni/jnisrc")}".toString(),
  33. "-I${file("src/main/jni/src/Jelly")}".toString(),
  34. "-I${file("src/main/jni/src/Papaya")}".toString(),
  35. "-I${file("src/main/jni/src/Helper")}".toString(),
  36. "-I${file("src/main/jni/src/Helper/utf8")}".toString(),
  37. "-I${file("src/main/jni/src/CTBModel")}".toString(),
  38. "-I${file("src/main/jni/src/CTBModel/CTBAlbum")}".toString(),
  39. "-I${file("src/main/jni/src/CTBModel/CTBAlbumParser")}".toString(),
  40. "-I${file("src/main/jni/src/CTBModel/CTBBaseModel")}".toString(),
  41. "-I${file("src/main/jni/src/CTBModel/CTBTrack")}".toString(),
  42. "-I${file("src/main/jni/src/Xml")}".toString(),
  43. "-I${file("src/main/jni/src/Xml/XmlModel")}".toString(),
  44. "-I${file("src/main/jni/src/Xml/XmlModel/XmlAttrNode")}".toString(),
  45. "-I${file("src/main/jni/src/Xml/XmlModel/XmlBaseNode")}".toString(),
  46. "-I${file("src/main/jni/src/Xml/XmlModel/XmlElementNode")}".toString(),
  47. "-I${file("src/main/jni/src/Xml/XmlModel/XmlTextNode")}".toString(),
  48. "-I${file("src/main/jni/src/Xml/XmlUtil")}".toString(),
  49. "-I${file("src/main/jni/src/Xml/XmlUtil/BoostXmlUtil")}".toString(),
  50. "-I${file("src/main/jni/src/Module")}".toString(),
  51. "-I${file("src/main/jni/src/CTBDataManager")}".toString(),
  52. "-I${file("src/main/jni/src/Sync/SyncProcess")}".toString(),
  53. "-I${file("src/main/jni/src/Sync/Task")}".toString(),
  54. "-I${file("src/main/jni/src/SyncLog")}".toString(),
  55. "-I${file("src/main/jni/src/Utils")}".toString()]
  56. )
  57. cppFlags.add("-I${file("src/main/jni/neon/include")}".toString())
  58. CFlags.addAll(["-I${file("src/main/jni/jnisrc")}".toString(),
  59. "-I${file("src/main/jni/src/Jelly")}".toString(),
  60. "-I${file("src/main/jni/src/Papaya")}".toString(),
  61. "-I${file("src/main/jni/src/Helper")}".toString(),
  62. "-I${file("src/main/jni/src/Helper/utf8")}".toString(),
  63. "-I${file("src/main/jni/src/CTBModel")}".toString(),
  64. "-I${file("src/main/jni/src/CTBModel/CTBAlbum")}".toString(),
  65. "-I${file("src/main/jni/src/CTBModel/CTBAlbumParser")}".toString(),
  66. "-I${file("src/main/jni/src/CTBModel/CTBBaseModel")}".toString(),
  67. "-I${file("src/main/jni/src/CTBModel/CTBTrack")}".toString(),
  68. "-I${file("src/main/jni/src/Xml")}".toString(),
  69. "-I${file("src/main/jni/src/Xml/XmlModel")}".toString(),
  70. "-I${file("src/main/jni/src/Xml/XmlModel/XmlAttrNode")}".toString(),
  71. "-I${file("src/main/jni/src/Xml/XmlModel/XmlBaseNode")}".toString(),
  72. "-I${file("src/main/jni/src/Xml/XmlModel/XmlElementNode")}".toString(),
  73. "-I${file("src/main/jni/src/Xml/XmlModel/XmlTextNode")}".toString(),
  74. "-I${file("src/main/jni/src/Xml/XmlUtil")}".toString(),
  75. "-I${file("src/main/jni/src/Xml/XmlUtil/BoostXmlUtil")}".toString(),
  76. "-I${file("src/main/jni/src/Module")}".toString(),
  77. "-I${file("src/main/jni/src/CTBDataManager")}".toString(),
  78. "-I${file("src/main/jni/src/Sync/SyncProcess")}".toString(),
  79. "-I${file("src/main/jni/src/Sync/Task")}".toString(),
  80. "-I${file("src/main/jni/src/SyncLog")}".toString(),
  81. "-I${file("src/main/jni/src/Utils")}".toString(),
  82. "-I${file("src/main/jni/neon//external/android")}".toString(),
  83. "-I${file("src/main/jni/neon/external/openssl/include/openssl")}".toString(),
  84. "-I${file("src/main/jni/neon/external/openssl/include")}".toString(),
  85. "-I${file("src/main/jni/neon/external/expat/include")}".toString(),
  86. "-I${file("src/main/jni/src/SyncLog")}".toString(),
  87. "-I${file("src/main/jni/src/SyncLog")}".toString(),
  88. "-I${file("src/main/jni/src/SyncLog")}".toString(),
  89. "-I${file("src/main/jni/src/SyncLog")}".toString(),
  90. "-I${file("src/main/jni/src/SyncLog")}".toString(),
  91. "-I${file("src/main/jni/src/SyncLog")}".toString()])
  92. CFlags.addAll(["-DDEBUG"])
  93. ldLibs.addAll BOOST_SHARED_LIBS
  94. ldLibs.addAll(["log", "m", "z"])
  95. ldFlags.addAll(["-llog","-fvisibility=hidden","-L/usr/lib ","-lm"])
  96. stl = "gnustl_shared"
  97. }
  98.  
  99. android.buildTypes {
  100. release {
  101. minifyEnabled = false
  102. proguardFiles.add(file('proguard-rules.pro'))
  103. }
  104. }
  105.  
  106. android.sources {
  107. main {
  108. jni {
  109. source {
  110. srcDir "src/main/jni"
  111. dependencies {
  112. APP_ABIS.each { abi ->
  113. library file("src/main/jni/neonlib/${abi}/libneon.a") abi "${abi}"
  114. library file("src/main/jni/neon/external/expat/${abi}/libexpat.a") abi "${abi}"
  115. library file("src/main/jni/openssllib/${abi}/libcrypto.so") abi "${abi}"
  116. library file("src/main/jni/openssllib/${abi}/libssl.so") abi "${abi}"
  117. }
  118. }
  119. }
  120. }
  121. jniLibs {
  122. source {
  123. srcDir "src/main/libs"
  124. }
  125. }
  126. }
  127. }
  128.  
  129. android.productFlavors {
  130. APP_ABIS.each { abi ->
  131. create(getFlavorName(abi)) {
  132. ndk.with {
  133. abiFilters.add(abi)
  134. getPrebuiltLibPaths(abi).each { path ->
  135. ldFlags.add("-L" + path)
  136. }
  137. }
  138. }
  139. }
  140. }
  141. }
  142.  
  143. tasks.all {
  144.  
  145. task ->
  146. println "printTask#${task}"
  147. if (task.name.startsWith('link')) {
  148. println "${task.name}.startsWith('link')"
  149. task.dependsOn copyNativeLibs
  150. }
  151. }
  152.  
  153. task copyNativeLibs {
  154. ["debug", "release"].each { buildType ->
  155. APP_ABIS.each { abi ->
  156. def libs = [:]
  157. BOOST_SHARED_LIBS.each { name ->
  158. libs[name] = "${getBoostLibDir(abi)}/lib${name}.so"
  159. }
  160. libs.crystax = getLibCrystax(abi)
  161.  
  162. libs.each { name, file ->
  163. dependsOn tasks.create(name: "copy-native-library-${name}-${abi}-${buildType}", type: Copy) {
  164. from file
  165. into getTargetLibDir(abi, buildType)
  166. }
  167. }
  168. }
  169. }
  170. }
  171.  
  172. task stripNativeLibs(dependsOn: copyNativeLibs) {
  173. ["debug", "release"].each { buildType ->
  174. APP_ABIS.each { abi ->
  175. def libs = []
  176. libs.addAll(BOOST_SHARED_LIBS)
  177. libs += "crystax"
  178.  
  179. libs.each { name ->
  180. dependsOn tasks.create(name: "strip-native-library-${name}-${abi}-${buildType}", type: Exec) {
  181. commandLine getStripExecutable(abi), "--strip-unneeded", "${getTargetLibDir(abi, buildType)}/lib${name}.so"
  182. }
  183. }
  184.  
  185. }
  186. }
  187. }
  188.  
  189. dependencies {
  190. compile fileTree(dir: 'libs', include: ['*.jar'])
  191. compile project(':ApiClient')
  192. compile 'de.greenrobot:eventbus:2.4.0'
  193. }
  194.  
  195. def getNdkDir() {
  196. if (System.env.ANDROID_NDK_ROOT != null)
  197. return System.env.ANDROID_NDK_ROOT
  198.  
  199. Properties properties = new Properties()
  200. properties.load(project.rootProject.file('local.properties').newDataInputStream())
  201. def ndkdir = properties.getProperty('ndk.dir', null)
  202. if (ndkdir == null)
  203. throw new GradleException("""\
  204. NDK location not found.
  205. Define location with ndk.dir in the local.properties file
  206. or with an ANDROID_NDK_ROOT environment variable.""")
  207.  
  208. return ndkdir
  209. }
  210.  
  211. def getCrystaxNdkDir() {
  212. def ndkDir = getNdkDir()
  213. if (!(new File(ndkDir, "sources/crystax").exists()))
  214. throw new GradleException("""\
  215. '${ndkDir}' is not a CrystaX NDK.
  216. Edit ndk.dir in local.properties or set ANDROID_NDK_ROOT
  217. environment variable pointing to CrystaX NDK""")
  218.  
  219. return ndkDir
  220. }
  221.  
  222. def getFlavorName(abi) {
  223. switch (abi) {
  224. case "armeabi":
  225. return "arm";
  226. case "armeabi-v7a":
  227. return "arm7"
  228. case "arm64-v8a":
  229. return "arm64"
  230. default:
  231. return abi.replaceAll('-', '_')
  232. }
  233. }
  234.  
  235. def getToolchainName(abi) {
  236. switch (abi) {
  237. case ~/^armeabi.*/:
  238. return "arm-linux-androideabi"
  239. case ~/^arm64.*/:
  240. return "aarch64-linux-android"
  241. case "mips":
  242. return "mipsel-linux-android"
  243. case "mips64":
  244. return "mips64el-linux-android"
  245. case ["x86", "x86_64"]:
  246. return abi
  247. default:
  248. throw new GradleException("Unsupported ABI: '${abi}'")
  249. }
  250. }
  251.  
  252. def getToolchainPrefix(abi) {
  253. switch (abi) {
  254. case ~/^armeabi.*/:
  255. return "arm-linux-androideabi"
  256. case ~/^arm64.*/:
  257. return "aarch64-linux-android"
  258. case "mips":
  259. return "mipsel-linux-android"
  260. case "mips64":
  261. return "mips64el-linux-android"
  262. case "x86":
  263. return "i686-linux-android"
  264. case "x86_64":
  265. return "x86_64-linux-android"
  266. default:
  267. throw new GradleException("Unsupported ABI: '${abi}'")
  268. }
  269. }
  270.  
  271. def getHostOS() {
  272. if (OperatingSystem.current().isLinux())
  273. return "linux"
  274. if (OperatingSystem.current().isMacOsX())
  275. return "darwin"
  276. if (OperatingSystem.current().isWindows())
  277. return "windows"
  278. throw new GradleException("Unsupported host OS")
  279. }
  280.  
  281. def getHostArch() {
  282. def arch = System.getProperty("os.arch")
  283. switch (arch) {
  284. case ["x86_64", "amd64"]:
  285. return "x86_64"
  286. case ~/^i[3456]86/:
  287. case "x86":
  288. return "x86"
  289. default:
  290. throw new GradleException("Can't detect host's CPU architecture: '${arch}'")
  291. }
  292. }
  293.  
  294. def getHostTag() {
  295. def tag = getHostOS()
  296. def arch = getHostArch()
  297. if (tag != "windows" || arch != "x86")
  298. tag += "-${arch}"
  299. return tag
  300. }
  301.  
  302. def getStripExecutable(abi) {
  303. def ndk = getCrystaxNdkDir()
  304. def toolchainName = getToolchainName(abi)
  305. def toolchainPrefix = getToolchainPrefix(abi)
  306. def hostTag = getHostTag()
  307. def strip = "${ndk}/toolchains/${toolchainName}-4.9/prebuilt/${hostTag}/bin/${toolchainPrefix}-strip"
  308. if (OperatingSystem.current().isWindows())
  309. strip = strip.replaceAll('/', '\\\\') + '.exe'
  310. return strip
  311. }
  312.  
  313. def getPrebuiltLibPaths(abi) {
  314. def paths = []
  315. paths += getBoostLibDir(abi)
  316. paths += getLibCrystaxDir(abi)
  317. return paths
  318. }
  319.  
  320. def getTargetLibDir(abi, buildType) {
  321. return "${buildDir}/intermediates/binaries/${buildType}/${getFlavorName(abi)}/lib/${abi}"
  322. }
  323.  
  324. def getLibCrystaxDir(abi) {
  325. return "${getCrystaxNdkDir()}/sources/crystax/libs/${abi}"
  326. }
  327.  
  328. def getLibCrystax(abi) {
  329. return "${getLibCrystaxDir(abi)}/libcrystax.so"
  330. }
  331.  
  332. def getBoostDir() {
  333. return "${getCrystaxNdkDir()}/sources/boost/1.58.0"
  334. }
  335.  
  336. def getBoostIncDir() {
  337. return "${getBoostDir()}/include"
  338. }
  339.  
  340. def getBoostLibDir(abi) {
  341. return "${getBoostDir()}/libs/${abi}"
  342. }

使用Android Studo开发NDK之Gradle的配置(能debug C代码)的更多相关文章

  1. Android高效开发环境(Genymotion,Gradle,Andriod Studio)

    临近十一,项目接近上线,终于有些碎片时间可以查看一些博客. 这篇博客是Android开发大牛Cyril Mottier在去年写的博客,我把它翻译一下共享给国内志同道合的朋友,同时也是对自己一个很好的锻 ...

  2. [Android] 环境配置之Android Studio开发NDK

    分类:Android环境搭建 (14351)  (20) ========================================================作者:qiujuer博客:bl ...

  3. Mac Android开发环境变量的配置(java、sdk、ndk、gradle)

    1.打开terminal 2.然后输入 vi .bash_profile 后按"e"进入编辑模式 3.输入想要配置的环境变量(Java.sdk.ndk.gradle): expor ...

  4. Android NDK开发 Android Studio使用新的Gradle构建工具配置NDK环境(一)

    本文主要讲述了如何如何在Android Studio使用新的Gradle构建工具配置NDK环境,现在把相关的步骤整理出来分享给Android程序员兄弟们,希望给他们在配置NDK环境时带来帮助. 从An ...

  5. android 串口开发第一篇:搭建ndk开发环境以及第一个jni调用程序

    一:ndk环境搭建 1:开发环境 我使用的是android studio 2.3.3版本,搭建ndk开发环境比较简单,打开File----Settings----Appearance&Beha ...

  6. Android开发之深入理解Android Studio构建文件build.gradle配置

    摘要: 每周一次,深入学习Android教程,TeachCourse今天带来的一篇关于Android Studio构建文件build.gradle的相关配置,重点学习几个方面的内容:1.applica ...

  7. Android应用开发编译框架流程与IDE及Gradle概要

    1 背景 建议阅读本文之前先阅读<Android Studio入门到精通>和<Groovy脚本基础全攻略>及<Gradle脚本基础全攻略>三篇博客作为背景知识,这样 ...

  8. Android游戏开发实践(1)之NDK与JNI开发03

    Android游戏开发实践(1)之NDK与JNI开发03 前面已经分享了两篇有关Android平台NDK与JNI开发相关的内容.以下列举前面两篇的链接地址,感兴趣的可以再回顾下.那么,这篇继续这个小专 ...

  9. Android游戏开发实践(1)之NDK与JNI开发01

    Android游戏开发实践(1)之NDK与JNI开发01 NDK是Native Developement Kit的缩写,顾名思义,NDK是Google提供的一套原生Java代码与本地C/C++代码&q ...

随机推荐

  1. 【BZOJ3218】【UOJ#77】a + b Problem

    题目 题目在这里 思路&做法 明显的最小割(其实是之前做过一道类似的题) S向每一个格子连容量为\(b_i\)的边 每一个格子向T连容量为\(w_i\)的边 对于格子\(i\)向满足条件的格子 ...

  2. Web启动,停止Windows服务

    When you grow stronger,the world become more dangerous.当你变得越强大,这个世界反而会变得越危险. ServiceModel.cs代码: publ ...

  3. .NET使用Office Open XML导出大量数据到 Excel

    我相信很多人在做项目的都碰到过Excel数据导出的需求,我从最开始使用最原始的HTML拼接(将需要导出的数据拼接成TABLE标签)到后来happy的使用开源的NPOI, EPPlus等开源组件导出EX ...

  4. Android Studio复制项目 两个App之间不覆盖安装操作步骤

    步骤一:修改包名 第五步注意:不能以数字等作为包名的开头. 步骤二:修改清单文件里面的包名 第八步注意:如果报红,从新引入新的包名下的Mainactivity类. 步骤三:修改Gradle Scrip ...

  5. asp.net URL传递中文参数System.Web.HttpUtility.UrlEncode与Server.UrlEncode的区别

    asp.net URL传递中文参数System.Web.HttpUtility.UrlEncode与Server.UrlEncode的区别(一) HttpUtility.UrlEncode 方法: 对 ...

  6. SQL触发器 inset自学经验

    本人建立了一个特价汇网站,想要记录每个商品的点击量和整个网站的访问量,于是就想用sql 触发器来实现 drop trigger tgr_cg_records_update_column create ...

  7. Embeding如何理解?

    参考: http://www.sohu.com/a/206922947_390227 https://zhuanlan.zhihu.com/p/27830489 https://www.jianshu ...

  8. JS中的map

    定义和用法: map() 方法返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值. map() 方法按照原始数组元素顺序依次处理元素. 注意: map() 不会对空数组进行检测. 注意: m ...

  9. uva 11992 Fast Matrix Operations 线段树模板

    注意 setsetset 和 addvaddvaddv 标记的下传. 我们可以控制懒惰标记的优先级. 由于 setsetset 操作的优先级高于 addaddadd 操作,当下传 setsetset ...

  10. 02.OOP面向对象-3.一些理解

    对封装的理解? 封装,类本身就是一个封装,封装了属性和方法.方法也是封装,对一些业务逻辑的封装.私有也是封装,将一些方法和属性私有化,对外提供可访问的接口. 对继承的理解 将共性的内容放在父类中,子类 ...