建置腳本
每個 Gradle 建置都包含一個或多個專案;一個根專案和子專案。
專案通常對應於需要建置的軟體元件,例如函式庫或應用程式。它可能代表一個函式庫 JAR、一個 Web 應用程式,或是一個從其他專案產生的 JAR 組裝而成的發佈 ZIP。
另一方面,它可能代表要完成的事項,例如將您的應用程式部署到預備或生產環境。
Gradle 腳本以 Groovy DSL 或 Kotlin DSL(領域特定語言)編寫。
建置腳本配置專案,並與 Project
類型的物件相關聯。

當建置腳本執行時,它會配置 Project
。
建置腳本可以是 Groovy 中的 *.gradle
檔案,或是 Kotlin 中的 *.gradle.kts
檔案。
建置腳本配置 Project 物件及其子物件。 |
Project
物件
Project
物件是 Gradle API 的一部分
建置腳本中的許多頂層屬性和區塊都是 Project API 的一部分。
例如,以下建置腳本使用 Project.name 屬性來印出專案的名稱
println(name)
println(project.name)
println name
println project.name
$ gradle -q check project-api project-api
println
語句都會印出相同的屬性。
第一個語句使用對 Project
物件的 name
屬性的頂層參考。第二個語句使用任何建置腳本都可用的 project
屬性,該屬性會傳回相關聯的 Project
物件。
標準專案屬性
Project
物件在您的建置腳本中公開一組標準屬性。
下表列出了一些常用的屬性
名稱 | 類型 | 描述 |
---|---|---|
|
|
專案目錄的名稱。 |
|
|
專案的完整名稱。 |
|
|
專案的描述。 |
|
|
傳回專案的依賴處理器。 |
|
|
傳回專案的儲存庫處理器。 |
|
|
提供對專案幾個重要位置的存取權。 |
|
|
此專案的群組。 |
|
|
此專案的版本。 |
下表列出了一些常用的方法
名稱 | 描述 |
---|---|
|
將檔案路徑解析為 URI,相對於此專案的專案目錄。 |
|
使用給定的名稱建立一個 Task,並將其新增到此專案。 |
建置腳本結構
建置腳本由 { … }
組成,這是 Groovy 和 Kotlin 中的特殊物件。此物件在 Kotlin 中稱為lambda,在 Groovy 中稱為closure。
簡而言之,plugins{ }
區塊是一個方法調用,其中 Kotlin lambda 物件或 Groovy closure 物件作為引數傳遞。它是以下簡寫形式
plugins(function() {
id("plugin")
})
區塊會對應到 Gradle API 方法。
函數內部的程式碼會針對一個名為 receiver 的 this
物件(在 Kotlin lambda 中)和一個名為 delegate 的 this
物件(在 Groovy closure 中)執行。Gradle 決定正確的 this
物件,並調用正確的對應方法。方法調用 id("plugin")
物件的 this
類型為 PluginDependenciesSpec
。
建置腳本基本上是由建立在 DSL 之上的 Gradle API 調用組成。Gradle 會逐行、由上而下執行腳本。
讓我們看看一個範例並將其分解
plugins { (1)
id("application")
}
repositories { (2)
mavenCentral()
}
dependencies { (3)
testImplementation("org.junit.jupiter:junit-jupiter-engine:5.9.3")
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
implementation("com.google.guava:guava:32.1.1-jre")
}
application { (4)
mainClass = "com.example.Main"
}
tasks.named<Test>("test") { (5)
useJUnitPlatform()
}
tasks.named<Javadoc>("javadoc").configure {
exclude("app/Internal*.java")
exclude("app/internal/*")
}
tasks.register<Zip>("zip-reports") {
from("Reports/")
include("*")
archiveFileName.set("Reports.zip")
destinationDirectory.set(file("/dir"))
}
plugins { (1)
id 'application'
}
repositories { (2)
mavenCentral()
}
dependencies { (3)
testImplementation 'org.junit.jupiter:junit-jupiter-engine:5.9.3'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
implementation 'com.google.guava:guava:32.1.1-jre'
}
application { (4)
mainClass = 'com.example.Main'
}
tasks.named('test', Test) { (5)
useJUnitPlatform()
}
tasks.named('javadoc', Javadoc).configure {
exclude 'app/Internal*.java'
exclude 'app/internal/*'
}
tasks.register('zip-reports', Zip) {
from 'Reports/'
include '*'
archiveFileName = 'Reports.zip'
destinationDirectory = file('/dir')
}
1 | 將外掛套用至建置。 |
2 | 定義可以找到依賴關係的位置。 |
3 | 新增依賴關係。 |
4 | 設定屬性。 |
5 | 註冊和配置任務。 |
1. 將外掛套用至建置
外掛用於擴展 Gradle。它們也用於模組化和重複使用專案配置。
可以使用 PluginDependenciesSpec
plugins 腳本區塊套用外掛。
plugins 區塊是首選方法
plugins { (1)
id("application")
}
plugins { (1)
id 'application'
}
在範例中,已套用 Gradle 內含的 application
外掛,將我們的專案描述為 Java 應用程式。
2. 定義可以找到依賴關係的位置
專案通常有許多工作所需的依賴關係。依賴關係包括外掛、函式庫或組件,Gradle 必須下載這些依賴關係才能成功建置。
建置腳本讓 Gradle 知道在哪裡尋找依賴關係的二進制檔案。可以提供多個位置
repositories { (2)
mavenCentral()
}
repositories { (2)
mavenCentral()
}
在範例中,guava
函式庫和 JetBrains Kotlin 外掛 (org.jetbrains.kotlin.jvm
) 將從 Maven Central Repository 下載。
3. 新增依賴關係
專案通常有許多工作所需的依賴關係。這些依賴關係通常是預編譯類別的函式庫,這些類別會匯入專案的原始碼中。
依賴關係透過配置進行管理,並從儲存庫中檢索。
使用 Project.getDependencies()
方法傳回的 DependencyHandler
來管理依賴關係。使用 Project.getRepositories()
方法傳回的 RepositoryHandler
來管理儲存庫。
dependencies { (3)
testImplementation("org.junit.jupiter:junit-jupiter-engine:5.9.3")
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
implementation("com.google.guava:guava:32.1.1-jre")
}
dependencies { (3)
testImplementation 'org.junit.jupiter:junit-jupiter-engine:5.9.3'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
implementation 'com.google.guava:guava:32.1.1-jre'
}
在範例中,應用程式程式碼使用 Google 的 guava
函式庫。Guava 提供用於集合、快取、原始類型支援、並行、通用註解、字串處理、I/O 和驗證的實用方法。
4. 設定屬性
外掛可以使用擴展將屬性和方法新增至專案。
Project
物件具有相關聯的 ExtensionContainer
物件,其中包含已套用至專案的外掛的所有設定和屬性。
在範例中,application
外掛新增了一個 application
屬性,用於詳細說明我們 Java 應用程式的主要類別
application { (4)
mainClass = "com.example.Main"
}
application { (4)
mainClass = 'com.example.Main'
}
5. 註冊和配置任務
任務執行一些基本的工作,例如編譯類別、執行單元測試或壓縮 WAR 檔案。
雖然任務通常在外掛中定義,但您可能需要在建置腳本中註冊或配置任務。
註冊任務會將任務新增至您的專案。
您可以使用 TaskContainer.register(java.lang.String)
方法在專案中註冊任務
tasks.register<Zip>("zip-reports") {
from("Reports/")
include("*")
archiveFileName.set("Reports.zip")
destinationDirectory.set(file("/dir"))
}
tasks.register('zip-reports', Zip) {
from 'Reports/'
include '*'
archiveFileName = 'Reports.zip'
destinationDirectory = file('/dir')
}
您可能已經看過 TaskContainer.create(java.lang.String)
方法的用法,應避免使用此方法。
tasks.create<Zip>("zip-reports") { }
register() 啟用了任務配置避免,因此優先於 create() 。 |
您可以使用 TaskCollection.named(java.lang.String)
方法找到要配置的任務
tasks.named<Test>("test") { (5)
useJUnitPlatform()
}
tasks.named('test', Test) { (5)
useJUnitPlatform()
}
以下範例配置 Javadoc
任務,以自動從 Java 程式碼產生 HTML 文件
tasks.named<Javadoc>("javadoc").configure {
exclude("app/Internal*.java")
exclude("app/internal/*")
}
tasks.named('javadoc', Javadoc).configure {
exclude 'app/Internal*.java'
exclude 'app/internal/*'
}
建置腳本編寫
建置腳本由零個或多個語句和腳本區塊組成
println(project.layout.projectDirectory);
語句可以包括方法調用、屬性賦值和本機變數定義
version = '1.0.0.GA'
腳本區塊是一個方法調用,它將 closure/lambda 作為參數
configurations {
}
closure/lambda 在執行時配置某些委派物件
repositories {
google()
}
建置腳本也是 Groovy 或 Kotlin 腳本
tasks.register("upper") {
doLast {
val someString = "mY_nAmE"
println("Original: $someString")
println("Upper case: ${someString.toUpperCase()}")
}
}
tasks.register('upper') {
doLast {
String someString = 'mY_nAmE'
println "Original: $someString"
println "Upper case: ${someString.toUpperCase()}"
}
}
$ gradle -q upper Original: mY_nAmE Upper case: MY_NAME
它可以包含 Groovy 或 Kotlin 腳本中允許的元素,例如方法定義和類別定義
tasks.register("count") {
doLast {
repeat(4) { print("$it ") }
}
}
tasks.register('count') {
doLast {
4.times { print "$it " }
}
}
$ gradle -q count 0 1 2 3
彈性任務註冊
使用 Groovy 或 Kotlin 語言的功能,您可以在迴圈中註冊多個任務
repeat(4) { counter ->
tasks.register("task$counter") {
doLast {
println("I'm task number $counter")
}
}
}
4.times { counter ->
tasks.register("task$counter") {
doLast {
println "I'm task number $counter"
}
}
}
$ gradle -q task1 I'm task number 1
Gradle 類型
在 Gradle 中,類型、屬性和提供器是管理和配置建置邏輯的基礎
-
類型:Gradle 定義類型(例如
Task
、Configuration
、File
等)來表示建置組件。您可以擴展這些類型以建立自訂任務或網域物件。 -
屬性:Gradle 屬性(例如
Property<T>
、ListProperty<T>
、SetProperty<T>
)用於建置配置。它們允許延遲評估,這表示它們的值僅在需要時才計算,從而增強彈性和效能。 -
提供器:
Provider<T>
表示延遲計算或檢索的值。提供器通常與屬性一起使用,以將值計算延遲到必要時。這對於將動態、執行階段值整合到您的建置中特別有用。
您可以在了解 Gradle 類型中了解更多資訊。
宣告變數
建置腳本可以宣告兩種變數:本機變數和額外屬性。
本機變數
使用 val
關鍵字宣告本機變數。本機變數僅在宣告它們的範圍內可見。它們是底層 Kotlin 語言的功能。
使用 def
關鍵字宣告本機變數。本機變數僅在宣告它們的範圍內可見。它們是底層 Groovy 語言的功能。
val dest = "dest"
tasks.register<Copy>("copy") {
from("source")
into(dest)
}
def dest = 'dest'
tasks.register('copy', Copy) {
from 'source'
into dest
}
額外屬性
Gradle 的增強物件,包括專案、任務和原始碼集,可以保留使用者定義的屬性。
透過擁有物件的 extra
屬性新增、讀取和設定額外屬性。或者,您可以使用 Kotlin 委派屬性透過 by extra
存取額外屬性。
透過擁有物件的 ext
屬性新增、讀取和設定額外屬性。或者,您可以使用 ext
區塊同時新增多個屬性。
plugins {
id("java-library")
}
val springVersion by extra("3.1.0.RELEASE")
val emailNotification by extra { "build@master.org" }
sourceSets.all { extra["purpose"] = null }
sourceSets {
main {
extra["purpose"] = "production"
}
test {
extra["purpose"] = "test"
}
create("plugin") {
extra["purpose"] = "production"
}
}
tasks.register("printProperties") {
val springVersion = springVersion
val emailNotification = emailNotification
val productionSourceSets = provider {
sourceSets.matching { it.extra["purpose"] == "production" }.map { it.name }
}
doLast {
println(springVersion)
println(emailNotification)
productionSourceSets.get().forEach { println(it) }
}
}
plugins {
id 'java-library'
}
ext {
springVersion = "3.1.0.RELEASE"
emailNotification = "build@master.org"
}
sourceSets.all { ext.purpose = null }
sourceSets {
main {
purpose = "production"
}
test {
purpose = "test"
}
plugin {
purpose = "production"
}
}
tasks.register('printProperties') {
def springVersion = springVersion
def emailNotification = emailNotification
def productionSourceSets = provider {
sourceSets.matching { it.purpose == "production" }.collect { it.name }
}
doLast {
println springVersion
println emailNotification
productionSourceSets.get().each { println it }
}
}
$ gradle -q printProperties 3.1.0.RELEASE build@master.org main plugin
此範例透過 by extra
將兩個額外屬性新增至 project
物件。此外,此範例透過將 extra["purpose"]
設定為 null
,將名為 purpose
的屬性新增至每個原始碼集。新增後,您可以透過 extra
讀取和設定這些屬性。
此範例透過 ext
區塊將兩個額外屬性新增至 project
物件。此外,此範例透過將 ext.purpose
設定為 null
,將名為 purpose
的屬性新增至每個原始碼集。新增後,您可以像預定義的屬性一樣讀取和設定所有這些屬性。
Gradle 需要特殊語法來新增屬性,以便它可以快速失敗。例如,這允許 Gradle 在腳本嘗試設定不存在的屬性時識別出來。您可以在可以存取其擁有物件的任何位置存取額外屬性。這使額外屬性比本機變數具有更廣泛的範圍。子專案可以存取其父專案上的額外屬性。
有關額外屬性的更多資訊,請參閱 API 文件中的 ExtraPropertiesExtension。
配置任意物件
範例 greet()
任務顯示了任意物件配置的範例
class UserInfo(
var name: String? = null,
var email: String? = null
)
tasks.register("greet") {
val user = UserInfo().apply {
name = "Isaac Newton"
email = "isaac@newton.me"
}
doLast {
println(user.name)
println(user.email)
}
}
class UserInfo {
String name
String email
}
tasks.register('greet') {
def user = configure(new UserInfo()) {
name = "Isaac Newton"
email = "isaac@newton.me"
}
doLast {
println user.name
println user.email
}
}
$ gradle -q greet Isaac Newton isaac@newton.me
Closure 委派
每個 closure 都有一個 delegate
物件。Groovy 使用此委派來查找變數和方法參考,以查找非本機變數和 closure 參數。Gradle 將其用於配置 closure,其中 delegate
物件指的是正在配置的物件。
dependencies {
assert delegate == project.dependencies
testImplementation('junit:junit:4.13')
delegate.testImplementation('junit:junit:4.13')
}
預設匯入
為了使建置腳本更簡潔,Gradle 會自動將一組 import 語句新增至腳本。
因此,您可以寫入 throw new StopExecutionException()
而不是寫入 throw new org.gradle.api.tasks.StopExecutionException()
。
Gradle 隱含地將以下匯入新增至每個腳本
import org.gradle.*
import org.gradle.api.*
import org.gradle.api.artifacts.*
import org.gradle.api.artifacts.capability.*
import org.gradle.api.artifacts.component.*
import org.gradle.api.artifacts.dsl.*
import org.gradle.api.artifacts.ivy.*
import org.gradle.api.artifacts.maven.*
import org.gradle.api.artifacts.query.*
import org.gradle.api.artifacts.repositories.*
import org.gradle.api.artifacts.result.*
import org.gradle.api.artifacts.transform.*
import org.gradle.api.artifacts.type.*
import org.gradle.api.artifacts.verification.*
import org.gradle.api.attributes.*
import org.gradle.api.attributes.java.*
import org.gradle.api.attributes.plugin.*
import org.gradle.api.cache.*
import org.gradle.api.capabilities.*
import org.gradle.api.component.*
import org.gradle.api.configuration.*
import org.gradle.api.credentials.*
import org.gradle.api.distribution.*
import org.gradle.api.distribution.plugins.*
import org.gradle.api.execution.*
import org.gradle.api.file.*
import org.gradle.api.flow.*
import org.gradle.api.initialization.*
import org.gradle.api.initialization.definition.*
import org.gradle.api.initialization.dsl.*
import org.gradle.api.initialization.resolve.*
import org.gradle.api.invocation.*
import org.gradle.api.java.archives.*
import org.gradle.api.jvm.*
import org.gradle.api.launcher.cli.*
import org.gradle.api.logging.*
import org.gradle.api.logging.configuration.*
import org.gradle.api.model.*
import org.gradle.api.plugins.*
import org.gradle.api.plugins.antlr.*
import org.gradle.api.plugins.catalog.*
import org.gradle.api.plugins.jvm.*
import org.gradle.api.plugins.quality.*
import org.gradle.api.plugins.scala.*
import org.gradle.api.problems.*
import org.gradle.api.project.*
import org.gradle.api.provider.*
import org.gradle.api.publish.*
import org.gradle.api.publish.ivy.*
import org.gradle.api.publish.ivy.plugins.*
import org.gradle.api.publish.ivy.tasks.*
import org.gradle.api.publish.maven.*
import org.gradle.api.publish.maven.plugins.*
import org.gradle.api.publish.maven.tasks.*
import org.gradle.api.publish.plugins.*
import org.gradle.api.publish.tasks.*
import org.gradle.api.reflect.*
import org.gradle.api.reporting.*
import org.gradle.api.reporting.components.*
import org.gradle.api.reporting.dependencies.*
import org.gradle.api.reporting.dependents.*
import org.gradle.api.reporting.model.*
import org.gradle.api.reporting.plugins.*
import org.gradle.api.resources.*
import org.gradle.api.services.*
import org.gradle.api.specs.*
import org.gradle.api.tasks.*
import org.gradle.api.tasks.ant.*
import org.gradle.api.tasks.application.*
import org.gradle.api.tasks.bundling.*
import org.gradle.api.tasks.compile.*
import org.gradle.api.tasks.diagnostics.*
import org.gradle.api.tasks.diagnostics.artifact.transforms.*
import org.gradle.api.tasks.diagnostics.configurations.*
import org.gradle.api.tasks.incremental.*
import org.gradle.api.tasks.javadoc.*
import org.gradle.api.tasks.options.*
import org.gradle.api.tasks.scala.*
import org.gradle.api.tasks.testing.*
import org.gradle.api.tasks.testing.junit.*
import org.gradle.api.tasks.testing.junitplatform.*
import org.gradle.api.tasks.testing.testng.*
import org.gradle.api.tasks.util.*
import org.gradle.api.tasks.wrapper.*
import org.gradle.api.toolchain.management.*
import org.gradle.authentication.*
import org.gradle.authentication.aws.*
import org.gradle.authentication.http.*
import org.gradle.build.event.*
import org.gradle.buildconfiguration.tasks.*
import org.gradle.buildinit.*
import org.gradle.buildinit.plugins.*
import org.gradle.buildinit.specs.*
import org.gradle.buildinit.tasks.*
import org.gradle.caching.*
import org.gradle.caching.configuration.*
import org.gradle.caching.http.*
import org.gradle.caching.local.*
import org.gradle.concurrent.*
import org.gradle.external.javadoc.*
import org.gradle.ide.visualstudio.*
import org.gradle.ide.visualstudio.plugins.*
import org.gradle.ide.visualstudio.tasks.*
import org.gradle.ide.xcode.*
import org.gradle.ide.xcode.plugins.*
import org.gradle.ide.xcode.tasks.*
import org.gradle.ivy.*
import org.gradle.jvm.*
import org.gradle.jvm.application.scripts.*
import org.gradle.jvm.application.tasks.*
import org.gradle.jvm.tasks.*
import org.gradle.jvm.toolchain.*
import org.gradle.language.*
import org.gradle.language.assembler.*
import org.gradle.language.assembler.plugins.*
import org.gradle.language.assembler.tasks.*
import org.gradle.language.base.*
import org.gradle.language.base.artifact.*
import org.gradle.language.base.compile.*
import org.gradle.language.base.plugins.*
import org.gradle.language.base.sources.*
import org.gradle.language.c.*
import org.gradle.language.c.plugins.*
import org.gradle.language.c.tasks.*
import org.gradle.language.cpp.*
import org.gradle.language.cpp.plugins.*
import org.gradle.language.cpp.tasks.*
import org.gradle.language.java.artifact.*
import org.gradle.language.jvm.tasks.*
import org.gradle.language.nativeplatform.*
import org.gradle.language.nativeplatform.tasks.*
import org.gradle.language.objectivec.*
import org.gradle.language.objectivec.plugins.*
import org.gradle.language.objectivec.tasks.*
import org.gradle.language.objectivecpp.*
import org.gradle.language.objectivecpp.plugins.*
import org.gradle.language.objectivecpp.tasks.*
import org.gradle.language.plugins.*
import org.gradle.language.rc.*
import org.gradle.language.rc.plugins.*
import org.gradle.language.rc.tasks.*
import org.gradle.language.scala.tasks.*
import org.gradle.language.swift.*
import org.gradle.language.swift.plugins.*
import org.gradle.language.swift.tasks.*
import org.gradle.maven.*
import org.gradle.model.*
import org.gradle.nativeplatform.*
import org.gradle.nativeplatform.platform.*
import org.gradle.nativeplatform.plugins.*
import org.gradle.nativeplatform.tasks.*
import org.gradle.nativeplatform.test.*
import org.gradle.nativeplatform.test.cpp.*
import org.gradle.nativeplatform.test.cpp.plugins.*
import org.gradle.nativeplatform.test.cunit.*
import org.gradle.nativeplatform.test.cunit.plugins.*
import org.gradle.nativeplatform.test.cunit.tasks.*
import org.gradle.nativeplatform.test.googletest.*
import org.gradle.nativeplatform.test.googletest.plugins.*
import org.gradle.nativeplatform.test.plugins.*
import org.gradle.nativeplatform.test.tasks.*
import org.gradle.nativeplatform.test.xctest.*
import org.gradle.nativeplatform.test.xctest.plugins.*
import org.gradle.nativeplatform.test.xctest.tasks.*
import org.gradle.nativeplatform.toolchain.*
import org.gradle.nativeplatform.toolchain.plugins.*
import org.gradle.normalization.*
import org.gradle.platform.*
import org.gradle.platform.base.*
import org.gradle.platform.base.binary.*
import org.gradle.platform.base.component.*
import org.gradle.platform.base.plugins.*
import org.gradle.plugin.devel.*
import org.gradle.plugin.devel.plugins.*
import org.gradle.plugin.devel.tasks.*
import org.gradle.plugin.management.*
import org.gradle.plugin.use.*
import org.gradle.plugins.ear.*
import org.gradle.plugins.ear.descriptor.*
import org.gradle.plugins.ide.*
import org.gradle.plugins.ide.api.*
import org.gradle.plugins.ide.eclipse.*
import org.gradle.plugins.ide.idea.*
import org.gradle.plugins.signing.*
import org.gradle.plugins.signing.signatory.*
import org.gradle.plugins.signing.signatory.pgp.*
import org.gradle.plugins.signing.type.*
import org.gradle.plugins.signing.type.pgp.*
import org.gradle.process.*
import org.gradle.swiftpm.*
import org.gradle.swiftpm.plugins.*
import org.gradle.swiftpm.tasks.*
import org.gradle.testing.base.*
import org.gradle.testing.base.plugins.*
import org.gradle.testing.jacoco.plugins.*
import org.gradle.testing.jacoco.tasks.*
import org.gradle.testing.jacoco.tasks.rules.*
import org.gradle.testkit.runner.*
import org.gradle.util.*
import org.gradle.vcs.*
import org.gradle.vcs.git.*
import org.gradle.work.*
import org.gradle.workers.*
下一步: 了解如何使用任務 >>