Log in

Previous Entry | Next Entry

Some Gradle clarifications


  • 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:


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'
    - 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.

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


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