dimanche 19 juin 2016

Debug Mapbox Android NDK library


I am attempting to follow the Android Studio Experimental Plugin User Guide instructions located at:

http://tools.android.com/tech-docs/new-build-system/gradle-experimental

to modify the Mapbox GL Native library located at:

https://github.com/mapbox/mapbox-gl-native

In specific, I have modified the following Android files:

https://github.com/mapbox/mapbox-gl-native/blob/master/platform/android/gradle/wrapper/gradle-wrapper.properties

https://github.com/mapbox/mapbox-gl-native/blob/master/platform/android/build.gradle

https://github.com/mapbox/mapbox-gl-native/blob/master/platform/android/MapboxGLAndroidSDK/build.gradle

https://github.com/mapbox/mapbox-gl-native/blob/master/platform/android/MapboxGLAndroidSDKTestApp/build.gradle

My goal is to modify the library so I can debug it. Ideally I would be able to use Android Studio to build the library and debug the C/C++ code. So far I can build it, but I can't debug it. A programmer working at Mapbox told me they don't how to debug the Android code either, so I suspect this isn't an easy goal to reach.

I have made many different attempts to apply the Android Studio Experimental Plugin User Guide instructions, but I'm not experienced at Gradle and my latest attempt is leaving me with the following error message which I don't understand:

Gradle 'android' project refresh failed Error:Cause:org.gradle.api.internal.ExtensibleDynamicObject

Does anyone know how to modify these files to have them build a debuggable Android NDK Library? What is causing the above error?

I am using:

> Linux Mint 17.2 
> Android Studio 2.1.1 
> Build #AI-143.2821654, built on April 28, 2016 
> JRE: 1.8.0_65-b17 amd64 
> JVM: Java HotSpot(TM) 64-Bit Server VM by Oracle Corporation

Below are the 4 files as I currently have them modified. Since I am new to Gradle, do not assume I have made any modfications correctly. I was merely attempting to apply the Android Studio Experimental Plugin User Guide instructions until I got a successful build.

Thanks


#// mapbox-gl-native/platform/android/gradle/wrapper/gradle-wrapper.properties

#Thu Apr 07 14:21:05 CDT 2016

distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
#//distributionUrl=https://services.gradle.org/distributions/gradle-2.12-bin.zip
#//distributionUrl=https://services.gradle.org/distributions/gradle-2.10-all.zip
distributionUrl=https://services.gradle.org/distributions/gradle-2.11-all.zip
distributionSha256Sum=e77064981906cd0476ff1e0de3e6fef747bd18e140960f1915cca8ff6c33ab5c

// mapbox-gl-native/platform/android/MapboxGLAndroidSDKTestApp/build.gradle

// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    repositories {
        jcenter()
        maven { url 'https://jitpack.io' }
    }
    dependencies {
        // classpath 'com.android.tools.build:gradle:2.1.0'
        //classpath 'com.android.tools.build:gradle-experimental:0.7.0'
        classpath 'com.android.tools.build:gradle-experimental:0.8.0-alpha2'
        classpath 'com.github.JakeWharton:sdk-manager-plugin:220bf7a88a7072df3ed16dc8466fb144f2817070'

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        jcenter()
        maven { url "http://oss.sonatype.org/content/repositories/snapshots/" }
    }
}

task wrapper(type: Wrapper) {
    gradleVersion = '2.12'
}

// mapbox-gl-native/platform/android/MapboxGLAndroidSDK/build.gradle

apply plugin: 'android-sdk-manager'
apply plugin: 'com.android.model.library'
apply plugin: 'checkstyle'
apply plugin: 'maven'
apply plugin: 'signing'

allprojects {
    group project.GROUP
    version project.VERSION_NAME

    repositories {
        mavenCentral()
    }
}

repositories {
    mavenCentral()
}

ext {
    supportLibVersion = '23.4.0'
}

dependencies {
    compile "com.android.support:support-annotations:${supportLibVersion}"
    compile "com.android.support:support-v4:${supportLibVersion}"
    compile "com.android.support:design:${supportLibVersion}"
    compile 'com.squareup.okhttp3:okhttp:3.3.0'
    compile 'com.mapzen.android:lost:1.1.0'
}

model {
android {
    compileSdkVersion Integer.parseInt(project.ANDROID_BUILD_SDK_VERSION)
    buildToolsVersion project.ANDROID_BUILD_TOOLS_VERSION

    defaultConfig {
        minSdkVersion Integer.parseInt(project.ANDROID_MIN_SDK)
        targetSdkVersion Integer.parseInt(project.ANDROID_BUILD_TARGET_SDK_VERSION)
    }

    sourceSets {
        main.res.srcDirs += 'src/main/res-public'
    }

    repositories {
        mavenCentral()
    }

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_7
        targetCompatibility JavaVersion.VERSION_1_7
    }

    lintOptions {
        checkAllWarnings true
        warningsAsErrors true
    }

    buildTypes {
        debug {
            jniDebuggable true
            buildConfigField "String", "MAPBOX_EVENTS_USER_AGENT_BASE", new StringBuilder().append(""").append("MapboxEventsAndroid/").append(project.VERSION_NAME).append(""").toString()
        }

        release {
            jniDebuggable false
            buildConfigField "String", "MAPBOX_EVENTS_USER_AGENT_BASE", new StringBuilder().append(""").append("MapboxEventsAndroid/").append(project.VERSION_NAME).append(""").toString()
            consumerProguardFiles 'proguard-rules.pro'
        }
    }
}
}

configurations {
    all*.exclude group: 'commons-logging', module: 'commons-logging'
    all*.exclude group: 'commons-collections', module: 'commons-collections'
}

model {
android.libraryVariants.all { variant ->
    def name = variant.name
    task "javadoc$name"(type: Javadoc) {
        description = "Generates javadoc for build $name"
        failOnError = false
        destinationDir = new File(destinationDir, variant.baseName)
        source = files(variant.javaCompile.source)
        classpath = files(variant.javaCompile.classpath.files) + files(android.bootClasspath)
        exclude '**/R.java', '**/BuildConfig.java', 'com/almeros/**'
        options.windowTitle("Mapbox Android SDK $VERSION_NAME Reference")
        options.docTitle("Mapbox Android SDK $VERSION_NAME")
        options.header("Mapbox Android SDK $VERSION_NAME Reference")
        options.bottom("© 2015–2016 Mapbox. All rights reserved.")
        options.links("http://docs.oracle.com/javase/7/docs/api/")
        options.linksOffline("http://d.android.com/reference/", "$System.env.ANDROID_HOME/docs/reference")
        options.overview("src/main/java/overview.html")
        options.group("Mapbox Android SDK", "com.mapbox.*")
        options.group("Third Party Libraries", "com.almeros.*")
        // TODO exclude generated R, BuildConfig, com.almeros.*
    }
}
}

checkstyle {
    configFile project.file('../checks.xml')
    showViolations true
}

/*
task cleanJNIBuilds {
    def jniLibsDir = new File("MapboxGLAndroidSDK/src/main/jniLibs")
    delete jniLibsDir.absolutePath
}
*/

model
{
android.libraryVariants.all { variant ->
    def name = variant.buildType.name
    def checkstyle = project.tasks.create "checkstyle${name.capitalize()}", Checkstyle
    checkstyle.dependsOn variant.javaCompile
    checkstyle.source variant.javaCompile.source
    checkstyle.classpath = project.fileTree(variant.javaCompile.destinationDir)
    checkstyle.exclude('**/BuildConfig.java')
    checkstyle.exclude('**/R.java')
    checkstyle.exclude('**/com/almeros/android/multitouch/**')
    project.tasks.getByName("check").dependsOn checkstyle
}

// From https://raw.github.com/mcxiaoke/gradle-mvn-push/master/jar.gradle
android.libraryVariants.all { variant ->
    def jarTask = project.tasks.create(name: "jar${variant.name.capitalize()}", type: Jar) {
        from variant.javaCompile.destinationDir
        exclude "**/R.class"
        exclude "**/BuildConfig.class"
    }
    jarTask.dependsOn variant.javaCompile
    artifacts.add('archives', jarTask);
}
}

// From https://raw.github.com/mcxiaoke/gradle-mvn-push/master/gradle-mvn-push.gradle
def isReleaseBuild() {
    return VERSION_NAME.contains("SNAPSHOT") == false
}

def getReleaseRepositoryUrl() {
    return hasProperty('RELEASE_REPOSITORY_URL') ? RELEASE_REPOSITORY_URL :
            "https://oss.sonatype.org/service/local/staging/deploy/maven2/"
}

def getSnapshotRepositoryUrl() {
    return hasProperty('SNAPSHOT_REPOSITORY_URL') ? SNAPSHOT_REPOSITORY_URL :
            "https://oss.sonatype.org/content/repositories/snapshots/"
}

def getRepositoryUsername() {
    return hasProperty('USERNAME') ? USERNAME :
            (hasProperty('NEXUS_USERNAME') ? NEXUS_USERNAME : "")
}

def getRepositoryPassword() {
    return hasProperty('PASSWORD') ? PASSWORD :
            (hasProperty('NEXUS_PASSWORD') ? NEXUS_PASSWORD : "")
}


task apklib(type: Zip) {
    appendix = extension = 'apklib'

    from 'AndroidManifest.xml'
    into('res') {
        from 'res'
    }
    into('src') {
        from 'src'
    }
}

artifacts {
    archives apklib
}

afterEvaluate { project ->
    uploadArchives {
        repositories {
            mavenDeployer {
                beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) }

                pom.groupId = GROUP
                pom.artifactId = POM_ARTIFACT_ID
                pom.version = VERSION_NAME

                repository(url: getReleaseRepositoryUrl()) {
                    authentication(userName: getRepositoryUsername(),
                            password: getRepositoryPassword())
                }
                snapshotRepository(url: getSnapshotRepositoryUrl()) {
                    authentication(userName: getRepositoryUsername(),
                            password: getRepositoryPassword())
                }

/*
                // Leaving out as artifact was incorrectly named when found
                addFilter('aar') { artifact, file ->
                    artifact.name == archivesBaseName
                }
                addFilter('apklib') { artifact, file ->
                    artifact.name == archivesBaseName + '-apklib'
                }
*/

                pom.project {
                    name POM_NAME
                    packaging POM_PACKAGING
                    description POM_DESCRIPTION
                    url POM_URL

                    scm {
                        url POM_SCM_URL
                        connection POM_SCM_CONNECTION
                        developerConnection POM_SCM_DEV_CONNECTION
                    }

                    licenses {
                        license {
                            name POM_LICENCE_NAME
                            url POM_LICENCE_URL
                            distribution POM_LICENCE_DIST
                        }
                    }

                    developers {
                        developer {
                            id POM_DEVELOPER_ID
                            name POM_DEVELOPER_NAME
                        }
                    }
                }
            }
        }
    }

    signing {
        required { isReleaseBuild() && gradle.taskGraph.hasTask("uploadArchives") }
        sign configurations.archives
    }

    model {
    task androidJavadocs(type: Javadoc) {
        source = android.sourceSets.main.java.sourceFiles
        classpath = files(android.bootClasspath)
    }
    }

    task androidJavadocsJar(type: Jar, dependsOn: androidJavadocs) {
        classifier = 'javadoc'
        from androidJavadocs.destinationDir
    }

    model {
    task androidSourcesJar(type: Jar) {
        classifier = 'sources'
        from android.sourceSets.main.java.sourceFiles
    }
    }

    artifacts {
        archives androidSourcesJar
        archives androidJavadocsJar
    }
}


task makeClean(type: Exec) {
    workingDir '../../'
    commandLine 'make', 'clean'
}

task makeAndroid(type: Exec) {
    workingDir '../../'
    commandLine 'make', 'android'
}

task makeAndroidAll(type: Exec) {
    workingDir '../../'
    commandLine 'make', 'apackage'
}

// mapbox-gl-native/platform/android/MapboxGLAndroidSDKTestApp/build.gradle

apply plugin: 'android-sdk-manager'
apply plugin: 'com.android.model.application'
apply plugin: 'checkstyle'

task accessToken {
    def tokenFile = new File("MapboxGLAndroidSDKTestApp/src/main/res/values/developer-config.xml")
    if (!tokenFile.exists()) {
        String tokenFileContents = "<?xml version="1.0" encoding="utf-8"?>n" +
                "<resources>n" +
                "    <string name="mapbox_access_token">" + "$System.env.MAPBOX_ACCESS_TOKEN" + "</string>n" +
                "</resources>"

        if (tokenFileContents == null) {
            throw new InvalidUserDataException("You must set the MAPBOX_ACCESS_TOKEN environment variable.")
        }
        tokenFile.write(tokenFileContents)
    }
}

gradle.projectsEvaluated {
    // preBuild.dependsOn('accessToken')
}

ext {
    supportLibVersion = '23.4.0'
}

model {
android {
    compileSdkVersion 23
    buildToolsVersion "23.0.3"

    defaultConfig {
        applicationId "com.mapbox.mapboxsdk.testapp"
        minSdkVersion.apiLevel 15
        targetSdkVersion.apiLevel 23
        versionCode 9
        versionName "4.1.0"

        // Specify AndroidJUnitRunner as the default test instrumentation runner
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_7
        targetCompatibility JavaVersion.VERSION_1_7
    }

    packagingOptions {
        exclude 'META-INF/LICENSE.txt'
        exclude 'META-INF/NOTICE.txt'
        exclude 'LICENSE.txt'
    }

    lintOptions {
        checkAllWarnings true
        warningsAsErrors true
        disable 'IconDensities'
        disable 'InvalidPackage'
    }

    testOptions {
        unitTests.returnDefaultValues = true
    }

    buildTypes {
        debug {
            // run code coverage reports
            testCoverageEnabled = true
        }
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}
}

dependencies {
    compile(project(':MapboxGLAndroidSDK')) {
        transitive = true
    }

    // Support libraries
    compile "com.android.support:support-annotations:${supportLibVersion}"
    compile "com.android.support:support-v4:${supportLibVersion}"
    compile "com.android.support:appcompat-v7:${supportLibVersion}"
    compile "com.android.support:design:${supportLibVersion}"
    compile "com.android.support:recyclerview-v7:${supportLibVersion}"

    // Leak Canary
    //debugCompile 'com.squareup.leakcanary:leakcanary-android:1.4-beta1'
    //releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.4-beta1'

    // Directions SDK
    compile('com.mapbox.mapboxsdk:mapbox-android-directions:1.0.0@aar') {
        transitive = true
    }

    // Geocoder SDK
    compile('com.mapbox.mapboxsdk:mapbox-android-geocoder:1.0.0@aar') {
        transitive = true
    }

    // Testing dependencies
    testCompile 'junit:junit:4.12'
    testCompile 'org.mockito:mockito-core:1.10.19'
    androidTestCompile "com.android.support:support-annotations:${supportLibVersion}"
    androidTestCompile 'com.android.support.test:runner:0.4.1'
    androidTestCompile 'com.android.support.test:rules:0.4.1'
    androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.1'
    androidTestCompile 'com.jayway.android.robotium:robotium-solo:5.5.4'
}

checkstyle {
    configFile project.file('../checks.xml')
    showViolations true
}

model {
android.applicationVariants.all { variant ->
    def name = variant.buildType.name
    def checkstyle = project.tasks.create "checkstyle${name.capitalize()}", Checkstyle
    checkstyle.dependsOn variant.javaCompile
    checkstyle.source variant.javaCompile.source
    checkstyle.classpath = project.fileTree(variant.javaCompile.destinationDir)
    checkstyle.exclude('**/BuildConfig.java')
    checkstyle.exclude('**/R.java')
    project.tasks.getByName("check").dependsOn checkstyle
}
}

Aucun commentaire:

Enregistrer un commentaire