使用Android Studo开发NDK之Gradle的配置(能debug C代码)

来源:互联网 发布:令狐公子 知乎 编辑:程序博客网 时间:2024/05/22 10:41
配置:

用的版本是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.Osimport 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}"}


1 0