In gradle, what is the purpose of using a buildSrc file as a top
level, as opposed to just a typical java project layout
(src/main/java)?
You can definitely do this. It is known as a composite build in gradle, but you have to tell Gradle to include any builds from that folder. A unique property of a top-level buildSrc
folder is that gradle automatically treats it as an included build.
Note that even though buildSrc
is treated as a composite build, it is not visible in the list of included builds when you run gradle.getIncludedBuilds()
. I believe the reason is because the list is reserved for builds which you manually included in your settings.gradle
.
For you to also include src/main/java
as a composite build, you have to run your gradle script using the --include-build
flag, followed by the path to src/main/java
. This is an unusual place for an included build, but gradle won't complain.
And then just have a top level build.gradle (at the same level as
proj1 and proj2) that defines common settings across the projects?
You CAN have a top-level build.gradle
at the same level as your proj1
, and proj2
sub-projects. This is typically how most multi-project projects are structured.
As another answer already highlighted, the purpose of the buildSrc
project is to create custom plugins or tasks which is meant to be shared locally among the different projects in your build. This is not to imply that you cannot create those custom tasks and plugins in your top-level build.gradle
. You can do it this way, but the problem is that you will not be able to use it in any of your sub-projects.
Remember that being able to import something in java/groovy requires that thing to exist in a proper java/groovy file (or module for java 9+). Seeing as your build.gradle
is simply a script, it is not arbitrary to simply import a plugin or task from it.
As I have already pointed out and this is from the Gradle docs, one of the reasons for having a buildSrc
directory is:
Upon discovery of the directory, Gradle automatically compiles and
tests this code and puts it in the classpath of your build script.
As you can see, the buildSrc
acts as an extension of your build process in that it can add additional functionality to all your project's build scripts.
A few more points:
- Any
dependencies
declared in your buildSrc/build.gradle
is visible to the rest of the build scripts in your project.
- The
buildscript
block in your buildSrc/build.gradle
is only visible to buildSrc/build.gradle
and nothing else.
- Any plugin class defined in
buildSrc
can be used in any build script in your project, and does not need to be declared in a META-INF/gradle-plugins
.
- Any dependencies defined in your main
build.gradle
or any of your subprojects is not visible in buildSrc
. If you remember that this folder is treated as an included build (i.e. external), it should make sense why it cannot see the classpath of the project that includes it.