Gradle - Multi-Project Builds
Gradle - Multi-Project Builds
- https://docs.gradle.org/current/userguide/intro_multi_project_builds.html
- https://discuss.gradle.org/t/multiproject-within-a-multiproject/42303
For a long-lived (aka - something you’ll maintain and may grow) multi-module project, I’d suggest following the idiomatic gradle structure: https://github.com/jjohannes/idiomatic-gradle. But there’s a lot to unpack there, so it may not be the ideal thing to start with. Once you grok it though, that structure scales incredibly well, and allows you to avoid duplicating lots of configuration (via ‘precompiled script plugins’, largely in the build-logic project in that repo), and make use of build caching without having to modify things.
Different ways to organize nested projects
https://discuss.gradle.org/t/multiproject-within-a-multiproject/42303
I’m in the beginnings of converting a large baseline from ‘ant’ to ‘gradle’. I’d like to avoid restructuring as much as possible and have run into a snag with what I would call a multiproject within a multiproject. Assume I have the following:
ProjectA
|
ProjectB
ProjectC
| - ProjectD
| - ProjectE
-
ProjectA
- settings.gradle contains: include(‘ProjectB’, ‘ProjectC’) -
ProjectC
- settings.gradle contains: include(‘ProjectD’, “ProjectE’) -
In
ProjectA
:./gradlew build
-
Expectation: build ProjectB, then traverse ProjectC and build ProjectD and ProjectE
-
Result: only ProjectB is actually built
If I manually change directory to ProjectC
and ./gradlew build
, ProjectD
and ProjectE
are built.
What am I doing wrong? ProjectC
is just the example created from running gradle init
and selecting options for a Java multiproject.
In ProjectA
: ./gradlew tasks --all
Other tasks reports ProjectB:compileJava
, but there is no ProjectC:compileJava
or whatever task would traverse into ProjectD
and ProjectE
.
Solution
Which option you use in your situation is more a question of taste or isolation or organisation, both would work if you do it properly.
Option 1
- You can either have one big multi-project build and only the one
settings.gradle.kts
file in the root project. - Ensure
ProjectA/settings.gradle
hasinclude(‘ProjectB’, ‘ProjectC:ProjectD’, ‘ProjectC:ProjectE’)
.
Option 2
Use Composite Builds
See
- https://docs.gradle.org/current/userguide/composite_builds.html
- https://docs.gradle.org/current/samples/sample_composite_builds_basics.html
Approach:
- You could make
ProjectC
with subprojectsProjectD
andProjectE
an own “stand-alone” build with own settings script, that you then include as sub build instead of sub project inProjectA
. - With this approach, use
includeBuild
instead ofinclude
.
Including a standalone multi-project inside another multi-project
https://discuss.gradle.org/t/including-a-standalone-multi-project-inside-another-multi-project/22606
Hello, I’ve been bashing my head against this problem and have not found a solution here nor on SO. My situations is relatively straight forward. I have an existing multi-project build, lets call it ‘legacy’, that for various reasons cannot be modified*. I also have a new multi-project build, lets call it ‘root’, that I would like to include legacy in as a sub-project. The directory structure looks like this:
root
| - build.grade
| - settings.gradle
A
| - build.gradle
B
| - build.gradle
legacy
| -build.gradle
| settings.gradle
C
| - build.gradle
D
| - build.gradle
Important file contents:
- C/build.gradle = …compile project(’:D’) …
- legacy/settings.gradle = include ‘C’ include ‘D’
No matter what I configure for root/settings.gradle I either get Project with path ':D' could not be found in project ':B:legacy:C'
or the whole legacy tree is ignored
Is there any way to make the legacy branch and root play nicely?
Note: Legacy cannot be drastically changed, but if there is a simple solution that would allow legacy to continue operating as a standalone project (it is currently a git submodule of root) then that could be entertained
Answer:
What you’re describing could be accomplished with a composite build. https://docs.gradle.org/current/userguide/composite_builds.html
This is the only way if you want the legacy build to remain completely untouched and standalone. You can reference dependencies from the legacy build in the root build by using external dependencies that are automatically substituted for project dependencies.