聊聊 Gradle buildSrc

简单了解一下 Gradle 项目中 buildSrc 的用法。

buildSrc 介绍

本节内容翻译自Organizing Gradle Projects

复杂的构建逻辑通常适合封装成自定义任务或者二进制插件。自定义任务和二进制插件不应放到项目的构建脚本中。如果这些逻辑不需要在多个独立的项目中共享,那么可以使用buildSrc

buildSrc目录视为一个included build。一旦 Gradle 发现这个目录,它会自动编译和测试其中的代码并将其添加到构建脚本的classpath。对于多项目构建(multi-project builds),只能有一个buildSrc目录,这个目录位于项目根目录。应优先使用buildSrc而不是插件(script plugins),因为前者代码更容易维护、重构和测试。

buildSrc使用跟Java和Groovy项目相同的代码结构(source code conventions)。它可以直接访问Gradle API。buildSrc目录下的build.gradle脚本中可以添加其他依赖。

Example 1. Custom buildSrc build script

1
2
3
4
5
6
7
repositories {
mavenCentral()
}

dependencies {
testImplementation 'junit:junit:4.13'
}

一个包含buildSrc的工程,其项目结构如下。buildSrc下的代码使用跟应用代码类似的包。如果有额外的配置需要,buildSrc目录可以放一个可选的构建脚本(比如,使用插件或声明依赖)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
.
├── buildSrc
│ ├── build.gradle
│ └── src
│ ├── main
│ │ └── java
│ │ └── com
│ │ └── enterprise
│ │ ├── Deploy.java
│ │ └── DeploymentPlugin.java
│ └── test
│ └── java
│ └── com
│ └── enterprise
│ └── DeploymentPluginTest.java
├── settings.gradle
├── subprojecto-one
│ └── build.gradle.kts
└── subproject-two
└── build.gradle.kts

注意buildSrc中的变更会引起整个项目变成out-of-date状态。因此,当进行小的增量变更时,–no-rebuild command-line option可加快编译速度。记住buildSrc修改完成后要定期进行全量构建。

总结一下:

参考 摘自 Gradle 文档:当运行 Gradle 时会检查项目中是否存在一个名为 buildSrc 的目录。然后 Gradle 会自动编译并测试这段代码,并将其放入构建脚本的类路径中, 对于多项目构建,只能有一个 buildSrc 目录,该目录必须位于根项目目录中, buildSrc 是 Gradle 项目根目录下的一个目录,它可以包含我们的构建逻辑,与脚本插件相比,buildSrc 应该是首选,因为它更易于维护、重构和测试代码

操作步骤

  • IDEA 新建 gradle 项目
  • 在项目下新建 buildSrc 目录 (注意是目录而不是 module)
  • buildSrc 目录下新建或修改 build.gradle 文件。内容如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
plugins {
id 'groovy'
id 'java'
}

group 'com.gradle'
version '0.0.1-SNAPSHOT'

repositories {
mavenCentral()
}

dependencies {
implementation 'org.codehaus.groovy:groovy-all:3.0.7'
testImplementation group: 'junit', name: 'junit', version: '4.12'
}
  • buildSrc 目录中创建源码目录,src/main/groovy
    -w716
  • 在源码目录下新建一个类 MyTask
1
2
3
4
5
6
7
8
9
10
class MyTask extends DefaultTask{
MyTask() {
this.description = "test buildSrc"
}

@TaskAction
void start() {
println 'hi, cm, bi bo bi bo... ...'
}
}
  • 在项目根目录的 build.gradle 中使用新建的 MyTask
    -w1391

参考