I have the following project structure
-->Starnderd Location
-->Project1
-->settings.gradle
-->build.gradle
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 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')