在 Gradle 中兩個頂級概念:project(項目)和 task 任務)
所有 Gradle 都有一個或多個 project 構成。project 的展現取決于 Gradle 所做的工作。舉例。 project 可以是一個 JAR 庫 或者是 web 應用。它可以是由項目生產 JAR 組成發布的 ZIP。一個 project 不一定 代表一個東西要構建。它可能是一件要做的事,如將應用程序部署到工作臺 或生產環境。如果這看起來有點模糊,現在不要擔心。Gradle 基于約定的構建支持增加一個 更具體的定義的 project。
每個項目都是由一個或多個 task。一個 task 代表了一個構建生成的原子的作品。這可能是編寫一些類,創建一個 JAR ,生成 Javadoc,或發布一些庫。
現在,我們將看看在構建一個 project 時定義一些簡單的 task 。后面的章節將介紹多個 project 和更多的 task 。
## [](https://github.com/waylau/Gradle-2-User-Guide/blob/master/Chapter%2006.%20Build%20Script%20Basics%20%E6%9E%84%E5%BB%BA%E8%84%9A%E6%9C%AC%E7%9A%84%E5%9F%BA%E7%A1%80%E8%AF%86.md#62-hello-world)6.2\. Hello world
運行 Gradle 是使用 gradle 命令行。命令行會尋找項目的根目錄下 build.gradle 的文件(有關命令行,詳見?[Appendix D. Gradle Command Line 命令行](https://github.com/waylau/Gradle-2-User-Guide/blob/master/Appendix%20D.%20Gradle%20Command%20Line%20%E5%91%BD%E4%BB%A4%E8%A1%8C.md)),這個就是構建的腳本,或者嚴格說是構建的配置腳本。他定義了project(項目)和 task 任務)。
嘗試輸出,創建一個?`build.gradle`?命名的文件:
Example 6.1\. Your first build script
build.gradle
~~~
task hello {
doLast {
println 'Hello world!'
}
}
~~~
命令行切換到包含 build.gradle 文件的目錄,執行?`gradle -q hello`
[](https://box.kancloud.cn/2015-08-19_55d47fe533d70.jpg)
Example 6.2\. Execution of a build script
輸出為:
~~~
> gradle -q hello
Hello world!
~~~
[](https://box.kancloud.cn/2015-08-19_55d47fecd4ae8.jpg)
這個腳本定義了一個 名字是`hello`?的 task,并且添加了動作。當運行?`gradle hello`?,Gradle 執行這個?`hello`?task,接著執行里面的動作。這里的動作只是簡單的包含了一些可以執行的 Groovy 代碼。
看上去很像 Ant ,不錯,Gradle task 是相當于 Ant 的 target,但是你將看到,他們更強大。我們使用了跟 Ant 不同的術語,因為 task 比 target 更富表現力。
不幸的是,這一術語與 Ant 有沖突,Ant 調用它的命令行,如 javac 或copy 稱之為 task 。所以當我們談論的 task ,默認說的是 Gradle task ,這是相當 Ant 的 target。如果我們談論的 Ant 的 task (Ant 命令),我們明確地說的 Ant task。
### [](https://github.com/waylau/Gradle-2-User-Guide/blob/master/Chapter%2006.%20Build%20Script%20Basics%20%E6%9E%84%E5%BB%BA%E8%84%9A%E6%9C%AC%E7%9A%84%E5%9F%BA%E7%A1%80%E8%AF%86.md#命令行加中--q-的作用)命令行加中?`-q`?的作用
q 是 quiet 的簡寫,意思是要安靜、干凈的輸出。如果不加?`-q`?則會輸出日志。詳見[Chapter 18\. Logging 日志](https://github.com/waylau/Gradle-2-User-Guide/blob/master/Chapter%2018.%20Logging%20%E6%97%A5%E5%BF%97.md).下面是對比
[](https://box.kancloud.cn/2015-08-19_55d47feecd975.jpg)
## [](https://github.com/waylau/Gradle-2-User-Guide/blob/master/Chapter%2006.%20Build%20Script%20Basics%20%E6%9E%84%E5%BB%BA%E8%84%9A%E6%9C%AC%E7%9A%84%E5%9F%BA%E7%A1%80%E8%AF%86.md#63-a-shortcut-task-definition-快捷-task-定義)6.3\. A shortcut task definition 快捷 task 定義
定義 task 可以使用快捷方式,這樣更簡明。
Example 6.3\. A task definition shortcut
build.gradle
~~~
task hello << {
println 'Hello world!'
}
~~~
再次執行,得到相同的輸出。在下面的文章中,我們都會采用這種定義方式。
[](https://box.kancloud.cn/2015-08-19_55d47fefc56d3.jpg)
## [](https://github.com/waylau/Gradle-2-User-Guide/blob/master/Chapter%2006.%20Build%20Script%20Basics%20%E6%9E%84%E5%BB%BA%E8%84%9A%E6%9C%AC%E7%9A%84%E5%9F%BA%E7%A1%80%E8%AF%86.md#64-build-scripts-are-code-構建的腳本都是代碼)6.4\. Build scripts are code 構建的腳本都是代碼
工具的構建腳本給你完整的 Groovy 的功能。作為開胃菜,看看這個:
Example 6.4\. Using Groovy in Gradle's tasks
build.gradle
~~~
task upper << {
String someString = 'mY_nAmE'
println "Original: " + someString
println "Upper case: " + someString.toUpperCase()
}
~~~
執行?`gradle -q upper`?輸出
~~~
> gradle -q upper
Original: mY_nAmE
Upper case: MY_NAME
~~~
[](https://box.kancloud.cn/2015-08-19_55d47ff094c15.jpg)
或者
Example 6.5\. Using Groovy in Gradle's tasks
build.gradle
~~~
task count << {
4.times { print "$it " }
}
~~~
執行?`gradle -q count`?輸出
~~~
> gradle -q count
0 1 2 3
~~~
[](https://box.kancloud.cn/2015-08-19_55d47ff27cc55.jpg)
## [](https://github.com/waylau/Gradle-2-User-Guide/blob/master/Chapter%2006.%20Build%20Script%20Basics%20%E6%9E%84%E5%BB%BA%E8%84%9A%E6%9C%AC%E7%9A%84%E5%9F%BA%E7%A1%80%E8%AF%86.md#65-task-dependencies-依賴)6.5\. Task dependencies 依賴
可以聲明 task 與 其他 task 的依賴
Example 6.6\. Declaration of task that depends on other task
build.gradle
~~~
task hello << {
println 'Hello world!'
}
task intro(dependsOn: hello) << {
println "I'm Gradle"
}
~~~
執行?`gradle -q intro`?輸出
~~~
> gradle -q intro
Hello world!
I'm Gradle
~~~
[](https://box.kancloud.cn/2015-08-19_55d47ff345d81.jpg)
添加一個依賴,相應的 task 不需要存在
Example 6.7\. Lazy dependsOn - the other task does not exist (yet)
build.gradle
~~~
task taskX(dependsOn: 'taskY') << {
println 'taskX'
}
task taskY << {
println 'taskY'
}
~~~
執行?`gradle -q taskX`輸出
~~~
> gradle -q taskX
taskY
taskX
~~~
[](https://box.kancloud.cn/2015-08-19_55d47ff5c1ef6.jpg)
taskX 的依賴 taskY 是在 taskY 定義之前 聲明的。這個在多 project 構建時很重要。關于 task 的依賴詳見?[Chapter 15\. More about Tasks 更多關于任務](https://github.com/waylau/Gradle-2-User-Guide/blob/master/Chapter%2015.%20More%20about%20Tasks%20%E6%9B%B4%E5%A4%9A%E5%85%B3%E4%BA%8E%E4%BB%BB%E5%8A%A1.md)
請注意不要使用快捷符號,當引用的 task 還沒有定義的情況下。
## [](https://github.com/waylau/Gradle-2-User-Guide/blob/master/Chapter%2006.%20Build%20Script%20Basics%20%E6%9E%84%E5%BB%BA%E8%84%9A%E6%9C%AC%E7%9A%84%E5%9F%BA%E7%A1%80%E8%AF%86.md#66-dynamic-tasks-動態-task)6.6\. Dynamic tasks 動態 task
Groovy 的能力不僅僅是定義一個 task。例如,你也可以用它來動態創建的 task。
Example 6.8\. Dynamic creation of a task
build.gradle
~~~
4.times { counter ->
task "task$counter" << {
println "I'm task number $counter"
}
}
~~~
執行?`gradle -q task1`?輸出
~~~
> gradle -q task1
I'm task number 1
~~~
[](https://box.kancloud.cn/2015-08-19_55d47ff6ef423.jpg)
## [](https://github.com/waylau/Gradle-2-User-Guide/blob/master/Chapter%2006.%20Build%20Script%20Basics%20%E6%9E%84%E5%BB%BA%E8%84%9A%E6%9C%AC%E7%9A%84%E5%9F%BA%E7%A1%80%E8%AF%86.md#67-manipulating-existing-tasks-利用現有的任務)6.7\. Manipulating existing tasks 利用現有的任務
一旦 task 創建,他們可以通過一個 API 訪問。例如,在運行時您可以使用此動態添加依賴到 task 。Ant 不允許這樣的事情。
Example 6.9\. Accessing a task via API - adding a dependency
build.gradle
~~~
4.times { counter ->
task "task$counter" << {
println "I'm task number $counter"
}
}
task0.dependsOn task2, task3
~~~
執行?`gradle -q task0`?輸出
~~~
> gradle -q task0
I'm task number 2
I'm task number 3
I'm task number 0
~~~
或者 可以添加行為到一個已經存在 task 中
Example 6.10\. Accessing a task via API - adding behaviour
build.gradle
~~~
task hello << {
println 'Hello Earth'
}
hello.doFirst {
println 'Hello Venus'
}
hello.doLast {
println 'Hello Mars'
}
hello << {
println 'Hello Jupiter'
}
~~~
執行?`gradle -q hello`?輸出
~~~
> gradle -q hello
Hello Venus
Hello Earth
Hello Mars
Hello Jupiter
~~~
[](https://box.kancloud.cn/2015-08-19_55d47ff79d64b.jpg)
doFirst 和 doLast 可以多次執行調用。他們在開始或結束的 task 動作清單中添加動作。task 執行時,按動作列表的順序執行的動作。操作符?`<<`?僅僅是 doLast 的別名。
## [](https://github.com/waylau/Gradle-2-User-Guide/blob/master/Chapter%2006.%20Build%20Script%20Basics%20%E6%9E%84%E5%BB%BA%E8%84%9A%E6%9C%AC%E7%9A%84%E5%9F%BA%E7%A1%80%E8%AF%86.md#68-shortcut-notations-快捷符號)6.8\. Shortcut notations 快捷符號
在前面的示例中已經注意到,有一個方便的符號訪問現有的 task 。每個 task 可以作為構建腳本的一個屬性:
Example 6.11\. Accessing task as a property of the build script
build.gradle
~~~
task hello << {
println 'Hello world!'
}
hello.doLast {
println "Greetings from the $hello.name task."
}
~~~
執行?`gradle -q hello`輸出
~~~
> gradle -q hello
Hello world!
Greetings from the hello task.
~~~
[](https://box.kancloud.cn/2015-08-19_55d47ff81fe62.jpg)
這使得代碼可讀性增強,尤其是當使用的插件提供的 task ,如 compile task
## [](https://github.com/waylau/Gradle-2-User-Guide/blob/master/Chapter%2006.%20Build%20Script%20Basics%20%E6%9E%84%E5%BB%BA%E8%84%9A%E6%9C%AC%E7%9A%84%E5%9F%BA%E7%A1%80%E8%AF%86.md#69-extra-task-properties-額外-task-屬性)6.9\. Extra task properties 額外 task 屬性
可以添加自己屬性到 task ,添加?`myProperty`屬性,設置 、`ext.myProperty`?初始值,從這一點上,該屬性可以讀取和設置就像一個預定義的任務屬性。
Example 6.12\. Adding extra properties to a task
build.gradle
~~~
task myTask {
ext.myProperty = "myValue"
}
task printTaskProperties << {
println myTask.myProperty
}
~~~
執行?`gradle -q printTaskProperties`輸出
~~~
> gradle -q printTaskProperties
myValue
~~~
[](https://box.kancloud.cn/2015-08-19_55d47ff988ea1.jpg)
task 不對額外屬性做限制,更多詳見[Chapter 13\. Writing Build Scripts 編寫構建腳本](https://github.com/waylau/Gradle-2-User-Guide/blob/master/Chapter%2013.%20Writing%20Build%20Scripts%20%E7%BC%96%E5%86%99%E6%9E%84%E5%BB%BA%E8%84%9A%E6%9C%AC.md)?中 13.4.2 節 “Extra properties”.
## [](https://github.com/waylau/Gradle-2-User-Guide/blob/master/Chapter%2006.%20Build%20Script%20Basics%20%E6%9E%84%E5%BB%BA%E8%84%9A%E6%9C%AC%E7%9A%84%E5%9F%BA%E7%A1%80%E8%AF%86.md#610-using-ant-tasks-使用-ant-task)6.10\. Using Ant Tasks 使用 Ant task
Ant task 是 Gradle 一等公民。 Gradle 給 Ant task 提供了不錯的整合通過簡單依靠于 Gradle 。Groovy 被奇異的 AntBuilder 裝載。從 Gradle 使用 Ant task 比使用 build.xml 文件更方便和更強大。從下面的例子中,你可以學習如何執行 Ant task 和如何訪問 Ant 屬性:
Example 6.13\. Using AntBuilder to execute ant.loadfile target
build.gradle
~~~
task loadfile << {
def files = file('antLoadfileResources').listFiles().sort()
files.each { File file ->
if (file.isFile()) {
ant.loadfile(srcFile: file, property: file.name)
println " *** $file.name ***"
println "${ant.properties[file.name]}"
}
}
}
~~~
執行?`gradle -q loadfile`輸出
~~~
> gradle -q loadfile
*** agile.manifesto.txt ***
Individuals and interactions over processes and tools
Working software over comprehensive documentation
Customer collaboration over contract negotiation
Responding to change over following a plan
*** gradle.manifesto.txt ***
Make the impossible possible, make the possible easy and make the easy elegant.
(inspired by Moshe Feldenkrais)
~~~
[](https://box.kancloud.cn/2015-08-19_55d47ffa4a8b4.jpg)
更多關于 構建腳本中使用 Ant ,詳見?[Chapter 17\. Using Ant from Gradle 從 Gradle 使用 Ant](https://github.com/waylau/Gradle-2-User-Guide/blob/master/Chapter%2017.%20Using%20Ant%20from%20Gradle%20%E4%BB%8E%20Gradle%20%E4%BD%BF%E7%94%A8%20Ant.md)
## [](https://github.com/waylau/Gradle-2-User-Guide/blob/master/Chapter%2006.%20Build%20Script%20Basics%20%E6%9E%84%E5%BB%BA%E8%84%9A%E6%9C%AC%E7%9A%84%E5%9F%BA%E7%A1%80%E8%AF%86.md#611-using-methods-使用方法)6.11\. Using methods 使用方法
Gradle 延伸取決你如何組織的建造邏輯。上面的例子中的第一級別的組織你的構建邏輯,是提取方法。
Example 6.14\. Using methods to organize your build logic
build.gradle
~~~
task checksum << {
fileList('../antLoadfileResources').each {File file ->
ant.checksum(file: file, property: "cs_$file.name")
println "$file.name Checksum: ${ant.properties["cs_$file.name"]}"
}
}
task loadfile << {
fileList('../antLoadfileResources').each {File file ->
ant.loadfile(srcFile: file, property: file.name)
println "I'm fond of $file.name"
}
}
File[] fileList(String dir) {
file(dir).listFiles({file -> file.isFile() } as FileFilter).sort()
}
~~~
執行?`gradle -q loadfile`輸出
~~~
> gradle -q loadfile
I'm fond of agile.manifesto.txt
I'm fond of gradle.manifesto.txt
~~~
[](https://box.kancloud.cn/2015-08-19_55d47ffb1346f.jpg)
以后你會發現這樣的方法可以在多 project 構建的子 project 之間共享。如果你建立邏輯變得越來越復雜,Gradle 為您提供其他工具很方便的方式來組織它。我們有專門一章[Chapter 60\. Organizing Build Logic](https://github.com/waylau/Gradle-2-User-Guide/blob/master/Chapter%2060.%20Organizing%20Build%20Logic%20%E7%BB%84%E7%BB%87%E6%9E%84%E5%BB%BA%E9%80%BB%E8%BE%91.md)
## [](https://github.com/waylau/Gradle-2-User-Guide/blob/master/Chapter%2006.%20Build%20Script%20Basics%20%E6%9E%84%E5%BB%BA%E8%84%9A%E6%9C%AC%E7%9A%84%E5%9F%BA%E7%A1%80%E8%AF%86.md#612-default-tasks-默認-task)6.12\. Default tasks 默認 task
Gradle 允許你定義一個或多個默認 task 給你的構建
Example 6.15\. Defining a default tasks
build.gradle
~~~
defaultTasks 'clean', 'run'
task clean << {
println 'Default Cleaning!'
}
task run << {
println 'Default Running!'
}
task other << {
println "I'm not a default task!"
}
~~~
執行?`gradle -q`?輸出
~~~
> gradle -q
Default Cleaning!
Default Running!
~~~
[](https://box.kancloud.cn/2015-08-19_55d47ffd34ced.jpg)
這個等于執行了?`gradle clean run`?,在多 project 中構建所有的子 project 都可以有自己具體的默認 task 。如果 子 project 沒有明確的默認 task,則執行父 project 的默認 task(如果定義的話)
## [](https://github.com/waylau/Gradle-2-User-Guide/blob/master/Chapter%2006.%20Build%20Script%20Basics%20%E6%9E%84%E5%BB%BA%E8%84%9A%E6%9C%AC%E7%9A%84%E5%9F%BA%E7%A1%80%E8%AF%86.md#613-configure-by-dag-通過-dag-配置)6.13\. Configure by DAG 通過 DAG 配置
以后會詳細描述(見[Chapter 56\. The Build Lifecycle 構建生命周期](https://github.com/waylau/Gradle-2-User-Guide/blob/master/Chapter%2056.%20The%20Build%20Lifecycle%20%E6%9E%84%E5%BB%BA%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F.md)?),Gradle 有配置階段和執行階段。配置階段后,Gradle 知道所有的 task 應該執行。Gradle 提供給你一個鉤子來利用這些信息。這個用例將檢查發布 的 task 是否是要執行的 task。基于此,你可以賦予不同的值到一些變量。
在下面的例子中,在不同 version 變量中的 distribution 和 release task 執行結果不同。
Example 6.16\. Different outcomes of build depending on chosen tasks
build.gradle
~~~
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'
}
}
~~~
執行?`gradle -q distribution`?輸出
~~~
> gradle -q distribution
We build the zip with version=1.0-SNAPSHOT
~~~
執行?`gradle -q release`?輸出
~~~
> gradle -q release
We build the zip with version=1.0
We release now
~~~
[](https://box.kancloud.cn/2015-08-19_55d47ffeaad04.jpg)
`whenReady`影響了 release task 在 release task 被執行之前。同樣適用于 release task 不是 主 task 的情況(比如,task 被 gradle 命令通過了)
## [](https://github.com/waylau/Gradle-2-User-Guide/blob/master/Chapter%2006.%20Build%20Script%20Basics%20%E6%9E%84%E5%BB%BA%E8%84%9A%E6%9C%AC%E7%9A%84%E5%9F%BA%E7%A1%80%E8%AF%86.md#614-where-to-next-下一步工作)6.14\. Where to next? 下一步工作
本章,我們大概瀏覽了下 task ,但這不是 task 的全部,可以詳見[Chapter 15\. More about Tasks 更多關于任務](https://github.com/waylau/Gradle-2-User-Guide/blob/master/Chapter%2015.%20More%20about%20Tasks%20%E6%9B%B4%E5%A4%9A%E5%85%B3%E4%BA%8E%E4%BB%BB%E5%8A%A1.md)
另外,繼續教程?[Chapter 7\. Java Quickstart 快速開始 Java](https://github.com/waylau/Gradle-2-User-Guide/blob/master/Chapter%2007.%20Java%20Quickstart%20%E5%BF%AB%E9%80%9F%E5%BC%80%E5%A7%8B%20Java.md)?和?[Chapter 8\. Dependency Management Basics 依賴管理的基礎知識.md](https://github.com/waylau/Gradle-2-User-Guide/blob/master/Chapter%2008.%20Dependency%20Management%20Basics%20%E4%BE%9D%E8%B5%96%E7%AE%A1%E7%90%86%E7%9A%84%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86.md)
- 關于
- 第1章 Introduction 介紹
- 第2章 Overview 總覽
- 第3章 Tutorials 教程
- 第4章 Installing Gradle 安裝
- 第5章 Troubleshooting 問題解決
- 第6章 Build Script Basics 構建腳本的基礎識
- 第7章 Java Quickstart 快速開始 Java
- 第8章 Dependency Management Basics 依賴管理的基礎知識
- 第9章 Groovy Quickstart 快速開始 Groovy
- 第10章 Web Application Quickstart 快速開始 Web 應用
- 第11章 Using the Gradle Command-Line 使用 Gradle 命令行
- 第12章 Using the Gradle Graphical User Interface 使用 Gradle 圖形化用戶界面
- 第13章 Writing Build Scripts 編寫構建腳本
- 第14章 Tutorial - 'This and That' 教程-這個那個
- 第15章 More about Tasks 更多關于任務
- 第16章 Working With Files 跟文件工作
- 第17章 Using Ant from Gradle 從 Gradle 使用 Ant
- 第18章 Logging 日志.md
- 第19章 The Gradle Daemon 守護進程
- 第20章 The Build Environment 構建環境
- 第21章 Gradle Plugins 插件
- 第22章 Standard Gradle plugins 標準 Gradle 插件
- 附錄E Existing IDE Support and how to cope without it 支持的 IDE 以及如何應對沒有它