新建一个安卓项目,Android Studio已经为我们生成的模板中,build.gradle总是很显眼。我也终于下定决心来了解下这个构建整合工具。

gradle脚本使用groovy编写,最近也开始支持用Kotlin编写。Kotlin大法好,但我暂时只找到了groovy的教程3,暂时不想去啃英文,先将就学着。

gradle安装

命令

对于OSX用户来说,brew install gradle就可以搞定这个步骤了。但是这里有个问题,就是这样会把openjdk当做依赖装上。也不算很大的问题,也能将就用。

gradle wrapper

gradle有一个很方便的命令,gradle wrapper,使用后会创建如下的目录结构

.
├── build.gradle
├── gradle
│   └── wrapper
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradlew
└── gradlew.bat

此时即使你没有安装gradle,仍然可以使用./gradlew代替gradle执行命令。如./gradlew clean install。在实际的项目中,这种方式使用比较普遍,因为gradle脚本很多特性受版本影响比较大,一般gradle的版本也会在项目中指定。

task

基本使用

task即构建任务,一个最简单的构建任务如下

task hello {
    doLast {
        println 'Hello world!'
    }
}

此时输入gradle -q hello就可以看到输出了。-qquiet,会忽略一些gradle自身的输出。

教程中还写了一种更简洁的写法1,但我发现这种写法已经被废弃2,不再写出。

任务依赖

声明任务间的依赖关系。

task taskY {
	doLast {
		println 'taskY'
	}
}
task taskX(dependsOn: taskY) {
	doLast {
		println 'taskX'
	}
}

task taskX(dependsOn: 'taskY') { //因为taskY还未定义,只能这样使用
	doLast {
		println 'taskX'
	}
}
task taskY {
	doLast {
		println 'taskY'
	}
}
➜  task gradle -q taskX
taskY
taskX
➜  task

动态任务

可以动态创建任务,使用已经存在的任务。

4.times { counter ->
    task "task$counter" {
		doLast{
			println "I'm task number $counter"
		}
	}
}
task0.dependsOn task2, task3
➜  task gradle -q task0
I'm task number 2
I'm task number 3
I'm task number 0
➜  task 

自定义属性

自定义属性和默认任务

defaultTasks 'information','hello'

task information {
	doLast {
		println 'I use this script to learn gradle.'
	}
}

task hello {
	ext {
		computer = 'IF'
		user = 'Haidee'
	}

	doLast {
		println 'Hello Susan'
	}	
	
	doFirst {
		println 'Hello Zero'
	}

	doLast {
		println "There are also $hello.computer and $hello.user in our organization."
	}
}
➜  task gradle -q
I use this script to learn gradle.
Hello Zero
Hello Susan
There are also IF and Haidee in our organization.
➜  task 

判断发布任务是否在要被执行的任务中

task distribution << {
    println "We build the zip with version=$version"
}

task release(dependsOn: 'distribution') << {
    println 'We release now'
}

gradle.taskGraph.whenReady {taskGraph ->
    if (taskGraph.hasTask(release)) {
        version = '1.0'
    } else {
        version = '1.0-SNAPSHOT'
    }
}
➜  task gradle -q distribution
We build the zip with version=1.0-SNAPSHOT
➜  task gradle -q release
We build the zip with version=1.0
We release now
➜  task 

使用gradle tasks --all可以列出当前项目所有构建任务。

java构建

基础java项目

mkdir javaproject
cd javaproject
mkdir -p src/main/java
mkdir -p src/test/java
echo "apply plugin: 'java'" > build.gradle
.
├── build.gradle
└── src
    ├── main
    │   └── java
    └── test
        └── java

5 directories, 1 file

添加依赖

repositories {
    mavenCentral()
}

dependencies {
    implementation group: 'commons-collections', name: 'commons-collections', version: '3.2'
    testImplementation group: 'junit', name: 'junit', version: '4.+'
}

定制 MANIFEST.MF 文件

sourceCompatibility = 1.8
version = '1.0'

jar {
    manifest {
        attributes 'Implementation-Title': 'Gradle Quickstart', 'Implementation-Version': version
    }
}

发布jar文件

uploadArchives {
    repositories {
       flatDir {
           dirs 'repos'
       }
    }
}

多项目java构建

mkdir multiproject
cd multiproject
mkdir api
mkdir -p services/webservice
mkdir shared

项目结构

.
├── api
│   ├── build
│   └── build.gradle
├── build.gradle
├── services
│   └── webservice
│       └── build.gradle
├── settings.gradle
└── shared
    └── build.gradle

settings.gradle指定要包括哪个项目。

include "shared", "api", "services:webservice", "services:shared"

通用配置

根项目的build.gradle

subprojects {
    apply plugin: 'java'

    repositories {
        mavenCentral()
    }

    dependencies {
        testImplementation 'junit:junit:4.11'
    }

    version = '1.0'

    jar {
        manifest.attributes provider: 'gradle'
    }
}

项目之间的依赖

api/build.gradle

dependencies {
    compile project(':shared')
}

依赖管理基础知识

依赖类型,待整理,当前找到的资料有点乱。

引用外部依赖需要groupnameversion属性。

仓库(未完全验证)。

repositories {
    mavenCentral()
    maven {
        url "http://repo.mycompany.com/maven2"
    }
    ivy {
        url "http://repo.mycompany.com/repo"
    }
    ivy {
        // URL can refer to a local directory
        url "../local-repo"
    }
}

groovy快速入门

就一个例子,入门入了个寂寞。

apply plugin: 'groovy'

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.codehaus.groovy:groovy-all:2.3.3'
    testImplementation 'junit:junit:4.11'
}

编写构建脚本

标准项目属性

project对象提供了一些标准属性,可以在对象中很方便地使用。

NameTypeDefault Value
projectProjectProject 实例对象
nameString项目目录的名称
pathString项目的绝对路径
descriptionString项目描述
projectDirFile包含构建脚本的目录
buildFileprojectDir/build
groupObject未具体说明
versionObject未具体说明
antAntBuilderAnt实例对象

来自Gradle User Guide3,未验证。

变量

声明变量

def dest = "dest"

拓展属性

ext {
    springVersion = "3.1.0.RELEASE"
    emailNotification = "[email protected]"
}

方法

圆括号可选。

avatar

归零幻想

邮件:[email protected]
Telegram: @zerofancy

正在追番《艾克斯奥特曼》。
——站长
RSS

友情链接