?

Log in

Previous Entry | Next Entry

Some Gradle clarifications

Shotcuts:

  • Any task defines doLast() and doFirst() public methods. The << operator is simply alias for doLast.

task transform {
              doLast {
                println "Executing $it task"
              }
          }

          is equals to

          task transform << {
           println "Executing $it task"
          }

          N.B. whenever it used, $it refers to the current instance of Gradle entity

  • gradle.taskGraph.whenReady is executed after configuration stage is completed for per-project basis. For example:

gradle.taskGraph.whenReady { taskGraph ->
        if( taskGraph.hasTask(loadFile) ) {
              version = '1.0'
        } else {
              version = '1.0-SNAPSHOT'
}
    println project
    println version
}

        N.B. project is pre-defined variable. Usually it stands for the current directory of the script

  • task myCopy(type: Copy) means that task myCopy 'inherits' from Gradle-supplied task Copy

Task configuration

Execution stage of Gradle always follows the configuration stage. When configuration stage mostlyperformed silently, the execution stage is invoked by cmd gradle <-quiet> <task>
At configuration stage it is possible to configure various properties of the tasks. For example, consider the following tasks:
   task transform(type: Copy, description: 'Transformation') << {
        println "Executing $it task"
        ext.srcFile = 'default.html'
   }

  task buildMe << {
    println "accessing " + tasks.getByName('transform')
    transform.from 'resources'
    transform.into 'target'
  }

  N.B. tasks.getByName('transform') my be simpified to prinln "accessing " + transform
  N.B.2 transform.from 'resources' assumes the base task - Copy - has an API (not just property!) from. No = is used by Groovy to assign the value in this case.
 N.B.3 two operators
transform.from 'resources'
transform.into 'target'

  may be expressed as a single compound one:

  transform {
      from 'resources'
      into 'target'
}

Access to the system


def opencvhome = System.getenv('OPENCV_HOME')
println opencvhome

Gradle Wrapper

Gradle Wrapper serves for Gradle integratation in VCS. Especially this used with Continuous Integration servers like Jenkins or Travis. The Wrapper is actually an jar (gradle-wrapper.jar) that can be created by invoking gradle wrapper with a version specified. Being stored in VCS, the wrapper persists the used version and furthermore, if this version is not present on the system, it is able to download it. Changing the used version is easy because Gradle Wrapper reads its configuration from associated gradle-wrapper.properties file.  For example, the following configuration may be used to exploit the Gradle 2.5:

distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.5-all.zip

Plugins
Plugins are just sets of the tasks. For AS, the most usefull pluig is 'android' or recently, with advent of AS 1.3, the experimental 'com.android.model.application'. Each plugin defines its own API, for example, the experimental plugin defines the following structure:

apply plugin: 'com.android.model.application'
-model
    - compileOptions.with
        - sourceCompatibility
        - targetCompatibility
    - android
        - defaultConfig.with
    - android.ndk
    - android.buildTypes
    - android.productFlavors
    - android.sources
        - main
          - jni
          - java
            - source
          - jniLibs
- dependencies
Let's see how this configuration applies to AS. With "normal" settings pointing java source to 'src' it looks like



When java source changes intentionally to something different - srcXXX, AS tries to find the source at this 'wrong' location and re-structure the project:



android.sources should be mentioned with double care. As for old, plain 'android' plugin, Google introduced a new folder 'jniLibs' to the source sets. This means that you can add the prebuilt .so files to this folder, and the plugin will take care of packaging those native libraries inside APK.

Sample
import org.apache.tools.ant.taskdefs.condition.Os

apply plugin: 'com.android.model.application'

model {

    compileOptions.with {
        sourceCompatibility = JavaVersion.VERSION_1_7
        targetCompatibility = JavaVersion.VERSION_1_7
    }

    android {
        compileSdkVersion = 22
        buildToolsVersion = "22.0.1"

        defaultConfig.with {
            applicationId = "com.example.oleg.myapplication"
            minSdkVersion.apiLevel = 18
            targetSdkVersion.apiLevel = 22
            versionCode = 1
            versionName = "1.0"
            multiDexEnabled = true
            testInstrumentationRunner = "android.support.test.runner.AndroidJUnitRunner"
        }

    }

    android.ndk {
        moduleName = "fastcvUtils"

        //abiFilters += ["armeabi", "armeabi-v7a", "x86"]
        abiFilters += "armeabi-v7a"

        // Link with static OpenCV libraries: the order is important!
        // The following order taken from OpenCV.mk
        def opencv_modules = ["shape", "stitching", "objdetect", "superres", "videostab", "calib3d", "features2d", "highgui", "videoio", "imgcodecs", "video", "photo", "ml", "imgproc", "flann", "core", "hal"]

        ldLibs += ["log","stdc++","dl", "z"]

        abiFilters.each { targetAbi ->
            println targetAbi

            opencv_modules.each{ module ->
                ldLibs += file(projectDir).absolutePath + "/src/main/jniLibs/" + targetAbi + "/libopencv_" + module + ".a"
            }
        }

        cppFlags   += "-Werror"
        cppFlags   += "--debug"
        cppFlags   += "-frtti"
        cppFlags   += "-fexceptions"
        cppFlags += "-I/Users/Oleg/Downloads/OpenCV-android-sdk/sdk/native/jni/include"
        //cppFlags    += "-std=c++11" // for lambda-expressions

        ldLibs += file(projectDir).absolutePath+"/src/main/jniLibs/armeabi-v7a/libtbb.a"

        stl = "gnustl_static"

    }

    android.buildTypes {
        release {
            isMinifyEnabled = false
            proguardFiles += file('proguard-android.pro')
            isJniDebuggable = true
            isDebuggable = true
        }

        debug {
            isJniDebuggable = true
            isDebuggable = true
        }
    }

    android.productFlavors {

        create("arm") {
            ndk.with {

                abiFilters += "armeabi"
                println "*** building for arm"
            }

        }

        create("armv7") {
            ndk.with {

                abiFilters += "armeabi-v7a"
                println "*** building for armv7"
            }

        }

        create("x86") {
            ndk.with {
                abiFilters += "x86"
                println "*** building for x86"
            }
        }
    }

    components.android {
        binaries.afterEach { binary ->
            println binary.name
            binary.mergedNdkConfig.cppFlags.add("-std=c++11")
        }
    }

}

dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    compile 'com.android.support:appcompat-v7:22.2.1'
    compile project(':opencv')
}


Tags: