我有一个非常简单的多项目构建,如下所示:
模块 1,它生成一个公共 API jar 并通过"公共 API"配置公开它:
configurations {
publicAPI
}
task generatePublicAPI(type: Jar) {
outputs.upToDateWhen { false }
baseName 'public-api'
from sourceSets.main.output
}
artifacts {
publicAPI generatePublicAPI
}
模块 2,它使用公共 API jar(通过引用模块 1 中定义的"publicAPI"配置)来生成应用程序 jar:
configurations {
generateApplication
}
dependencies {
generateApplication project(path: ':module1', configuration: 'publicAPI')
}
task jarApp(type: Jar) {
baseName 'app'
from configurations.generateApplication.collect {
it.isDirectory() ? it : zipTree(it)
}
}
现在,当我执行"gradle :module2:jarApp"任务时,我收到以下错误:
无法展开压缩 '/home/picasso/Documents/GradlePlayground/module1/build/libs/public-api.jar' 因为它不存在
我可以看到 gradle 并没有尝试执行模块 1 的"生成公共API"。
但是,如果我使"jarApp"任务显式依赖于"生成公共API"任务,
task jarApp(dependsOn: 'module1:generatePublicAPI', type: Jar) {...}
然后一切都很好。
但是,这种方法不会违背使用依赖配置的目的之一,这样我就不必担心 module1 如何构建的细节,例如哪个任务生成 jar 以及它生成什么工件?
我认为 gradle 能够通过遵循引用的依赖项配置的"路线"来计算出它需要执行的任务。
我在这里是否缺少一些东西,以便可以自动执行"生成公共API"任务,而无需为"createApp"任务显式声明"依赖"?
我在 Gradleware 的论坛上问了同样的问题,并从一位核心开发人员那里得到了答案,这里是链接。
基本上,问题是collect
方法返回一个新集合,但 gradle 无法知道这个新集合是从配置生成的,因此它无法推断要执行哪个任务。
解决方案不是声明对任务的依赖关系,而是声明对实际配置的依赖关系,如下所示:
task jarApp(dependsOn: configurations.generateApplication, type: Jar)