Is it possible to set up a gradle project with more than 2 levels?
Asked Answered
P

4

37

We have been using gradle for about a year and have been somewhat successful with it. A number of features are still a little opaque, but we are getting there. I am not sure I am going about solving the problem correctly, so I will go ahead and ask the question:

All the examples that I have seen for gradle have a root project and one level of sub-projects. For a number of reasons, we would like to consolidate our git projects. All of these are gradle projects, some of which have gradle sub-projects. What we want to end up with is essentially a multi-level gradle structure. We do not want to alter the gradle setup for all those projects and instead would like to have a top level gradle that manages all the projects and corresponding subprojects. My first attempt showed that I cannot have a controlling build.gradle that orchestrates all of the projects and subprojects. Am I doing something wrong? Am I following and inherently broken paradigm?

Here is a sample structure for what I want to do:

Top Project
  build.gradle
  Project
    build.gradle
    Sub Project
      build.gradle
      src
    Sub Project
      ...
  Project
    ...

Thank you and I hope I did not miss some obvious explanation in the documentation.

Parkins answered 8/3, 2013 at 16:42 Comment(2)
After doing some more reading, it looks like what I should do is use the GradleBuild task: gradle.org/docs/current/userguide/…Parkins
GradleBuild is the best you can do today. The real deal (aggregating builds) is a planned feature.Batista
B
23

I would simply put the following in TopProject/settings.gradle:

include 'Project1:SubProject1'
include 'Project1:SubProject2'
include 'Project2:SubProject1'
...

The only change required to the projects you currently have is to remove settings.gradle files from them as you can only have one setting.gradle file per project structure.

Basil answered 8/3, 2013 at 18:54 Comment(3)
Well, it may be that our builds are not ideally set, but that did not work quite right. GradleBuild seems to be doing the trick along with some dynamic task generation.Parkins
This will lead to two level 'flattened' project structure, NOT to a multilevel structure. If you open this in IDE you will see all projects listed instead of grouped.Lally
One should add that dependencies to such nested projectes have the form implementation project(":Project1:SubProject1")Carleton
G
14

I had a similar problem. The simplest solution was to configure gradle by adding projects in the $root/settings.gradle file similar to the Erdi's answer. However, I managed to automatically add all subprojects. The logic will simply go through my directory structure and find all directories that contain build.gradle and add them as subprojects.

Here is how to do it:

  • Make sure you don't have any other settings.gradle but the root one
  • The content of the root settings.gradle file should be:
fileTree('.') {
  include '**/build.gradle'
  exclude 'build.gradle' // Exclude the root build file.
}.collect { relativePath(it.parent).replace(File.separator, ':') }
 .each { include(it) }

I hope this helps.

Gowrie answered 6/12, 2015 at 19:47 Comment(1)
A follow-up for anyone implementing this method, Gradle actually tries to run tasks in the parent sub-directory. Even when it only has sub-folders for sub-projects.Handclap
M
3

Kotlin version of settings.gradle.kts

fileTree(".") {
    include("**/build.gradle")
    include("**/build.gradle.kts")
    exclude("buildSrc/**")
    exclude("build.gradle.kts")
}.map {
    relativePath(it.parent)
        .replace(File.separator, ":")
}.forEach {
    include(it)
}

Instead of adding it manually like this (like Intellij Idea suggests):

include("modules:core")
findProject(":modules:core")?.name = "core"
Machmeter answered 15/2, 2020 at 15:32 Comment(0)
P
0

This is working quite well:

ext{
  buildPrefix = "build"
  allProjects = ["P1", "P2"]
}

def createTasks(String prefix) {
  def newTasks = allProjects.each {
    def pName ->
      def tName = "$prefix$pName"
      tasks.add(name: tName, type: GradleBuild) {
        dir = pName
        tasks = [ prefix ]
      }
  }
}

createTasks(buildPrefix)

ext {
  buildTasks = tasks.findAll{ t -> t.name.startsWith(buildPrefix) }
}

task build(dependsOn: buildTasks) {}

I can just add the other tasks that I want to expose at the top level.

Thanks for the pointers.

Parkins answered 8/3, 2013 at 19:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.