设置文件是每个 Gradle 构建的入口点。

author gradle 7

在 Gradle 构建生命周期的早期,初始化阶段会在你的项目根目录中找到设置文件。

当找到设置文件 settings.gradle(.kts) 时,Gradle 会实例化一个 Settings 对象。

Settings 对象的用途之一是允许你声明构建中要包含的所有项目。

设置脚本

设置脚本可以是 Groovy 的 settings.gradle 文件,也可以是 Kotlin 的 settings.gradle.kts 文件。

在 Gradle 为构建组装项目之前,它会创建一个 Settings 实例并针对它执行设置文件。

Settings

当设置脚本执行时,它会配置此 Settings。因此,设置文件定义了 Settings 对象。

一个 Settings 实例和一个 settings.gradle(.kts) 文件之间存在一对一的对应关系。

Settings 对象

Settings 对象是 Gradle API 的一部分。

  • 在 Groovy DSL 中,Settings 对象文档可以在这里找到。

  • 在 Kotlin DSL 中,Settings 对象文档可以在这里找到。

设置脚本中的许多顶级属性和块都是 Settings API 的一部分。

例如,我们可以使用 Settings.rootProject 属性在设置脚本中设置根项目名称。

settings.rootProject.name = "application"

通常缩短为

settings.gradle.kts
rootProject.name = "application"
settings.gradle
rootProject.name = 'application'

标准 Settings 属性

Settings 对象在您的设置脚本中公开了一组标准属性。

下表列出了一些常用属性

名称 描述

buildCache

构建缓存配置。

plugins

已应用于设置的插件容器。

rootDir

构建的根目录。根目录是根项目的项目目录。

rootProject

构建的根项目。

settings

返回此设置对象。

下表列出了一些常用方法

名称 描述

include()

将给定项目添加到构建中。

includeBuild()

将指定路径的构建包含到组合构建中。

设置脚本结构

Settings 脚本是一系列对 Gradle API 的方法调用,通常使用 { …​ },这是 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 逐行从上到下执行脚本。

让我们看一个例子并将其分解

settings.gradle.kts
pluginManagement {  (1)
    repositories {
        gradlePluginPortal()
    }
}

plugins {   (2)
    id("org.gradle.toolchains.foojay-resolver-convention") version "1.0.0"
}

rootProject.name = "simple-project"     (3)

dependencyResolutionManagement {    (4)
    repositories {
        mavenCentral()
    }
}

include("sub-project-a")     (5)
include("sub-project-b")
include("sub-project-c")
settings.gradle
pluginManagement {  (1)
    repositories {
        gradlePluginPortal()
    }
}

plugins {   (2)
    id("org.gradle.toolchains.foojay-resolver-convention") version "1.0.0"
}

rootProject.name = 'simple-project'     (3)

dependencyResolutionManagement {    (4)
    repositories {
        mavenCentral()
    }
}

include("sub-project-a")    (5)
include("sub-project-b")
include("sub-project-c")
1 定义插件的位置
2 应用设置插件。
3 定义根项目名称。
4 定义依赖解析策略。
5 向构建添加子项目。

1. 定义插件的位置

设置文件可以使用 pluginManagement 块管理构建的插件版本和存储库。它提供了一种方法来定义项目应使用哪些插件以及应从哪些存储库解析它们。

settings.gradle.kts
pluginManagement {  (1)
    repositories {
        gradlePluginPortal()
    }
}
settings.gradle
pluginManagement {  (1)
    repositories {
        gradlePluginPortal()
    }
}

2. 应用设置插件

设置文件可以选择性地应用插件,这些插件是配置项目设置所必需的。在下面的示例中,这些插件通常是 Develocity 插件Toolchain Resolver 插件

在设置文件中应用的插件仅影响 Settings 对象。

settings.gradle.kts
plugins {   (2)
    id("org.gradle.toolchains.foojay-resolver-convention") version "1.0.0"
}
settings.gradle
plugins {   (2)
    id("org.gradle.toolchains.foojay-resolver-convention") version "1.0.0"
}

3. 定义根项目名称

设置文件使用 rootProject.name 属性定义项目名称。

settings.gradle.kts
rootProject.name = "simple-project"     (3)
settings.gradle
rootProject.name = 'simple-project'     (3)

每个构建只有一个根项目。

4. 定义依赖解析策略

设置文件可以选择性地定义规则和配置,用于跨项目进行依赖解析。它提供了一种集中管理和自定义依赖解析的方法。

settings.gradle.kts
dependencyResolutionManagement {    (4)
    repositories {
        mavenCentral()
    }
}
settings.gradle
dependencyResolutionManagement {    (4)
    repositories {
        mavenCentral()
    }
}

你还可以在此部分中包含版本目录。

5. 向构建添加子项目

设置文件通过使用 include 语句添加所有子项目来定义项目结构。

settings.gradle.kts
include("sub-project-a")     (5)
include("sub-project-b")
include("sub-project-c")
settings.gradle
include("sub-project-a")    (5)
include("sub-project-b")
include("sub-project-c")

你还可以使用 includeBuild 包含整个构建。

设置文件脚本编写

Settings 对象还有更多属性和方法,您可以使用它们来配置构建。

重要的是要记住,虽然许多 Gradle 脚本通常以简短的 Groovy 或 Kotlin 语法编写,但设置脚本中的每个项本质上都是在 Gradle API 的 Settings 对象上调用方法。

include("app")

实际上是

settings.include("app")

此外,您可以使用 Groovy 和 Kotlin 语言的全部功能。

例如,您不必多次使用 include 添加子项目,而是可以遍历项目根文件夹中的目录列表并自动包含它们。

rootDir.listFiles().filter { it.isDirectory && (new File(it, "build.gradle.kts").exists()) }.forEach {
    include(it.name)
}
此类逻辑应在插件中开发。