zoukankan      html  css  js  c++  java
  • 使用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}"
    }


  • 相关阅读:
    Data Base Oracle 常用命令
    ASP.NET Core ASP.NET Core+MVC搭建及部署
    Hadoop 之 MapReduce 框架演变详解
    计算机网络: IP地址,子网掩码,默认网关,DNS服务器详解
    Linux系统基本网络配置之ifconfig命令
    Linux-eth0 eth0:1 和eth0.1关系、ifconfig以及虚拟IP实现介绍
    Linux 中将用户添加到组的指令
    几种常见的Shell
    常见的Shell
    Linux(CentOS6.5)下创建新用户和组,并制定用户和组ID
  • 原文地址:https://www.cnblogs.com/slgkaifa/p/7083331.html
Copyright © 2011-2022 走看看