Gradle多项目构建
Gradle
可以轻松处理各种大小规模的项目。小项目由一个单一的构建文件和一个源代码树构成。 大项目可以将其拆分成更小的,相互依赖的模块,以便更容易理解。Gradle完美支持这种多项目构建的场景。
多项目构建的结构
这种构建有各种形状和大小,但它们都有一些共同的特点 -
- 在项目的根目录或主目录中都有一个
settings.gradle
文件。 - 根目录或主目录都有一个
build.gradle
文件。 - 具有自己的
*.gradle
构建文件的子目录(某些多项目构建可能会省略子项目构建脚本)。
要列出构建文件中的所有项目,可以使用以下命令。
D:/water>gradle -q projects
如果命令执行成功,将获得以下输出。
D:/water>gradle -q projects
------------------------------------------------------------
Root project
------------------------------------------------------------
Root project 'water'
+--- Project ':bluewhale'
/--- Project ':krill'
To see a list of the tasks of a project, run gradle <project-path>:tasks
For example, try running gradle :bluewhale:tasks
报告将显示每个项目的描述(如果指定)。可以使用以下命令指定描述。 将其粘贴到build.gradle
文件中。
description = 'The shared API for the application'
指定常规构建配置
在根项目中的build.gradle
文件中,常规配置可以应用于所有项目或仅应用于子项目。
allprojects {
group = 'com.example.gradle'
version = '0.1.0'
}
subprojects {
apply plugin: 'java'
apply plugin: 'eclipse'
}
这指定了一个公共com.example.gradle
组和一个0.1.0
版本到所有项目。subprojects
闭合所有应用对子项目通用配置,但不对根项目应用,如:allprojects
闭合。
项目指定配置和依赖关系
核心ui
和util
子项目也可以有自己的build.gradle
文件,如果它们有特定的需求,那么一般不会应用根项目配置。
例如,ui
项目通常具有对核心项目的依赖性。所以在ui
项目中需要有配置自己的build.gradle
文件来指定这个依赖。
dependencies {
compile project(':core')
compile 'log4j:log4j:1.2.17'
}
项目依赖项可使用项目方法指定。
Gradle多项目构建的示例
定义公共行为
让我们看看下面的一个例子的项目树。这是一个多项目构建,其中包含一个名为water
的根项目和一个名称为bluewham
的子项目。在这个示例中,我们把在创建一个目录D:/water
,作为根项目的目录。
多项目树 - water
和bluewham
项目的构建布局如下图所示 -
water/
build.gradle
settings.gradle
bluewhale/
首先,创建一个文件 settings.gradle 并写入以下代码内容 -
include 'bluewhale'
bluewhale
项目的构建脚本在哪里? 在Gradle中构建脚本是可选的。显然,对于单个项目构建,如果没有构建脚本那么项目是没有意义的。但对于多项目构建情况不同。让我们看看water
项目的构建脚本并执行它,创建一个文件build.gradle
并写入以下代码:
Closure cl = { task -> println "I'm $task.project.name" }
task hello << cl
project(':bluewhale') {
task hello << cl
}
并执行 gradle -q hello
输出结果如下 -
D:/water>gradle -q hello
I'm water
I'm bluewhale
Gradle允许从构建脚本中访问多项目构建的任何项目。 Project API提供了一个名称为project()
的方法,它将一个路径作为参数,并返回此路径的Project
对象。
为每个项目显式添加任务是不方便的。我们可以稍微做一下调整,先将另一个名称为krill
的项目添加到多项目构建中。
现在目录结构看起来如下所示 -
water/
build.gradle
settings.gradle
bluewhale/
krill/
再次编辑 settings.gradle
将以下代码加入到文件中 -
include 'bluewhale', 'krill'
现在我们已经重写 water
构建脚本并将其放在一行中。
将文件water
项目中的 build.gradle
并写入以下代码:
allprojects {
task hello << { task -> println "I'm $task.project.name" }
}
并执行 gradle -q hello
输出结果如下 -
D:/water>gradle -q hello
I'm water
I'm bluewhale
I'm krill
这是如何工作的? Project API提供了一个属性allprojects
,它返回当前项目及其下面所有子项目的列表。 如果使用闭包调用allprojects
,则闭包的语句将委派给与所有项目相关联的项目。当然也可以通过allprojects.each
进行迭代,但这将更冗长。
其他构建系统使用继承作为定义公共行为的主要方法。Gradle也为项目提供继承,您将在后面看到。但Gradle使用配置注入作为定义公共行为的常用方式。这是一种非常强大和灵活的配置多项目构建的方式。共享配置的另一种可能性是使用公共外部脚本。
子项目配置
Project API
还提供了一个仅用于访问子项目的属性。
定义公共行为
定义所有项目和子项目的公共行为,编辑 build.gradle
文件使用以下代码 -
allprojects {
task hello << {task -> println "I'm $task.project.name" }
}
subprojects {
hello << {println "- I depend on water"}
}
并执行 gradle -q hello
输出结果如下 -
D:/water>gradle -q hello
I'm water
I'm bluewhale
- I depend on water
I'm krill
- I depend on water
注意两个代码片段引用“hello
”任务。 第一个,它使用“task
”关键字,构建任务并提供它的基本配置。第二部分不使用“task
”关键字,因为它进一步配置现有的“hello
”任务。只能在项目中构建一次任务,但可以添加任意数量的代码块以提供其他配置。
添加指定行为
可以在常见行为之上添加指定的行为。要应用这个特定的行为,通常将项目特定的行为放在项目的构建脚本中。我们可以为 bluewhale
项目添加项目特定的行为,如下所示:
编辑 build.gradle
文件使用以下代码 -
allprojects {
task hello << {task -> println "I'm $task.project.name" }
}
subprojects {
hello << {println "- I depend on water"}
}
project(':bluewhale').hello << {
println "- I'm the largest animal that has ever lived on this planet."
}
并执行 gradle -q hello
输出结果如下 -
D:/water>gradle -q hello
I'm water
I'm bluewhale
- I depend on water
- I'm the largest animal that has ever lived on this planet.
I'm krill
- I depend on water
正如上面所说的,通常把项目特定的行为放入这个项目的构建脚本中。现在重构代码并向krill
项目添加一些项目特定的行为。
定义 krill
项目的具体行为
构建布局如下图中所示 -
water/
build.gradle
settings.gradle
bluewhale/
build.gradle
krill/
build.gradle
settings.gradle
文件的内容 -
include 'bluewhale', 'krill'
bluewhale/build.gradle
文件的内容 -
hello.doLast {
println "- I'm the largest animal that has ever lived on this planet."
}
krill/build.gradle
文件的内容 -
hello.doLast {
println "- The weight of my species in summer is twice as heavy as all human beings."
}
build.gradle
文件的内容 -
allprojects {
task hello << {task -> println "I'm $task.project.name" }
}
subprojects {
hello << {println "- I depend on water"}
}
并执行 gradle -q hello
输出结果如下 -
D:/water>gradle -q hello
I'm water
I'm bluewhale
- I depend on water
- I'm the largest animal that has ever lived on this planet.
I'm krill
- I depend on water
- The weight of my species in summer is twice as heavy as all human beings.
参考
- https://docs.gradle.org/current/userguide/multi_project_builds.html
- https://www.petrikainulainen.net/getting-started-with-gradle/