# Structuring and Building a Software Component with Gradle

version 7.3

If you are building a software of a certain size with Gradle, you have two basic structuring mechanisms. First, this chapter describes how to structure your software project using a Gradle multi-project. In this documentation, we consider this to be a single software component which is structured internally. Second, you may regard your software as a software product that is composed of multiple software components where each component is represented by a separate Gradle build. This is described in detail in the chapter on structuring software products with Gradle

## Creating a multi-project build

A multi-project build in Gradle consists of one root project, and one or more subprojects.

A basic multi-project build contains a root project and a single subproject. This is a structure of a multi-project build that contains a single subproject called `app`:

Example 1. Basic multi-project build
Project layout

    .
    ├── app
    │   ...
    │   └── build.gradle
    └── settings.gradle

Project layout

    .
    ├── app
    │   ...
    │   └── build.gradle.kts
    └── settings.gradle.kts

This is the recommended project structure for starting any Gradle project. The build init plugin also generates skeleton projects that follow this structure - a root project with a single subproject.

Note that the root project does not have a Gradle build file, only a settings file that defines the subprojects to include.

settings.gradle

    rootProject.name = 'basic-multiproject'
    include 'app'

settings.gradle.kts

    rootProject.name = "basic-multiproject"
    include("app")

In this case, Gradle will look for a build file in the `app` directory.

We can view the structure of a multi-project build by running the `gradle projects` command.

    > gradle -q projects

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

    Root project 'basic-multiproject'
    \--- Project ':app'

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

Let’s say the `app` subproject is a Java application by applying the application plugin and configuring the main class:

app/build.gradle

    plugins {
        id 'application'
    }

    application {
        mainClass = 'com.example.Hello'
    }

app/build.gradle.kts

    plugins {
        id("application")
    }

    application {
        mainClass.set("com.example.Hello")
    }

app/src/main/java/com/example/Hello.java

    package com.example;

    public class Hello {
        public static void main(String[] args) {
            System.out.println("Hello, world!");
        }
    }

We can then run the application by executing the `run` task from the application plugin.

    > gradle -q run
    Hello, world!

And that’s how simple it is to create a basic multi-project build.

## Adding subprojects

Let’s say we want to add another subproject called `lib` to the previously created project. All we need to do is add another `include` statement in the root settings file:

settings.gradle

    rootProject.name = 'basic-multiproject'
    include 'app'
    include 'lib'

settings.gradle.kts

    rootProject.name = "basic-multiproject"
    include("app")
    include("lib")

Gradle will then look for the build file for the new subproject in the `lib/` subdirectory of the project:

Example 2. Multi-project build with two subprojects
Project layout

    .
    ├── app
    │   ...
    │   └── build.gradle
    ├── lib
    │   ...
    │   └── build.gradle
    └── settings.gradle

Project layout

    .
    ├── app
    │   ...
    │   └── build.gradle.kts
    ├── lib
    │   ...
    │   └── build.gradle.kts
    └── settings.gradle.kts

Next, will explore how build logic can be shared between subprojects and how subprojects can depend on one another.

## Naming recommendations

As your project grows, naming and consistency gets increasingly more important. To keep your builds maintainable, we recommend the following:

1. Keep default project names for subprojects: It is possible to configure custom project names in the settings file. However, it’s an unnecessary extra effort for the developers to keep track of which project belongs to what folders.

2. Use kebab case formatting for all project names: A kebab case formatting is when all letters lowercase, words separated with a dash (‘-’) character (e.g.`kebab-case-formatting`). This is already the de-facto pattern for many large projects. Besides, Gradle supports name abbreviation for kebab case names.

3. Define the root project name in the settings file: The ´rootProject.name´ effectively assigns a name to the build as a whole, which is used in reports like build scans. If the root project name is not set, the name will be the container directory name, which can be unstable (i.e. you can check out your project to any directory).