四时宝库

程序员的知识宝库

Gradle学习记录010 多工程构建 part1

详细学习Gradle的多工程构建。第一部分。该学习记录基于Gradle官方网站资料。本篇参考链接如下:

https://docs.gradle.org/current/userguide/multi_project_builds.html

多工程构建是Gradle的卖点(虽然它是免费的)。从这篇开始,预计花费两到三篇来学习多工程的构建。

工程的交叉配置

按需求配置原则

多工程构建为了节省时间,Gradle只配置需要配置的任务和工程,只执行需要执行的任务。主要尊寻一下几点:

  1. 根工程必然会被配置
  2. 被执行的构建脚本所在的工程必然会被配置,除非Gradle没有执行任何任务。
  3. 工程之间有依赖关系的情况下,依赖的工程如果被配置了,那么被依赖的工程也必然被配置。
  4. 不同工程的任务之间有依赖关系的情况同上。
  5. 命令行输入的执行命令中,有指定的工程时,被指定的工程也会被配置。比如"projectA:projectB:someTask"

下面的示例合并了官网的数个示例,并做了一些小修改。注意脚本中的注释以及输出结果。

工程目录结构:

water
├── bluewhale
│ └── build.gradle
├── build.gradle
├── krill
│ └── build.gradle
├── settings.gradle
└── tropicalFish
 └── build.gradle

主工程water的build.gradle文件:

// 只是用于展示Closure的用法
Closure cl = { task -> println "I'm $task.project.name" }
// 为所有的工程追加一个hello任务
allprojects {
 task hello {
 doLast (cl)
 }
}
// 为所有的子工程的hello任务追加输出语句
subprojects {
 hello {
 doLast {
 println "- I depend on water"
 }
 }
 
 // 子工程评价完成的时间点,判断工程的自定义变量arctic是否为true。
 // 如果是则为其hello任务追加输出语句
 // 如上一章所述,afterEvaluate也是配置阶段的一部分
 afterEvaluate { Project project ->
 if (project.arctic) {
 hello.configure {
 doLast {
 println '- I love to spend time in the arctic waters.'
 }
 }
 }
 }
}
// 为特定子工程的hello任务追加输出语句
project(':bluewhale').hello {
 doLast {
 println "- I'm a mammal."
 }
}
// 在配置阶段,为非热带鱼的子工程的hello任务追加输出语句
configure(subprojects.findAll {it.name != 'tropicalFish'}) {
 hello {
 doLast {
 println '- I love to spend time in the arctic waters.'
 }
 }
}

主工程water的settings.gradle文件:

rootProject.name = 'water'
// 引入了蓝鲸,磷虾,热带鱼三个子工程
include 'bluewhale', 'krill', 'tropicalfish'

子工程的build.gradle文件:

// 用于过滤的自定义变量
ext.arctic = true
// 子工程的构建脚本中定义的hello任务
hello.doLast {
 println "- I'm the largest animal that has ever lived on this planet."
}
// 三个子工程中,有两个拥有此任务
task distanceToIceberg {
 doLast {
 println '20 nautical miles'
 }
}

子工程krill的build.gradle文件:

// 用于过滤的自定义变量
ext.arctic = true
// 子工程的构建脚本中定义的hello任务
hello.doLast {
 println "- I'm the largest animal that has ever lived on this planet."
}
// 三个子工程中,有两个拥有此任务
task distanceToIceberg {
 doLast {
 println '20 nautical miles'
 }
}

子工程tropicalfish的build.gradle文件

// 用于过滤的自定义变量
ext.arctic = false

执行结果1:

$ gradle hello

> Task :hello

I'm water

> Task :bluewhale:hello

I'm bluewhale

- I depend on water

- I'm a mammal.

- I love to spend time in the arctic waters.

- I'm the largest animal that has ever lived on this planet.

- I love to spend time in the arctic waters.

> Task :krill:hello

I'm krill

- I depend on water

- I love to spend time in the arctic waters.

- The weight of my species in summer is twice as heavy as all human beings.

- I love to spend time in the arctic waters.

> Task :tropicalfish:hello

I'm tropicalfish

- I depend on water

- I love to spend time in the arctic waters.

这个执行结果完美展示了根工程,子工程内定义的同名任务的执行顺序。

执行结果2:

$ gradle distanceToIceberg

> Task :bluewhale:distanceToIceberg

20 nautical miles

> Task :krill:distanceToIceberg

20 nautical miles

BUILD SUCCESSFUL in 1s

2 actionable tasks: 2 executed

三个子工程中,只有两个含有distanceToIceberg任务。在根工程的目录下执行gradle命令时,Gradle会自动查找所有子工程并找出同名方法,然后执行他们。

执行结果3:

$ gradle :hello :krill:hello hello

> Task :hello

I'm water

> Task :krill:hello

I'm krill

- I depend on water

- I love to spend time in the arctic waters.

- The weight of my species in summer is twice as heavy as all human beings.

- I love to spend time in the arctic waters.

> Task :bluewhale:hello

I'm bluewhale

- I depend on water

- I'm a mammal.

- I love to spend time in the arctic waters.

- I'm the largest animal that has ever lived on this planet.

- I love to spend time in the arctic waters.

> Task :tropicalfish:hello

I'm tropicalfish

- I depend on water

- I love to spend time in the arctic waters.

这个执行结果展示了如何执行特定子工程的特定任务。:hello是根工程的任务。:krill:hello是子工程的任务。值得注意的是命令的最后一个hello。它并没有像输出结果1那样把所有工程里的hello都重新执行一遍。它只是执行了bluewhale和tropicalfish的hello任务。

以上的示例只是展示了配置阶段的依赖,关于执行阶段的依赖如何设置,part2会继续学习。

发表评论:

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言
    友情链接