34

在 gradle 中,使用buildSrc文件作为顶层的目的是什么,而不仅仅是典型的 java 项目布局(src/main/java)?

如果我有一个布局

src
   main
      java

或者

buildSrc
    src
       main
          java

有什么区别(或这样做的原因)?它在多模块项目中更有用吗?即使对于一个多模块项目,我不能做类似的事情吗

proj1
  src


proj2
  src

然后只有一个顶级 build.gradle (与proj1and处于同一级别proj2),它定义了项目中的通用设置?

4

2 回答 2

62

buildSrc是一个单独的构建,其目的是构建旨在用于主构建的构建脚本中的任何任务、插件或其他类,但不必在构建之间共享。(*)它不会可以将此类类构建为主构建的一部分,因为它们必须在主构建的构建脚本甚至可以编译/评估之前就存在,并且 Gradle 在它执行任何工作之前编译/评估所有构建脚本(配置与执行阶段) .

与将所有构建代码放入构建脚本相比,buildSrc它为您提供了一种开发构建代码的方法,更像是常规代码,作为可以测试的类,导入到您的 IDE 等。这是一种保持构建脚本简单和干燥的方法,即使对于更复杂的构建。

buildSrc在多项目构建中更常见,因为较大的构建更有可能实现自己的自定义任务和插件。

随着时间的推移,它将发展成为在单个 Gradle 调用buildSrc中执行多个依赖构建的更通用的能力。

(*) 跨构建共享类是可能的,但涉及更多。特别是,您需要将类发布到存储库,并且使用构建必须从那里显式导入它们,类似于在构建之间共享生产库时。

于 2012-12-14T08:54:02.980 回答
8

在 gradle 中,使用 buildSrc 文件作为顶层文件的目的是什么,而不仅仅是典型的 java 项目布局(src/main/java)?

你绝对可以做到这一点。它被称为 gradle 中的复合构建,但您必须告诉 Gradle包含该文件夹中的任何构建。顶级文件夹的一个独特属性buildSrc是 gradle 自动将其视为包含的构建。

请注意,即使buildSrc被视为复合构建,当您运行时,它在包含的构建列表中也不可见gradle.getIncludedBuilds()。我相信原因是因为该列表是为您手动包含在settings.gradle.

为了让您也包含src/main/java为复合构建,您必须使用--include-build标志运行您的 gradle 脚本,然后是src/main/java. 对于包含的构建来说,这是一个不寻常的地方,但 gradle 不会抱怨。

然后只有一个顶级 build.gradle(与 proj1 和 proj2 处于同一级别),它定义了项目中的通用设置?

您可以拥有与您的, 和子项目build.gradle相同级别的顶层。这通常是大多数多项目项目的结构方式。proj1proj2


正如已经强调的另一个答案,该buildSrc项目的目的是创建自定义插件或任务,这些插件或任务旨在在您的构建中的不同项目之间本地共享。这并不意味着您不能在顶级build.gradle. 您可以这样做,但问题是您将无法在任何子项目中使用它。

请记住,能够在 java/groovy 中导入某些内容需要该内容存在于正确的 java/groovy 文件(或 java 9+ 的模块)中。由于您build.gradle只是一个脚本,因此简单地从中导入插件或任务并不是任意的。

正如我已经指出的,这是来自Gradle 文档,拥有目录的原因之一buildSrc是:

发现目录后,Gradle 会自动编译和测试此代码,并将其放入构建脚本的类路径中

如您所见,它buildSrc充当构建过程的扩展,因为它可以为您项目的所有构建脚本添加额外的功能。


还有几点:

  • dependencies在您的项目中声明的任何buildSrc/build.gradle内容都对项目中的其他构建脚本可见。
  • 您中的buildscriptbuildSrc/build.gradle仅对其他人可见,buildSrc/build.gradle而没有其他内容。
  • 中定义的任何插件类buildSrc 都可以在项目中的任何构建脚本中使用,并且不需要在META-INF/gradle-plugins.
  • build.gradle在主项目或任何子项目中定义的任何依赖项在buildSrc. 如果您记得这个文件夹被视为包含的构建(即外部),那么它为什么看不到包含它的项目的类路径应该是有道理的。
于 2019-07-13T03:00:28.680 回答