首页 > 解决方案 > 未使用 :submodule:build 语法构建的子模块的 gradle 子模块

问题描述

我有以下由gradle正确找到的项目结构:

$ ./gradlew projects
Root project 'test-project'
\--- Project ':sub-1'
     \--- Project ':sub-1:sub-2'

这让我相信我的设置是正确的。

现在,我发现以下 gradle 语法:

$ ./gradlew clean :sub-1:build

不等于:

$ cd sub-1
$ ../gradlew clean build
$ cd ..

以上是 gradle 网站上很多地方都说明的等价性。喜欢这里

运行前者,结果不正确:

> Task :sub-1:test
test.project.LibrarySuite > someLibraryMethod is always true PASSED

运行后者,结果是正确的:

> Task :sub-1:test
test.project.LibrarySuite > someLibraryMethod is always true PASSED
> Task :sub-1:sub-2:test
test.project.LibrarySuite > someLibraryMethod is always true PASSED

请帮助我了解我是否可能假设或做错了什么,或者这是否是应该向 gradle 团队提出的错误。

标签: gradle

解决方案


您将在此处找到有关 Gradle 如何处理多项目构建设置中的任务执行的详细说明:https ://docs.gradle.org/current/userguide/intro_multi_project_builds.html#sec:executing_a_multiproject_build ,特别是:

从用户的角度来看,多项目构建仍然是您可以运行的任务的集合。不同之处在于您可能想要控制执行哪个项目的任务。您在这里有两个选择:

  • 切换到您感兴趣的子项目对应的目录,然后正常执行 gradle 即可。

  • 使用任何目录中的限定任务名称,尽管这通常是从根目录完成的。例如: gradle :services:webservice:build 将构建 webservice 子项目及其依赖的任何子项目。

第一种方法类似于单项目用例,但在多项目构建的情况下,Gradle 的工作方式略有不同。命令 gradle test 将在具有该任务的任何子项目中执行测试任务,相对于当前工作目录。因此,如果您从根项目目录运行命令,您将在 api、shared、services:shared 和 services:webservice 中运行测试。如果您从 services 项目目录运行命令,您将只执行 services:shared 和 services:webservice 中的任务。

这解释了 Gradle 在您在问题中给出的两个示例中的行为方式:

  1. $ ./gradlew clean :sub-1:build

    从根项目目录:您执行 task clean,它将为当前项目和下面的每个子项目执行,然后(具有限定的任务名称)只为子项目:sub-1:build执行任务buildsub1

Gradle 执行日志:

> Task :clean UP-TO-DATE
> Task :sub-1:clean
> Task :sub-1:sub-2:clean UP-TO-DATE
> Task :sub-1:compileJava NO-SOURCE
> Task :sub-1:processResources NO-SOURCE
> Task :sub-1:classes UP-TO-DATE
> Task :sub-1:jar
> Task :sub-1:assemble
> Task :sub-1:compileTestJava NO-SOURCE
> Task :sub-1:processTestResources NO-SOURCE
> Task :sub-1:testClasses UP-TO-DATE
> Task :sub-1:test NO-SOURCE
> Task :sub-1:check UP-TO-DATE
> Task :sub-1:build

编辑以回答@Guido 的评论:这也将构建任何其他项目sub-1所依赖的,因此./gradlew clean :sub-1:build也会触发构建sub-2ifsub-1项目dependsOn sub-2

sub-1 build.gradle

dependencies {
   implementation project(":sub-1:sub-2")
}
  1. $ cd sub-1 && ../gradlew clean build

然后从sub-1子项目目录中触发任务,无需使用限定名称,因此这两个任务都将在当前项目和子项目上执行:cleanbuild

等级输出:

$ ../gradlew  clean build --console=plain
> Task :sub-1:clean
> Task :sub-1:sub-2:clean
> Task :sub-1:compileJava NO-SOURCE
> Task :sub-1:processResources NO-SOURCE
> Task :sub-1:classes UP-TO-DATE
> Task :sub-1:jar
> Task :sub-1:assemble
> Task :sub-1:compileTestJava NO-SOURCE
> Task :sub-1:processTestResources NO-SOURCE
> Task :sub-1:testClasses UP-TO-DATE
> Task :sub-1:test NO-SOURCE
> Task :sub-1:check UP-TO-DATE
> Task :sub-1:build
> Task :sub-1:sub-2:compileJava NO-SOURCE
> Task :sub-1:sub-2:processResources NO-SOURCE
> Task :sub-1:sub-2:classes UP-TO-DATE
> Task :sub-1:sub-2:jar
> Task :sub-1:sub-2:assemble
> Task :sub-1:sub-2:compileTestJava NO-SOURCE
> Task :sub-1:sub-2:processTestResources NO-SOURCE
> Task :sub-1:sub-2:testClasses UP-TO-DATE
> Task :sub-1:sub-2:test NO-SOURCE
> Task :sub-1:sub-2:check UP-TO-DATE
> Task :sub-1:sub-2:build


推荐阅读