Gradle复合构建:如何让被包含构建的任务依赖主项目任务?
被包含构建任务依赖根项目任务的实现方案
Gradle本身没有提供直接让被包含构建任务依赖根项目任务的语法,但可以通过以下几种方式实现任务顺序控制:
方法1:利用构建服务(Build Service)协调执行顺序
构建服务可跨构建共享状态,我们可以用它标记根项目任务的完成状态,让被包含构建的任务等待该状态就绪。
- 根项目
build.gradle中注册构建服务并关联任务:
// 定义构建服务类型 abstract class RootTaskCompletedService implements BuildService<BuildServiceParameters.None> {} // 注册共享服务 def rootTaskService = project.getGradle().getSharedServices().registerIfAbsent("rootTaskCompleted", RootTaskCompletedService) {} // 根项目任务完成后绑定服务 tasks.register("rootPreTask") { doLast { // 这里执行根任务的业务逻辑 println "根项目前置任务执行完成" } finalizedBy(rootTaskService) }
- 被包含构建的
build.gradle中依赖该构建服务:
// 获取根项目注册的共享服务 def rootTaskService = gradle.sharedServices.find("rootTaskCompleted") // 让被包含构建的任务等待服务就绪 tasks.named("app:run") { dependsOn(rootTaskService) }
方法2:通过任务输出文件建立依赖关系
利用文件存在性作为依赖触发条件,让被包含构建的任务等待根项目任务生成的标记文件。
- 根项目
build.gradle中创建生成标记文件的任务:
tasks.register("rootPreTask") { def markerFile = file("$buildDir/root-task-completed.marker") outputs.file(markerFile) doLast { markerFile.text = "completed at ${new Date()}" println "根项目前置任务执行完成" } }
- 根项目
settings.gradle中共享根项目任务输出给被包含构建:
includeBuild("my-app") { dependencySubstitution { substitute(module("com.example:root-marker")).using(project(":")).withVariant("marker") } }
- 被包含构建的
build.gradle中依赖该标记文件:
configurations.create("rootMarker") dependencies { rootMarker("com.example:root-marker") } tasks.named("app:run") { dependsOn(configurations.rootMarker) doFirst { println "根项目前置任务已完成,开始执行app:run" } }
方法3:通过Gradle启动参数传递执行信号
在根项目任务中设置系统属性,被包含构建的任务检查该属性,若未设置则触发根项目任务执行(注意:此方法可能破坏Gradle任务依赖图,仅适合简单场景)。
- 根项目
build.gradle:
tasks.register("rootPreTask") { doLast { System.setProperty("rootTaskCompleted", "true") println "根项目前置任务执行完成" } }
- 被包含构建的
build.gradle:
tasks.named("app:run") { doFirst { if (!System.getProperty("rootTaskCompleted")) { gradle.parent.rootProject.tasks.named("rootPreTask").get().execute() } } }
内容的提问来源于stack exchange,提问作者Kimble
相关产品推荐
相关产品推荐

