# Executing Multi-Project Builds

version 7.6.4

Only the smallest of projects has a single build file and source tree, unless it happens to be a massive, monolithic application. It’s often much easier to digest and understand a project that has been split into smaller, inter-dependent modules. The word “inter-dependent” is important, though, and is why you typically want to link the modules together through a single build.

Gradle supports this scenario through multi-project builds.

For details about authoring multi-project builds, consult the Authoring Multi-Project Builds section of the user manual.

## Identifying project structure

To identify the project structure, you can use `gradle projects` command. As an example, let’s use a multi-project build with the following structure:

    > gradle -q projects

    ------------------------------------------------------------
    Root project 'multiproject'
    ------------------------------------------------------------

    Root project 'multiproject'
    +--- Project ':api'
    +--- Project ':services'
    |    +--- Project ':services:shared'
    |    \--- Project ':services:webservice'
    \--- Project ':shared'

    To see a list of the tasks of a project, run gradle <project-path>:tasks
    For example, try running gradle :api:tasks

From a user’s perspective, multi-project builds are still collections of tasks you can run. The difference is that you may want to control which project’s tasks get executed. The following sections will cover the two options you have for executing tasks in a multi-project build.

## Executing tasks by name

The command `gradle test` will execute the `test` task in any subprojects, relative to the current working directory, that have that task. If you run the command from the root project directory, you’ll run `test` in api, shared, services:shared and services:webservice. If you run the command from the services project directory, you’ll only execute the task in services:shared and services:webservice.

The basic rule behind Gradle’s behavior is: execute all tasks down the hierarchy which have this name. Only complain if there is no such task found in any of the subprojects traversed.

| Some tasks selectors, like `help` or `dependencies`, will only run the task on the project they are invoked on and not on all the subprojects. The main motivation for this is that these tasks print out information that would be hard to process if it combined the information from all projects.

Gradle looks down the hierarchy, starting with the current dir, for tasks with the given name and executes them. One thing is very important to note. Gradle always evaluates every project of the multi-project build and creates all existing task objects. Then, according to the task name arguments and the current directory, Gradle filters the tasks which should be executed. Because of Gradle’s cross project configuration, every project has to be evaluated before any task gets executed.

When you’re using the Gradle wrapper, executing a task for a specific subproject by running Gradle from the subproject’s directory doesn’t work well because you have to specify the path to the wrapper script if you’re not in the project root. For example, if want to run `build` task for the webservice subproject and you’re in the webservice subproject directory, you would have to run `../../gradlew build`. The next section shows how this can be achieved directly from the project’s root directory.

## Executing tasks by fully qualified name

You can use a task’s fully qualified name to execute a specific task in a specific subproject. For example: `gradle :services:webservice:build` will run the `build` task of the webservice subproject. The fully qualified name of a task is simply its project path plus the task name.

A project path has the following pattern: it starts with an optional colon, which denotes the root project. The root project is the only project in a path that is not specified by its name. The rest of a project path is a colon-separated sequence of project names, where the next project is a subproject of the previous project. You can see the project paths when running `gradle projects` as shown in identifying project structure section.

This approach works for any task, so if you want to know what tasks are in a particular subproject, just use the `tasks` task, e.g. `gradle :services:webservice:tasks`.

Regardless of which technique you use to execute tasks, Gradle will take care of building any subprojects that the target depends on. You don’t have to worry about the inter-project dependencies yourself. If you’re interested in how this is configured, you can read about writing multi-project builds later in the user manual.

That’s all you really need to know about multi-project builds as a build user. You can now identify whether a build is a multi-project one and you can discover its structure. And finally, you can execute tasks within specific subprojects.

## Multi-Project Building and Testing

The `build` task of the Java plugin is typically used to compile, test, and perform code style checks (if the CodeQuality plugin is used) of a single project. In multi-project builds you may often want to do all of these tasks across a range of projects. The `buildNeeded` and `buildDependents` tasks can help with this.

In this example, the `:services:person-service` project depends on both the `:api` and `:shared` projects. The `:api` project also depends on the `:shared` project.

Assume you are working on a single project, the `:api` project. You have been making changes, but have not built the entire project since performing a clean. You want to build any necessary supporting jars, but only perform code quality and unit tests on the project you have changed. The `build` task does this.

Example 1. Build and Test Single Project
Output of `gradle :api:build`

    > gradle :api:build
    > Task :shared:compileJava
    > Task :shared:processResources
    > Task :shared:classes
    > Task :shared:jar
    > Task :api:compileJava
    > Task :api:processResources
    > Task :api:classes
    > Task :api:jar
    > Task :api:assemble
    > Task :api:compileTestJava
    > Task :api:processTestResources
    > Task :api:testClasses
    > Task :api:test
    > Task :api:check
    > Task :api:build

    BUILD SUCCESSFUL in 0s

If you have just gotten the latest version of source from your version control system which included changes in other projects that `:api` depends on, you might want to not only build all the projects you depend on, but test them as well. The `buildNeeded` task also tests all the projects from the project dependencies of the testRuntime configuration.

Example 2. Build and Test Depended On Projects
Output of `gradle :api:buildNeeded`

    > gradle :api:buildNeeded
    > Task :shared:compileJava
    > Task :shared:processResources
    > Task :shared:classes
    > Task :shared:jar
    > Task :api:compileJava
    > Task :api:processResources
    > Task :api:classes
    > Task :api:jar
    > Task :api:assemble
    > Task :api:compileTestJava
    > Task :api:processTestResources
    > Task :api:testClasses
    > Task :api:test
    > Task :api:check
    > Task :api:build
    > Task :shared:assemble
    > Task :shared:compileTestJava
    > Task :shared:processTestResources
    > Task :shared:testClasses
    > Task :shared:test
    > Task :shared:check
    > Task :shared:build
    > Task :shared:buildNeeded
    > Task :api:buildNeeded

    BUILD SUCCESSFUL in 0s

You also might want to refactor some part of the `:api` project that is used in other projects. If you make these types of changes, it is not sufficient to test just the `:api` project, you also need to test all projects that depend on the `:api` project. The `buildDependents` task also tests all the projects that have a project dependency (in the testRuntime configuration) on the specified project.

Example 3. Build and Test Dependent Projects
Output of `gradle :api:buildDependents`

    > gradle :api:buildDependents
    > Task :shared:compileJava
    > Task :shared:processResources
    > Task :shared:classes
    > Task :shared:jar
    > Task :api:compileJava
    > Task :api:processResources
    > Task :api:classes
    > Task :api:jar
    > Task :api:assemble
    > Task :api:compileTestJava
    > Task :api:processTestResources
    > Task :api:testClasses
    > Task :api:test
    > Task :api:check
    > Task :api:build
    > Task :services:person-service:compileJava
    > Task :services:person-service:processResources
    > Task :services:person-service:classes
    > Task :services:person-service:jar
    > Task :services:person-service:assemble
    > Task :services:person-service:compileTestJava
    > Task :services:person-service:processTestResources
    > Task :services:person-service:testClasses
    > Task :services:person-service:test
    > Task :services:person-service:check
    > Task :services:person-service:build
    > Task :services:person-service:buildDependents
    > Task :api:buildDependents

    BUILD SUCCESSFUL in 0s

Finally, you may want to build and test everything in all projects. Any task you run in the root project folder will cause that same named task to be run on all the children. So you can just run `gradle build` to build and test all projects.