详细学习Gradle的多工程构建。第一部分。该学习记录基于Gradle官方网站资料。本篇参考链接如下:
https://docs.gradle.org/current/userguide/multi_project_builds.html
多工程构建是Gradle的卖点(虽然它是免费的)。从这篇开始,预计花费两到三篇来学习多工程的构建。
工程的交叉配置
按需求配置原则
多工程构建为了节省时间,Gradle只配置需要配置的任务和工程,只执行需要执行的任务。主要尊寻一下几点:
- 根工程必然会被配置
- 被执行的构建脚本所在的工程必然会被配置,除非Gradle没有执行任何任务。
- 工程之间有依赖关系的情况下,依赖的工程如果被配置了,那么被依赖的工程也必然被配置。
- 不同工程的任务之间有依赖关系的情况同上。
- 命令行输入的执行命令中,有指定的工程时,被指定的工程也会被配置。比如"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会继续学习。