Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple settings gradle files for multiple projects building

I have the following project structure

-->Starnderd Location         -->Project1             -->settings.gradle             -->build.gradle            -->Subproject11               -->build.gradle            -->Subproject12               -->build.gradle         -->Project2             -->settings.gradle             -->build.gradle            -->Subproject21               -->build.gradle            -->Subproject22               -->build.gradle         -->build.gradle         -->settings.gradle 

Idea of above project structure is that we have multiple projects which contains subprojects, each project can have dependencies to other projects. Also subprojects inside the project can have dependencies to other subprojects within the same project. Projects will be specified in the settings.gradle in the root. Also settings.gradle inside each project will say what are the subprojects of that particular project.

My settings.gradle in the root would looks like

include 'Project1',          'Project2' 

and Project1 settings.gradle will looks like

include 'SubProject11'          'SubProject12' 

other dependency orders are defined in the respective build.gradle files If I rand gradle clean build install inside the root location(Standar location) it doesn't seems to use configurations in the Project level settings.gradle file.

What I'm doing here wrong?

like image 716
Isuru Avatar asked Aug 28 '12 06:08

Isuru


People also ask

Can you have multiple build Gradle files?

gradle for one project? Yes. You can have multiple build files in one project.

Why are there multiple build Gradle files?

By default, the project-level Gradle file uses buildscript to define the Gradle repositories and dependencies. This allows different projects to use different Gradle versions.


1 Answers

I was able to solve this problem in a relatively clean way. Improvements are certainly welcome!

Although Gradle does not support multiple settings.gradle scripts out of the box, it is possible to create individual sub-projects each with their own settings.gradle file. Let's say you have multi-project A that depends on multi-project B, each with their own sub-projects. Your directory structure might look like:

A - settings.gradle - foo - faz \ B   - settings.gradle   - bar   - bap 

Out of the box, Gradle expects A/settings.gradle to look something like this:

include ':foo', ':faz', 'B:bar', 'B:bap' 

The problem with this is that every time B adds a new project, A/settings.gradle must also change even if the new project is only used by B. To avoid this situation, you could try to apply B/settings.gradle in A/settings.gradle instead of adding redundant declarations:

apply from: 'B/settings.gradle' include ':foo', ':faz' 

If you try this, you'll find that Gradle fails because it generates the wrong projectDir for :bar and :bap. It mistakenly assumes that B's includes are relative to settingsDir which happens to be A/ when Gradle is invoked from that project root. To fix this you can add another script such as B/settings-parent.gradle (the exact name is not significant):

apply from: 'settings.gradle'  def updateProjectPaths(Set<ProjectDescriptor> projects) {     projects.each { ProjectDescriptor project ->         String relativeProjectPath = project.projectDir.path.replace(settingsDir.path, "")         project.projectDir = new File("B/$relativeProjectPath")         // Recursively update paths for all children         updateProjectPaths(project.children)     } }  updateProjectPaths(rootProject.children) 

This strips settingsDir.path and prefixes the path with B/. This can be extended to multiple layers of settings[-parent].gradle files by having each layer add itself onto the path. Now you will apply this script to A/settings.gradle:

apply from: 'B/settings-parent.gradle' include ':foo', ':faz' 

With this scheme, new B projects do not unnecessarily break A/settings.gradle and all projects can be used without explicitly referencing the B sub-project. For example, if ':foo' wanted to use 'B:bap', it may simply declare:

compile project(':bap') 
like image 168
James Wald Avatar answered Sep 23 '22 01:09

James Wald