构建脚本
每个 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 方法。
函数内部的代码针对一个 this
对象执行,该对象在 Kotlin lambda 中称为 receiver,在 Groovy closure 中称为 delegate。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 { (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
属性添加、读取和设置额外属性。或者,您可以使用 by extra
通过 Kotlin 委托属性访问额外属性。
通过拥有对象的 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 使用此 delegate 查找对非局部变量和 closure 参数的变量和方法引用。Gradle 将其用于配置 closure,其中 delegate
对象引用正在配置的对象。
dependencies {
assert delegate == project.dependencies
testImplementation('junit:junit:4.13')
delegate.testImplementation('junit:junit:4.13')
}
默认导入
为了使构建脚本更简洁,Gradle 会自动向脚本添加一组导入语句。
因此,您可以编写 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.*
下一步: 学习如何使用 Tasks >>