Gradle 支持多项目构建。
虽然一些小型项目和整体应用程序可能包含单个构建文件和源代码树,但更常见的情况是项目被分割成更小的、相互依赖的模块。 “相互依赖”这个词至关重要,因为您通常希望通过单个构建将许多模块链接在一起。
Gradle 通过多项目构建支持这种场景。这有时被称为多模块项目。 Gradle 将模块称为子项目。
多项目构建由一个根项目和一个或多个子项目组成。
多项目结构
以下表示包含两个子项目的多项目构建的结构:
目录结构应如下所示:
├── .gradle │ └── ⋮ ├── gradle │ ├── libs.version.toml │ └── wrapper ├── gradlew ├── gradlew.bat ├── settings.gradle.kts (1) ├── sub-project-1 │ └── build.gradle.kts (2) ├── sub-project-2 │ └── build.gradle.kts (2) └── sub-project-3 └── build.gradle.kts (2)
1 | 该settings.gradle.kts 文件应包含所有子项目。 |
2 | 每个子项目都应该有自己的build.gradle.kts 文件。 |
多项目标准
Gradle 社区对于多项目构建结构有两个标准:
-
使用 buildSrc 进行多项目构建- 其中
buildSrc
是 Gradle 项目根目录中包含所有构建逻辑的类似子项目的目录。 -
复合构建- 包含其他构建的构建,其中
build-logic
包含可重用构建逻辑的 Gradle 项目根目录中的构建目录。
1. 多项目构建使用buildSrc
多项目构建允许您组织具有许多模块的项目,连接这些模块之间的依赖关系,并轻松地在它们之间共享通用的构建逻辑。
例如,一个包含许多名为mobile-app
、web-app
、api
、lib
、的模块的构建documentation
可以按如下方式构建:
.
├── gradle
├── gradlew
├── settings.gradle.kts
├── buildSrc
│ ├── build.gradle.kts
│ └── src/main/kotlin/shared-build-conventions.gradle.kts
├── mobile-app
│ └── build.gradle.kts
├── web-app
│ └── build.gradle.kts
├── api
│ └── build.gradle.kts
├── lib
│ └── build.gradle.kts
└── documentation
└── build.gradle.kts
这些模块之间将具有依赖关系,例如web-app
和mobile-app
dependent on lib
。这意味着为了让 Gradle 构建web-app
或mobile-app
,它必须lib
首先构建。
在此示例中,根设置文件将如下所示:
include("mobile-app", "web-app", "api", "lib", "documentation")
子项目(模块)的包含顺序并不重要。 |
buildSrc
Gradle 会自动识别该目录。它是定义和维护共享配置或命令式构建逻辑(例如自定义任务或插件)的好地方。
buildSrc
如果build.gradle(.kts)
在buildSrc
.
如果java
插件应用于buildSrc
项目,则编译后的代码buildSrc/src/main/java
将放入根构建脚本的类路径中,使其可用于构建中的任何子项目( web-app
、mobile-app
、等...)。lib
请参阅如何声明子项目之间的依赖关系以了解更多信息。
2. 复合构建
复合构建,也称为包含构建,最适合在构建(而不是子项目)之间共享逻辑或隔离对共享构建逻辑(即约定插件)的访问。
让我们以前面的例子为例。其中的逻辑buildSrc
已转变为包含插件的项目,并且可以独立于根项目构建进行发布和工作。
该插件被移动到它自己的构建中,build-logic
使用构建脚本和设置文件调用:
.
├── gradle
├── gradlew
├── settings.gradle.kts
├── build-logic
│ ├── settings.gradle.kts
│ └── conventions
│ ├── build.gradle.kts
│ └── src/main/kotlin/shared-build-conventions.gradle.kts
├── mobile-app
│ └── build.gradle.kts
├── web-app
│ └── build.gradle.kts
├── api
│ └── build.gradle.kts
├── lib
│ └── build.gradle.kts
└── documentation
└── build.gradle.kts
build-logic 位于根项目的子目录中
的事实是无关紧要的。如果需要,该文件夹可以位于根项目之外。
|
根设置文件包括整个build-logic
构建:
pluginManagement {
includeBuild("build-logic")
}
include("mobile-app", "web-app", "api", "lib", "documentation")
请参阅如何创建复合构建以includeBuild
了解更多信息。
多项目路径
项目路径具有以下模式:它以可选的冒号开头,表示根项目。
根项目:
是路径中唯一未按其名称指定的项目。
项目路径的其余部分是用冒号分隔的项目名称序列,其中下一个项目是上一个项目的子项目:
:sub-project-1
运行时可以看到项目路径gradle projects
:
------------------------------------------------------------
Root project 'project'
------------------------------------------------------------
Root project 'project'
+--- Project ':sub-project-1'
\--- Project ':sub-project-2'
项目路径通常反映文件系统布局,但也有例外。最显着的是复合构建。
确定项目结构
您可以使用该gradle projects
命令来识别项目结构。
作为示例,让我们使用具有以下结构的多项目构建:
> gradle -q projects
------------------------------------------------------------ Root project 'multiproject' ------------------------------------------------------------ Root project 'multiproject' +--- Project ':api' +--- Project ':services' | +--- Project ':services:shared' | \--- Project ':services:webservice' \--- Project ':shared' To see a list of the tasks of a project, run gradle <project-path>:tasks For example, try running gradle :api:tasks
多项目构建是您可以运行的任务的集合。不同之处在于您可能想要控制执行哪个项目的任务。
以下部分将介绍在多项目构建中执行任务的两个选项。
按名称执行任务
该命令将在相对于具有该任务的当前工作目录的任何子项目中gradle test
执行该任务。test
如果从项目根目录运行该命令,您将test
在api、shared、services:shared和services:webservice中运行。
如果从services项目目录运行命令,则只会执行services:shared和services:webservice中的任务。
Gradle 行为背后的基本规则是使用该名称执行层次结构中的所有任务。如果在遍历的任何子项目中都没有找到这样的任务,则进行抱怨。
某些任务选择器(例如help 或dependencies )只会在调用它们的项目上运行任务,而不是在所有子项目上运行,以减少屏幕上打印的信息量。
|
通过完全限定名称执行任务
您可以使用任务的完全限定名称来执行特定子项目中的特定任务。例如:gradle :services:webservice:build
将运行webservicebuild
子项目的任务。
任务的完全限定名称是其项目路径加上任务名称。
这种方法适用于任何任务,因此如果您想知道特定子项目中有哪些任务,请使用任务tasks
,例如gradle :services:webservice:tasks
。
多项目构建和测试
该build
任务通常用于编译、测试和检查单个项目。
在多项目构建中,您可能经常希望跨多个项目执行所有这些任务。和buildNeeded
任务buildDependents
可以帮助解决这个问题。
在此示例中,:services:person-service
项目同时依赖于:api
和:shared
项目。项目:api
也要看:shared
项目。
假设您正在处理单个项目,即该:api
项目,您一直在进行更改,但自从执行clean
.您想要构建任何必要的支持 JAR,但仅对已更改的项目部分执行代码质量和单元测试。
该build
任务执行以下操作:
$ gradle :api:build > Task :shared:compileJava > Task :shared:processResources > Task :shared:classes > Task :shared:jar > Task :api:compileJava > Task :api:processResources > Task :api:classes > Task :api:jar > Task :api:assemble > Task :api:compileTestJava > Task :api:processTestResources > Task :api:testClasses > Task :api:test > Task :api:check > Task :api:build BUILD SUCCESSFUL in 0s
如果您刚刚从版本控制系统获取了最新版本的源代码,其中包括:api
依赖的其他项目中的更改,您可能想要构建您依赖的所有项目并测试它们。
该buildNeeded
任务构建并测试配置的项目依赖项中的所有项目testRuntime
:
$ gradle :api:buildNeeded > Task :shared:compileJava > Task :shared:processResources > Task :shared:classes > Task :shared:jar > Task :api:compileJava > Task :api:processResources > Task :api:classes > Task :api:jar > Task :api:assemble > Task :api:compileTestJava > Task :api:processTestResources > Task :api:testClasses > Task :api:test > Task :api:check > Task :api:build > Task :shared:assemble > Task :shared:compileTestJava > Task :shared:processTestResources > Task :shared:testClasses > Task :shared:test > Task :shared:check > Task :shared:build > Task :shared:buildNeeded > Task :api:buildNeeded BUILD SUCCESSFUL in 0s
您可能想要重构:api
其他项目中使用的项目的某些部分。如果进行这些更改,仅测试:api
项目是不够的。您必须测试依赖于该:api
项目的所有项目。
该buildDependents
任务测试对指定项目具有项目依赖性(在 testRuntime 配置中)的所有项目:
$ gradle :api:buildDependents > Task :shared:compileJava > Task :shared:processResources > Task :shared:classes > Task :shared:jar > Task :api:compileJava > Task :api:processResources > Task :api:classes > Task :api:jar > Task :api:assemble > Task :api:compileTestJava > Task :api:processTestResources > Task :api:testClasses > Task :api:test > Task :api:check > Task :api:build > Task :services:person-service:compileJava > Task :services:person-service:processResources > Task :services:person-service:classes > Task :services:person-service:jar > Task :services:person-service:assemble > Task :services:person-service:compileTestJava > Task :services:person-service:processTestResources > Task :services:person-service:testClasses > Task :services:person-service:test > Task :services:person-service:check > Task :services:person-service:build > Task :services:person-service:buildDependents > Task :api:buildDependents BUILD SUCCESSFUL in 0s
最后,您可以构建和测试所有项目中的所有内容。您在根项目文件夹中运行的任何任务都将导致该同名任务在所有子项目上运行。
您可以运行gradle build
来构建和测试所有项目。
请参阅构建构建章节以了解更多信息。
下一步: 了解 Gradle 构建生命周期>>