使用Android Studo开发NDK之Gradle的配置(能debug C代码)
配置:
用的版本号是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代码:
import org.apache.tools.ant.taskdefs.condition.Os
import org.gradle.internal.os.OperatingSystem; apply plugin: 'com.android.model.application' final APP_ABIS = ["armeabi", "armeabi-v7a","arm64-v8a"]
final BOOST_SHARED_LIBS = ["boost_serialization","boost_system","boost_filesystem","boost_thread"] model { android {
compileSdkVersion = 23
buildToolsVersion = "23.0.2"
defaultConfig.with {
applicationId = "com.duotin.ctblib"
minSdkVersion.apiLevel = 15
targetSdkVersion.apiLevel = compileSdkVersion.asType(Integer)
versionCode = 1
versionName = "1.0"
}
} android.ndk {
toolchain = "gcc"
toolchainVersion = "4.9"
moduleName = "ctblib"
cppFlags.add("-std=c++11")
cppFlags.add("-fexceptions")
cppFlags.add("-frtti")
cppFlags.add("-I" + getBoostIncDir())
cppFlags.addAll(["-fvisibility=hidden", "-Wno-error=format-security",
"-I${file("src/main/jni/jnisrc")}".toString(),
"-I${file("src/main/jni/src/Jelly")}".toString(),
"-I${file("src/main/jni/src/Papaya")}".toString(),
"-I${file("src/main/jni/src/Helper")}".toString(),
"-I${file("src/main/jni/src/Helper/utf8")}".toString(),
"-I${file("src/main/jni/src/CTBModel")}".toString(),
"-I${file("src/main/jni/src/CTBModel/CTBAlbum")}".toString(),
"-I${file("src/main/jni/src/CTBModel/CTBAlbumParser")}".toString(),
"-I${file("src/main/jni/src/CTBModel/CTBBaseModel")}".toString(),
"-I${file("src/main/jni/src/CTBModel/CTBTrack")}".toString(),
"-I${file("src/main/jni/src/Xml")}".toString(),
"-I${file("src/main/jni/src/Xml/XmlModel")}".toString(),
"-I${file("src/main/jni/src/Xml/XmlModel/XmlAttrNode")}".toString(),
"-I${file("src/main/jni/src/Xml/XmlModel/XmlBaseNode")}".toString(),
"-I${file("src/main/jni/src/Xml/XmlModel/XmlElementNode")}".toString(),
"-I${file("src/main/jni/src/Xml/XmlModel/XmlTextNode")}".toString(),
"-I${file("src/main/jni/src/Xml/XmlUtil")}".toString(),
"-I${file("src/main/jni/src/Xml/XmlUtil/BoostXmlUtil")}".toString(),
"-I${file("src/main/jni/src/Module")}".toString(),
"-I${file("src/main/jni/src/CTBDataManager")}".toString(),
"-I${file("src/main/jni/src/Sync/SyncProcess")}".toString(),
"-I${file("src/main/jni/src/Sync/Task")}".toString(),
"-I${file("src/main/jni/src/SyncLog")}".toString(),
"-I${file("src/main/jni/src/Utils")}".toString()]
)
cppFlags.add("-I${file("src/main/jni/neon/include")}".toString())
CFlags.addAll(["-I${file("src/main/jni/jnisrc")}".toString(),
"-I${file("src/main/jni/src/Jelly")}".toString(),
"-I${file("src/main/jni/src/Papaya")}".toString(),
"-I${file("src/main/jni/src/Helper")}".toString(),
"-I${file("src/main/jni/src/Helper/utf8")}".toString(),
"-I${file("src/main/jni/src/CTBModel")}".toString(),
"-I${file("src/main/jni/src/CTBModel/CTBAlbum")}".toString(),
"-I${file("src/main/jni/src/CTBModel/CTBAlbumParser")}".toString(),
"-I${file("src/main/jni/src/CTBModel/CTBBaseModel")}".toString(),
"-I${file("src/main/jni/src/CTBModel/CTBTrack")}".toString(),
"-I${file("src/main/jni/src/Xml")}".toString(),
"-I${file("src/main/jni/src/Xml/XmlModel")}".toString(),
"-I${file("src/main/jni/src/Xml/XmlModel/XmlAttrNode")}".toString(),
"-I${file("src/main/jni/src/Xml/XmlModel/XmlBaseNode")}".toString(),
"-I${file("src/main/jni/src/Xml/XmlModel/XmlElementNode")}".toString(),
"-I${file("src/main/jni/src/Xml/XmlModel/XmlTextNode")}".toString(),
"-I${file("src/main/jni/src/Xml/XmlUtil")}".toString(),
"-I${file("src/main/jni/src/Xml/XmlUtil/BoostXmlUtil")}".toString(),
"-I${file("src/main/jni/src/Module")}".toString(),
"-I${file("src/main/jni/src/CTBDataManager")}".toString(),
"-I${file("src/main/jni/src/Sync/SyncProcess")}".toString(),
"-I${file("src/main/jni/src/Sync/Task")}".toString(),
"-I${file("src/main/jni/src/SyncLog")}".toString(),
"-I${file("src/main/jni/src/Utils")}".toString(),
"-I${file("src/main/jni/neon//external/android")}".toString(),
"-I${file("src/main/jni/neon/external/openssl/include/openssl")}".toString(),
"-I${file("src/main/jni/neon/external/openssl/include")}".toString(),
"-I${file("src/main/jni/neon/external/expat/include")}".toString(),
"-I${file("src/main/jni/src/SyncLog")}".toString(),
"-I${file("src/main/jni/src/SyncLog")}".toString(),
"-I${file("src/main/jni/src/SyncLog")}".toString(),
"-I${file("src/main/jni/src/SyncLog")}".toString(),
"-I${file("src/main/jni/src/SyncLog")}".toString(),
"-I${file("src/main/jni/src/SyncLog")}".toString()])
CFlags.addAll(["-DDEBUG"])
ldLibs.addAll BOOST_SHARED_LIBS
ldLibs.addAll(["log", "m", "z"])
ldFlags.addAll(["-llog","-fvisibility=hidden","-L/usr/lib ","-lm"])
stl = "gnustl_shared"
} android.buildTypes {
release {
minifyEnabled = false
proguardFiles.add(file('proguard-rules.pro'))
}
} android.sources {
main {
jni {
source {
srcDir "src/main/jni"
dependencies {
APP_ABIS.each { abi ->
library file("src/main/jni/neonlib/${abi}/libneon.a") abi "${abi}"
library file("src/main/jni/neon/external/expat/${abi}/libexpat.a") abi "${abi}"
library file("src/main/jni/openssllib/${abi}/libcrypto.so") abi "${abi}"
library file("src/main/jni/openssllib/${abi}/libssl.so") abi "${abi}"
}
}
}
}
jniLibs {
source {
srcDir "src/main/libs"
}
}
}
} android.productFlavors {
APP_ABIS.each { abi ->
create(getFlavorName(abi)) {
ndk.with {
abiFilters.add(abi)
getPrebuiltLibPaths(abi).each { path ->
ldFlags.add("-L" + path)
}
}
}
}
}
} tasks.all { task ->
println "printTask#${task}"
if (task.name.startsWith('link')) {
println "${task.name}.startsWith('link')"
task.dependsOn copyNativeLibs
}
} task copyNativeLibs {
["debug", "release"].each { buildType ->
APP_ABIS.each { abi ->
def libs = [:]
BOOST_SHARED_LIBS.each { name ->
libs[name] = "${getBoostLibDir(abi)}/lib${name}.so"
}
libs.crystax = getLibCrystax(abi) libs.each { name, file ->
dependsOn tasks.create(name: "copy-native-library-${name}-${abi}-${buildType}", type: Copy) {
from file
into getTargetLibDir(abi, buildType)
}
}
}
}
} task stripNativeLibs(dependsOn: copyNativeLibs) {
["debug", "release"].each { buildType ->
APP_ABIS.each { abi ->
def libs = []
libs.addAll(BOOST_SHARED_LIBS)
libs += "crystax" libs.each { name ->
dependsOn tasks.create(name: "strip-native-library-${name}-${abi}-${buildType}", type: Exec) {
commandLine getStripExecutable(abi), "--strip-unneeded", "${getTargetLibDir(abi, buildType)}/lib${name}.so"
}
} }
}
} dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile project(':ApiClient')
compile 'de.greenrobot:eventbus:2.4.0'
} def getNdkDir() {
if (System.env.ANDROID_NDK_ROOT != null)
return System.env.ANDROID_NDK_ROOT Properties properties = new Properties()
properties.load(project.rootProject.file('local.properties').newDataInputStream())
def ndkdir = properties.getProperty('ndk.dir', null)
if (ndkdir == null)
throw new GradleException("""\
NDK location not found.
Define location with ndk.dir in the local.properties file
or with an ANDROID_NDK_ROOT environment variable.""") return ndkdir
} def getCrystaxNdkDir() {
def ndkDir = getNdkDir()
if (!(new File(ndkDir, "sources/crystax").exists()))
throw new GradleException("""\
'${ndkDir}' is not a CrystaX NDK.
Edit ndk.dir in local.properties or set ANDROID_NDK_ROOT
environment variable pointing to CrystaX NDK""") return ndkDir
} def getFlavorName(abi) {
switch (abi) {
case "armeabi":
return "arm";
case "armeabi-v7a":
return "arm7"
case "arm64-v8a":
return "arm64"
default:
return abi.replaceAll('-', '_')
}
} def getToolchainName(abi) {
switch (abi) {
case ~/^armeabi.*/:
return "arm-linux-androideabi"
case ~/^arm64.*/:
return "aarch64-linux-android"
case "mips":
return "mipsel-linux-android"
case "mips64":
return "mips64el-linux-android"
case ["x86", "x86_64"]:
return abi
default:
throw new GradleException("Unsupported ABI: '${abi}'")
}
} def getToolchainPrefix(abi) {
switch (abi) {
case ~/^armeabi.*/:
return "arm-linux-androideabi"
case ~/^arm64.*/:
return "aarch64-linux-android"
case "mips":
return "mipsel-linux-android"
case "mips64":
return "mips64el-linux-android"
case "x86":
return "i686-linux-android"
case "x86_64":
return "x86_64-linux-android"
default:
throw new GradleException("Unsupported ABI: '${abi}'")
}
} def getHostOS() {
if (OperatingSystem.current().isLinux())
return "linux"
if (OperatingSystem.current().isMacOsX())
return "darwin"
if (OperatingSystem.current().isWindows())
return "windows"
throw new GradleException("Unsupported host OS")
} def getHostArch() {
def arch = System.getProperty("os.arch")
switch (arch) {
case ["x86_64", "amd64"]:
return "x86_64"
case ~/^i[3456]86/:
case "x86":
return "x86"
default:
throw new GradleException("Can't detect host's CPU architecture: '${arch}'")
}
} def getHostTag() {
def tag = getHostOS()
def arch = getHostArch()
if (tag != "windows" || arch != "x86")
tag += "-${arch}"
return tag
} def getStripExecutable(abi) {
def ndk = getCrystaxNdkDir()
def toolchainName = getToolchainName(abi)
def toolchainPrefix = getToolchainPrefix(abi)
def hostTag = getHostTag()
def strip = "${ndk}/toolchains/${toolchainName}-4.9/prebuilt/${hostTag}/bin/${toolchainPrefix}-strip"
if (OperatingSystem.current().isWindows())
strip = strip.replaceAll('/', '\\\\') + '.exe'
return strip
} def getPrebuiltLibPaths(abi) {
def paths = []
paths += getBoostLibDir(abi)
paths += getLibCrystaxDir(abi)
return paths
} def getTargetLibDir(abi, buildType) {
return "${buildDir}/intermediates/binaries/${buildType}/${getFlavorName(abi)}/lib/${abi}"
} def getLibCrystaxDir(abi) {
return "${getCrystaxNdkDir()}/sources/crystax/libs/${abi}"
} def getLibCrystax(abi) {
return "${getLibCrystaxDir(abi)}/libcrystax.so"
} def getBoostDir() {
return "${getCrystaxNdkDir()}/sources/boost/1.58.0"
} def getBoostIncDir() {
return "${getBoostDir()}/include"
} def getBoostLibDir(abi) {
return "${getBoostDir()}/libs/${abi}"
}
使用Android Studo开发NDK之Gradle的配置(能debug C代码)的更多相关文章
- Android高效开发环境(Genymotion,Gradle,Andriod Studio)
临近十一,项目接近上线,终于有些碎片时间可以查看一些博客. 这篇博客是Android开发大牛Cyril Mottier在去年写的博客,我把它翻译一下共享给国内志同道合的朋友,同时也是对自己一个很好的锻 ...
- [Android] 环境配置之Android Studio开发NDK
分类:Android环境搭建 (14351) (20) ========================================================作者:qiujuer博客:bl ...
- Mac Android开发环境变量的配置(java、sdk、ndk、gradle)
1.打开terminal 2.然后输入 vi .bash_profile 后按"e"进入编辑模式 3.输入想要配置的环境变量(Java.sdk.ndk.gradle): expor ...
- Android NDK开发 Android Studio使用新的Gradle构建工具配置NDK环境(一)
本文主要讲述了如何如何在Android Studio使用新的Gradle构建工具配置NDK环境,现在把相关的步骤整理出来分享给Android程序员兄弟们,希望给他们在配置NDK环境时带来帮助. 从An ...
- android 串口开发第一篇:搭建ndk开发环境以及第一个jni调用程序
一:ndk环境搭建 1:开发环境 我使用的是android studio 2.3.3版本,搭建ndk开发环境比较简单,打开File----Settings----Appearance&Beha ...
- Android开发之深入理解Android Studio构建文件build.gradle配置
摘要: 每周一次,深入学习Android教程,TeachCourse今天带来的一篇关于Android Studio构建文件build.gradle的相关配置,重点学习几个方面的内容:1.applica ...
- Android应用开发编译框架流程与IDE及Gradle概要
1 背景 建议阅读本文之前先阅读<Android Studio入门到精通>和<Groovy脚本基础全攻略>及<Gradle脚本基础全攻略>三篇博客作为背景知识,这样 ...
- Android游戏开发实践(1)之NDK与JNI开发03
Android游戏开发实践(1)之NDK与JNI开发03 前面已经分享了两篇有关Android平台NDK与JNI开发相关的内容.以下列举前面两篇的链接地址,感兴趣的可以再回顾下.那么,这篇继续这个小专 ...
- Android游戏开发实践(1)之NDK与JNI开发01
Android游戏开发实践(1)之NDK与JNI开发01 NDK是Native Developement Kit的缩写,顾名思义,NDK是Google提供的一套原生Java代码与本地C/C++代码&q ...
随机推荐
- php 0,null,empty,空,false,字符串关系(转)
在php中由于是弱类型语言,不同类型值之间可以隐式转换,使得false,null,”,0,’0′这几个值的比较有些混乱,现总结一下: //相等判断 '' == NULL == 0 == false ( ...
- flex和layout移动端布局
1.九宫格 样式为: ul{ display: flex; flex-wrap: wrap;//超出换行 } li{ width: 33%; height: 60px; display: flex; ...
- Pop3协议详解
POP3全称为Post Office Protocol version3,即邮局协议第3版.它被用户代理用来邮件服务器取得邮件.POP3采用的也是C/S通信 模型 用户从邮件服务器上接收邮件的典型 ...
- 解决生成主键 id重复的解决办法
作者:董春秋链接:https://www.zhihu.com/question/30674667/answer/49082988来源:知乎著作权归作者所有,转载请联系作者获得授权. 全局id生成器.我 ...
- 逐步理解Java中的线程安全问题
什么是Java的线程安全问题? 线程安全就是多线程访问时,采用了加锁机制,当一个线程访问该类的某个数据时,进行保护,其他线程不能进行访问直到该线程读/写完,其他线程才可使用.不会出现数据不一致或者数据 ...
- vc++创建窗体
//创建窗口,一般分为四步 /*1 WinMain函数的定义 2 创建一个窗口 3 编写消息循环 4 编写窗口过程函数*/ #include <windows.h> //包含windows ...
- word2016如何英汉互译
1.如果是一篇英文文档且是pdf格式,可以用word2016打开直接转化成了word,就算不是会员也可以的,在此附上16版的光盘安装包,可以百度自行下载 (链接:https://pan.baidu.c ...
- linux笔记常用命令
LINUX成长日记 1.本人工作实例:(将一台服务器的数据库复制到另外一台服务器上) scp -r -P 8351 /bak_mysql/sz_b2b2c201705180200.sql root@1 ...
- 【BZOJ2806】【CTSC2012】Cheat - 广义后缀自动机+单调队列优化DP
题意: Description Input 第一行两个整数N,M表示待检查的作文数量,和小强的标准作文库的行数 接下来M行的01串,表示标准作文库 接下来N行的01串,表示N篇作文 Output N行 ...
- javascript的带操作符的赋值运算
看犀牛书发现的问题 下面两个表达式 表达式一 data[i++] *= 2; 表达式二 data[i++] = data[i++] * 2; var data = [7,8,9]; var i = ...