Gradle 基础用法
命令行
执行任务
可以通过命令行执行一个或多个任务
# 执行任务 compile
> gradle compile
# 按顺序执行多个任务任务 compile, test
> gradle compile test
任务依赖
下面定义四个任务,dist
和test
依赖于comile
任务,执行gradle dist test
时compile
任务只会被执行一次。
build.gradle
task compile {
doLast {
println 'compiling source'
}
}
task compileTest(dependsOn: compile) {
doLast {
println 'compiling unit tests'
}
}
task test(dependsOn: [compile, compileTest]) {
doLast {
println 'running unit tests'
}
}
task dist(dependsOn: [compile, test]) {
doLast {
println 'building the distribution'
}
}
执行gradle dist test
后输出
> gradle dist test
:compile
compiling source
:compileTest
compiling unit tests
:test
running unit tests
:dist
building the distribution
BUILD SUCCESSFUL in 0s
4 actionable tasks: 4 executed
任务名称缩写
在命令行指定任务名时不必使用完整的任务名,只需提供能唯一识别任务的部分即可。
比如任务zee
可以通过以下命令执行:
> gradle z
> gradle ze
> gradle zee
假设同时存在任务zee
,zoo
,执行gradle z
将失败。
可以对驼峰式任务名中的各个单词使用缩写,比如任务fooBar
可以通过以下命令执行:
> gradle fB
> gradle foB
> gradle fooB
...
> gradle foBa
...
> gradle fooBar
获取构建信息
Gradle提供了一些内建任务以获取特定的构建信息,以便调试问题和理解构建的结构与依赖。
# 以树形结构列出当前项目子项目
> gradle -q projects
# 显示当前项目项的任务列表
> gradle -q tasks
# 显示当前项目项的所有任务
> gradle -q tasks --all
# 查看任务信息
> gradle -q help --task <task>
# 显示当前项目的依赖
> gradle dependencies
# 显示指定子项目的依赖
> gradle <subproject>:dependencies
# 显示当前项目buildscript的依赖
> gradle buildEnvironment
# 显示指定子项目buildscript的依赖
> gradle <subproject>:buildEnvironment
# 查看特定配置中指定依赖的依赖
> gradle -q <subproject>:dependencyInsight --dependency <dependency> --configuration <configuration>
# 查看项目属性
> gradle -q <subproject>:properties
命令行选项
-
-?,-h,--help
: 打印所有的命令行选项 -
-i, --info
: 改变日志级别为INFO -
-q, --quiet
: 只打印错误信息 -
-S, --full-stacktrace
: 发生错误时打印完整堆栈信息 -
-s, --stacktrace
: 发生错误时打印堆栈信息 -
-b, --build-file
: 指定执行的构建脚本(默认build.gradle) -
-c, --settings-file
: 指定配置脚本(默认settings.gradle) -
-D, --system-prop
: 传递一个系统属性给JVM,比如:-Dmyprop=myvalue -
-P, --project-prop
: 传递一个项目属性值给构建脚本,比如:-Pmyprop=myvalue -
--offline
: 以离线模式运行构建(Gradle只检查本地缓存中的依赖) -
-x, --exclude-task
: 执行构建时排除指定任务
参考
https://docs.gradle.org/current/userguide/command_line_interface.html
构建脚本
Gradle 的一切建立在 项目(project)与任务(task) 这两个基本概念上。 参考
- 每个Gradle构建由一个或多个项目组成,项目代表什么取决于你想用做什么。它可以是一个JAR库或Web应用,也可以是一个由其它项目发行了ZIP。
- 每个项目由一个或多个任务组成,任务表示在构建中执行的某些原子的工作内容。比如编译一个类,创建一个JAR,生成Javadoc等。
在命令行使用gradle命令时,它会在当前目录寻找build.gradle文件,这个文件就是构建脚本(build script),定义了项目和它的任务。
任务基本写法
// 通过命令 gradle hello 执行
// 使用-q参数不输出日志 gradle -q hello
task hello {
doLast {
println 'Hello world!'
}
}
// 任务可以有依赖关系
task intro(dependsOn: hello) {
doLast {
println "I'm Gradle"
}
}
// doFirst和doLast可以被执行多次,动作被添加到列表中,任务执行时被依次调用。
hello.doLast {
println 'Hello Mars'
}
hello {
doLast {
println 'Hello Jupiter'
}
}
// 为任务添加额外的属性
task myTask {
ext.myProperty = "myValue"
}
task printTaskProperties {
doLast {
// 访问添加的属性
println myTask.myProperty
}
}
构建的生命周期(build lifecycle)
构建分为三个阶段
- 初始化(Initialization),Gradle支持单项目和多项目构建,在初始化阶段,确定哪些项目是构建的一部分,并创建
Project
实例。 - 配置(Configuration),在这个阶段所有项目对象(任务...)都被配置,属于构建的所有项目的
build scripts
都被执行。 - 执行(Execution),确定要被执行任务的子集并执行,此任务子集由命令行传入的任务名和当前目录决定。
settings.gradle 在初始化阶段被执行
println '===> initialization'
build.gradle
println '===> configuration - build.gradle - project a'
afterEvaluate {
println '===> evaluation - build.gradle - project.after'
}
beforeEvaluate {
println '===> evaluation - build.gradle - project.before'
}
task testOne {
println '===> configuration - build.gradle - task.one'
}
println '===> configuration - build.gradle - project b'
task testTwo {
doLast {
println '===> execution - build.gradle - task.two'
}
}
task testThree {
doFirst {
println '===> execution - build.gradle - task.three.doFirst'
}
doLast {
println '===> execution - build.gradle - task.three.doLast'
}
println '===> configuration - build.gradle - task.three'
}
执行 gradle testOne testTwo testThree
后输出
> gradle testOne testTwo testThree
===> initialization
===> configuration - build.gradle - project a
===> configuration - build.gradle - task.one
===> configuration - build.gradle - project b
===> configuration - build.gradle - task.three
===> evaluation - build.gradle - project.after
:app:testOne UP-TO-DATE
:app:testTwo
===> execution - build.gradle - task.two
:app:testThree
===> execution - build.gradle - task.three.doFirst
===> execution - build.gradle - task.three.doLast
为项目添加属性(gradle.properties)
Gradle 有多种方式以特定的顺序为项目添加属性,以不同方式设置的相同属性排序靠后的将被设置:
- 父项目目录的
gradle.properties
文件 - 项目目录的
gradle.properties
文件 - Gradle 用户根目录的
gradle.properties
文件(~/.gradle/gradle.properties) - 以
ORG_GRADLE_PROJECT_
开始的环境变量,对于环境变量ORG_GRADLE_PROJECT_myProperty
,会设置名为 myProperty 的属性。 - 以
-Dorg.gradle.project.
开始的系统属性,对于系统属性-Dorg.gradle.project.myProperty
,会设置名为 myProperty 的属性。 - 在命令行中设置的 -P 参数
参考
https://docs.gradle.org/current/userguide/build_environment.html
Gradle 包装器
Gradle 包装器会自动下载并安装指定版本的Gradle运行时,为开发人员提供一致的构建环境。
wrapper 任务
可以为wrapper任务指定一些参数
- --gradle-version 指定gradle运行时版本
- --distribution-type 指定发行包类型:bin只有二进制文件;all包含二进制,源码和文档
- --gradle-distribution-url 指定发行包下载地址
运行wrapper任务
> gradle wrapper --gradle-version 3.3
:wrapper
BUILD SUCCESSFUL
Total time: 1.416 secs
wrapper任务会生成以下文件
<project-root>/
gradlew
gradlew.bat
gradle/wrapper/
gradle-wrapper.jar
gradle-wrapper.properties
在运行gradlew命令构建时,它会先检查指定版本的Gradle运行时是否可用,如果不可用就先下载它。
下载的Gradle通常存放在 <project-root>/.gradle/wrapper/dists
参考
Gradle Wrapper
https://docs.gradle.org/current/userguide/gradle_wrapper.html
DSL Wrapper
https://docs.gradle.org/current/dsl/org.gradle.api.tasks.wrapper.Wrapper.html
使用插件
https://docs.gradle.org/current/userguide/plugins.html
使用分为两步
- 解析(resolve),找到正确的插件版本并添加到 script classpath。
脚本插件是在应用时自解析的,Gradle自带的核心插件是自动解析的。 - 应用(apply),在项目中对插件执行
Plugin.apply(T)
。
此操作是幂等的,多次调用无副作用。
应用插件
// 应用脚本插件
apply from: 'other.gradle'
// 根据类型应用插件
apply from: JavaPlugin
// 应用二进制插件
apply from: ‘java’
使用buildscript解析插件并应用
build.gradle
buildscript {
repositories {
jcenter()
}
dependencies {
classpath "com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.5"
}
}
apply plugin: "com.jfrog.bintray"
使用 plugins DSL 应用插件
plugins DSL 将解析与应用合并在一步执行,简化了用法。
plugins {
// 应用核心插件
id 'java'
// 应用已发布到 Gradle plugin portal 的插件
id "com.jfrog.bintray" version "1.7.3"
}
使用 plugins DSL 应用自定义仓库中的插件
在 settings.gradle 引入自定义插件仓库
pluginManagement {
repositories {
maven { url 'custom-repo' }
gradlePluginPortal()
}
}
在 build.gradle 中应用插件
plugins {
id "ezy.example.gradleplugin" version "1.0.0"
}
自定义插件(Custom Plugin)
自定义插件可以可以放在以下几个地方:
- 可以直接写在 build.gradle 中,但此插件不能被其它构建引用。
- 在单独的文件中实现插件,放在buildSrc项目中(buildSrc/src/main/groovy/)。
运行 Gradle 时,如果存在 buildSrc 目录,不需要额外的指令,其中的代码就会被编译测试并添加到构建脚本的 classpath 中,同一个工程中的所有构建文件中都可以引用。 - 在单独的工程中自定义插件,上传到远程仓库。通过添加依赖,引用这个插件。
简单的例子
以下代码是一个简单的自定义插件示例。
在应用插件后会创建一个任务(hello),并且可通过greeting.message
传入参数,在命令行中输入gradle hello
执行
build.gradle
apply plugin: SimplePlugin
// 其它一些配置
// ...
greeting {
message = "hello, hahahahahahha!"
}
class GreetingPluginExtension {
String message = 'Hello from GreetingPlugin'
}
class GreetingPlugin implements Plugin<Project> {
void apply(Project project) {
println "===>>> GreetingPlugin"
project.extensions.create('greeting', GreetingPluginExtension)
project.task('hello') {
doLast {
println "===>>> task hello : ${extension.message}"
}
}
}
}
使用 java-gradle-plugin 自定义插件
如果希望自己发布到自定义仓库中的插件也能使用plugins DSL引用,需要用到插件 java-gradle-plugin
- 它会为插件在
META-INF
目录生成插件描述 - 它会为每个插件生成一个Plugin Marker Artifact
Demo(https://docs.gradle.org/current/samples/sample_gradle_plugin.html)
plugins {
id "java-gradle-plugin"
}
// ...
gradlePlugin {
plugins {
greeting {
id = 'com.example.plugin.greeting'
implementationClass = 'com.example.plugin.GreetingPlugin'
}
}
}