我对 gradle 和 groovy 都很陌生。
问题
我有一个非常简单的多项目结构,如下所示:
Root project 'gradle_test'
+--- Project ':sub1'
\--- Project ':sub2'
这就是 sub1 项目的“build.grade”文件的样子:
// build.gradle of sub1 project
task testConfiguration {
println project(':sub2').configurations.sub2FooConfiguration
}
最后,这是 sub2 项目的“build.grade”文件:
// build.gradle of sub2 project
configurations {
sub2FooConfiguration
}
非常少。现在,如果我运行 gradle :sub1:testConfiguration
,我收到以下错误:
A problem occurred evaluating project ':sub1'.
> Could not find property 'sub2FooConfiguration' on configuration container.
但是,如果 sub1 项目中的 testConfiguration
任务修改如下,则一切正常:
// notice the "<<" (I believe this is calling the 'doLast' method on the task instance)
task testConfiguration << {
println project(':sub2').configurations.sub2FooConfiguration
}
问题
我认为“testConfiguration”任务的两个版本之间的区别在于,在第一个实例中,将配置闭包
传递给任务,而在修改后的版本中,将“正常”闭包传递给该任务被传递给“doLast”方法。
那么,首先我的假设正确吗?
其次,为什么我一开始就无法访问“sub2”项目?
最后,是否可以在第一个实例中(即在配置闭包中)访问“sub2”项目?
[更新]进一步的问题
鉴于“Invisible Arrow”提供的已接受答案,我想问一个有关引用另一个项目配置的最佳实践的进一步问题(即 sub1 中的任务需要使用 sub2 项目生成的存档) 。
我应该声明两个项目之间的评估依赖关系吗?
或者我应该只在执行时引用 sub2 的配置(例如在 doLast() 中)?
或者,我应该在两个项目之间创建依赖项配置吗?
最佳答案
是的,两者之间是有区别的。 构建基本上分为 3 个阶段,即初始化、配置和执行。这在Build Lifecycle下有详细描述。 Gradle 文档中的章节。
在您的情况下,第一个实例属于配置阶段,无论任务是否执行,都会评估该阶段。这意味着当您开始构建时,闭包中的所有语句都会被执行。
task testConfiguration {
// This always runs during a build,
// irrespective of whether the task is executed or not
println project(':sub2').configurations.sub2FooConfiguration
}
第二个实例属于执行阶段。请注意<<
是 doLast
的简写,并且在执行任务时调用此闭包。
task testConfiguration << {
// Called during actual execution of the task,
// and called only if the task was scheduled to be executed.
// Note that Configuration phase for both projects are complete at this point,
// which is why :sub1 is able to access :sub2's configurations.sub2FooConfiguration
println project(':sub2').configurations.sub2FooConfiguration
}
现在来看看为什么第一个实例会出现错误。这是因为 sub2
的配置阶段项目尚未评估。因此sub2FooConfiguration
尚未创建。
sub1
之间不存在显式求值依赖关系。和sub2
。在你的情况下,sub1
需求sub2
作为评估依赖项,因此我们可以在 sub1
中添加该依赖项的build.gradle
在任务声明之前,如下:
evaluationDependsOn(':sub2')
task testConfiguration {
println project(':sub2').configurations.sub2FooConfiguration
}
这将确保 sub2
总是在 sub1
之前评估(评估意味着项目的配置阶段)。 sub1
现在可以访问configurations.sub2FooConfiguration
在任务声明结束时。 Multi-project Builds对此进行了详细解释。章节。
在第二个实例中,configurations.sub2FooConfiguration
可以访问,因为调用是在任务的执行 block 中(在两个项目的配置阶段之后)。
PS:请注意,如果您颠倒了项目名称,那么第一个实例可能实际上可以工作,因为如果没有显式依赖项,Gradle 会按字母顺序配置项目。但是,当然,您永远不应该依赖于此,并确保显式声明项目之间的依赖关系。
关于groovy - 等级 : Can't access configuration defined in one project from another project,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27881883/