使用子项目和复合构建学习 Gradle 项目构建基础知识。
步骤 1. 关于多项目构建
通常,构建包含多个项目,例如将在您的生态系统中部署的共享库或独立应用程序。
在 Gradle 中,多项目构建包括
-
表示您的 Gradle 构建的文件
settings.gradle(.kts)
,包括必需的子项目,例如 include("app", "model", "service") -
每个子项目在相应子目录中的
build.gradle(.kts)
和源代码
我们的构建当前包含一个名为 authoring-tutorial
的根项目,该项目有一个 app
子项目
. (1)
├── app (2)
│ ... (3)
│ └── build.gradle.kts (4)
└── settings.gradle.kts (5)
1 | authoring-tutorial 根项目 |
2 | app 子项目 |
3 | app 源代码 |
4 | app 构建脚本 |
5 | 可选的设置文件 |
. (1)
├── app (2)
│ ... (3)
│ └── build.gradle (4)
└── settings.gradle (5)
1 | authoring-tutorial 根项目 |
2 | app 子项目 |
3 | app 源代码 |
4 | app 构建脚本 |
5 | 可选的设置文件 |
步骤 2. 向构建添加另一个子项目
想象一下,我们的项目正在增长,需要一个自定义库才能发挥作用。
让我们创建这个假想的 lib
。首先,创建一个 lib
文件夹
mkdir lib
cd lib
创建一个名为 build.gradle(.kts)
的文件,并向其中添加以下行
plugins {
id("java")
}
repositories {
mavenCentral()
}
dependencies {
testImplementation("org.junit.jupiter:junit-jupiter:5.9.3")
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
implementation("com.google.guava:guava:32.1.1-jre")
}
tasks.named<Test>("test") {
useJUnitPlatform()
}
tasks.register("task3"){
println("REGISTER TASK3: This is executed during the configuration phase")
}
tasks.named("task3"){
println("NAMED TASK3: This is executed during the configuration phase")
doFirst {
println("NAMED TASK3 - doFirst: This is executed during the execution phase")
}
doLast {
println("NAMED TASK3 - doLast: This is executed during the execution phase")
}
}
plugins {
id 'java'
}
repositories {
mavenCentral()
}
dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter:5.9.3'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
implementation 'com.google.guava:guava:32.1.1-jre'
}
test {
useJUnitPlatform()
}
tasks.register('task3') {
println('REGISTER TASK3: This is executed during the configuration phase')
}
tasks.named('task3') {
println('NAMED TASK3: This is executed during the configuration phase')
doFirst {
println('NAMED TASK3 - doFirst: This is executed during the execution phase')
}
doLast {
println('NAMED TASK3 - doLast: This is executed during the execution phase')
}
}
您的项目应如下所示
.
├── app
│ ...
│ └── build.gradle.kts
├── lib
│ └── build.gradle.kts
└── settings.gradle.kts
.
├── app
│ ...
│ └── build.gradle
├── lib
│ └── build.gradle
└── settings.gradle
让我们向 lib
子项目添加一些代码。创建一个新目录
mkdir -p lib/src/main/java/com/gradle
在名为 CustomLib.java
的文件中创建一个名为 CustomLib
的 Java 类,其中包含以下源代码
package com.gradle;
public class CustomLib {
public static String identifier = "I'm a String from a lib.";
}
现在,该项目应具有以下文件和目录结构
.
├── app
│ ├── build.gradle.kts
│ └── src
│ └── main
│ └── java
│ └── authoring
│ └── tutorial
│ └── App.java
├── lib
│ ├── build.gradle.kts
│ └── src
│ └── main
│ └── java
│ └── com
│ └── gradle
│ └── CustomLib.java
└── settings.gradle.kts
.
├── app
│ ├── build.gradle
│ └── src
│ └── main
│ └── java
│ └── authoring
│ └── tutorial
│ └── App.java
├── lib
│ ├── build.gradle
│ └── src
│ └── main
│ └── java
│ └── com
│ └── gradle
│ └── CustomLib.java
└── settings.gradle
但是,lib
子项目不属于该构建,并且在将其添加到 settings.gradle(.kts)
文件之前,您将无法执行 task3
。
要将 lib
添加到构建中,请相应地更新根目录中的 settings.gradle(.kts)
文件
plugins {
id("org.gradle.toolchains.foojay-resolver-convention") version "0.7.0"
}
rootProject.name = "authoring-tutorial"
include("app")
include("lib") // Add lib to the build
plugins {
id 'org.gradle.toolchains.foojay-resolver-convention' version '0.7.0'
}
rootProject.name = 'authoring-tutorial'
include('app')
include('lib') // Add lib to the build
让我们在 app/build.gradle(.kts)
中将 lib
子项目添加为 app
依赖项
dependencies {
implementation(project(":lib")) // Add lib as an app dependency
}
dependencies {
implementation(project(':lib')) // Add lib as an app dependency
}
更新 app
源代码,以便其导入 lib
package authoring.tutorial;
import com.gradle.CustomLib;
public class App {
public String getGreeting() {
return "CustomLib identifier is: " + CustomLib.identifier;
}
public static void main(String[] args) {
System.out.println(new App().getGreeting());
}
}
最后,让我们使用命令 ./gradlew run
运行 app
$ ./gradlew run
> Configure project :app
> Task :app:processResources NO-SOURCE
> Task :lib:compileJava
> Task :lib:processResources NO-SOURCE
> Task :lib:classes
> Task :lib:jar
> Task :app:compileJava
> Task :app:classes
> Task :app:run
CustomLib identifier is: I'm a String from a lib.
BUILD SUCCESSFUL in 11s
8 actionable tasks: 6 executed, 2 up-to-date
我们针对根项目 authoring-tutorial
的构建现在包括两个子项目,app
和 lib
。app
依赖于 lib
。您可以独立于 app
构建 lib
。但是,要构建 app
,Gradle 也会构建 lib
。
步骤 3. 了解复合构建
复合构建仅仅是包含其他构建的构建。
复合构建允许您
-
从项目构建中提取构建逻辑(并在子项目之间重复使用)
-
组合通常独立开发的构建(例如插件和应用程序)
-
将大型构建分解为更小、更独立的部分
步骤 4. 将构建添加到构建中
让我们向我们的构建添加一个插件。首先,在 gradle
目录中创建一个名为 license-plugin
的新目录
cd gradle
mkdir license-plugin
cd license-plugin
进入 gradle/license-plugin
目录后,运行 gradle init
。确保您选择 Gradle plugin
项目以及以下 init
任务的其他选项
$ gradle init --dsl kotlin --type kotlin-gradle-plugin --project-name license
$ gradle init --dsl groovy --type groovy-gradle-plugin --project-name license
为任何其他提示选择默认值。
您的项目应如下所示
.
├── app
│ ...
│ └── build.gradle.kts
├── lib
│ ...
│ └── build.gradle.kts
├── gradle
│ ├── ...
│ └── license-plugin
│ ├── settings.gradle.kts
│ └── plugin
│ ├── gradle
│ │ └── ....
│ ├── src
│ │ ├── functionalTest
│ │ │ └── ....
│ │ ├── main
│ │ │ └── kotlin
│ │ │ └── license
│ │ │ └── LicensePlugin.kt
│ │ └── test
│ │ └── ...
│ └── build.gradle.kts
│
└── settings.gradle.kts
.
├── app
│ ...
│ └── build.gradle
├── lib
│ ...
│ └── build.gradle
├── gradle
│ ├── ...
│ └── license-plugin
│ ├── settings.gradle
│ └── plugin
│ ├── gradle
│ │ └── ....
│ ├── src
│ │ ├── functionalTest
│ │ │ └── ....
│ │ ├── main
│ │ │ └── groovy
│ │ │ └── license
│ │ │ └── LicensePlugin.groovy
│ │ └── test
│ │ └── ...
│ └── build.gradle
│
└── settings.gradle
花点时间查看 LicensePlugin.kt
或 LicensePlugin.groovy
代码和 gradle/license-plugin/settings.gradle(.kts)
文件。请务必注意,这是一个完全独立的构建,具有自己的设置文件和构建脚本
rootProject.name = "license"
include("plugin")
rootProject.name = 'license'
include('plugin')
要将我们的 license-plugin
构建添加到根项目,请相应地更新根 settings.gradle(.kts)
文件
plugins {
id("org.gradle.toolchains.foojay-resolver-convention") version "0.7.0"
}
rootProject.name = "authoring-tutorial"
include("app")
include("subproject")
includeBuild("gradle/license-plugin") // Add the new build
plugins {
id 'org.gradle.toolchains.foojay-resolver-convention' version '0.7.0'
}
rootProject.name = 'running-tutorial-groovy'
include('app')
include('lib')
includeBuild('gradle/license-plugin')
您可以在根文件夹 authoring-tutorial
中运行 ./gradlew projects
来查看根项目的结构
$ ./gradlew projects
------------------------------------------------------------
Root project 'authoring-tutorial'
------------------------------------------------------------
Root project 'authoring-tutorial'
+--- Project ':app'
\--- Project ':lib'
Included builds
\--- Included build ':license-plugin'
我们针对根项目 authoring-tutorial
的构建现在包括两个子项目 app
和 lib
,以及另一个构建 license-plugin
。
在项目根目录中运行时
-
./gradlew build
- 构建app
和lib
-
./gradlew :app:build
- 构建app
和lib
-
./gradlew :lib:build
- 仅构建lib
-
./gradlew :license-plugin:plugin:build
- 仅构建license-plugin
使用 Gradle 设计项目架构的方法有很多。
多项目构建非常适合组织具有许多模块的项目,例如 mobile-app
、web-app
、api
、lib
和 documentation
,这些模块之间存在依赖关系。
复合(包含)构建非常适合分离构建逻辑(即约定插件)或测试系统(即修补库)
下一步: 设置文件 >>