Gradle Multi-Project Builds TODEPLETE
External
- https://docs.gradle.org/current/userguide/multi_project_builds.html
- https://guides.gradle.org/creating-multi-project-builds/
- https://docs.gradle.org/current/userguide/tutorial_java_projects.html#sec:examples
- https://docs.gradle.org/current/userguide/build_lifecycle.html#sec:multi_project_builds
Internal
Overview
A multi-project build is a build where more than one project is built during a single execution run. Multi-project builds are always represented by a tree of Project instances with a single root. Usually, there is a direct mapping between Project tree elements and directories on the file system where the project configuration and files are maintained, but this behavior is configurable.
A project has a name, and a fully qualified path which uniquely identifies it in the hierarchy.
The project hierarchy is described in the settings.gradle file of the root project. This file is required for multi-project builds. The root project build file can be used to configure as much commonality as possible in the allprojects{...} block, leaving sub-projects to customize only what is specific for them.
A sub-project is a project that is part of a multi-project hierarchy, and it is not the root project. There is a subprojects{...} script block that can be used to provide configuration for sub-projects only. Sub-project may have their own settings.gradle and build.gradle configuration files, though they are not required: the behavior of sub-project can be configured in the root project's configuration files.
A multi-project build can have a flat or hierarchical layout. A hierarchical layout allows for multiple level of projects. The project path is assumed to be equal to the relative physical file system path. "include" method argument "project1:child2" is mapped onto a "project1/child2" directory, relative to the root directory of the project. "project1:child2:subchild3" implies three projects: "project1", "project1:child2" and "project1:child2:subchild3". A flat layout is is introduced by the "includeFlat" method, which takes directory names are argument. These directories need to exist as samplings of the root project directory.
The component project and the associated structure of a multi-project build can be displayed with:
gradle projects
It is possible to run any task in any sub-project with the following syntax:
gradle :<sub-project-path>:<task-name>
If you were to spend a lot of time working in one sub-project, changing to that directory and running the build from there is normal. Running a task from that subdirectory will trigger all necessary actions form its dependency projects, thanks to the Gradle task graph implementation.
Inter-Project Dependencies
Sub-projects do not automatically expose their artifacts to other sub-projects of the same multi-build project. The dependencies between sub-projects must be declared explicitly in the dependencies{...} script block of the dependent sub-project. For example, if classes that belong to "subproject-B" depend on classes in "subproject-A", then subproject-B build.gradle must contain:
dependencies {
...
implementation project(':subproject-A')
...
}
Selective Project Configuration
Selective project configuration can be achieved via project filtering, by invoking Project's configure(...) method with a predicate closure that selects specific sub-projects, as shown in the example below. The method is executed in the configuration phase, in the order in which it was specified in build.gradle: if other script blocks are declared under the configure(...) method invocation, they will be executed after it, possibly overwriting configuration introduced by configure(...).
configure(subprojects.findAll {it.name == 'subproject-A' || it.name == 'subproject-B'} ) {
println "configuring sub-project $it"
apply plugin : ...
dependencies {
...
}
}