【使用Android Studo开发NDK之Gradle的配置(能debug C代码)】观书散遗帙,探古穷至妙。这篇文章主要讲述使用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_ROOTProperties 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 App 内存泄露之Thread
- Android eclipse 提示java代码 快捷键
- Android 解决ViewPager双层嵌套的滑动问题
- Android在程序中浏览网页
- xxx.app已损坏,打不开.你应该将它移到废纸篓-已解决
- Android 自定义View - 饼图
- Android 使用AIDL实现进程间的通信
- 25款最佳免费绿屏(色度键)软件和应用程序
- 18款最佳免费DVD复制软件合集(哪个最适合你())