// Copyright 2020 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
[[multi_project_builds]]
= Structuring and Building a Software Component with Gradle

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.adoc#structure_large_projects,structuring software products with Gradle>>

[[sec:creating_multi_project_builds]]
== 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`:

.Basic multi-project build
====
[.multi-language-sample]
=====
.Project layout
[source, groovy]
----
.
├── app
│   ...
│   └── build.gradle
└── settings.gradle
----
=====
[.multi-language-sample]
=====
.Project layout
[source, kotlin]
----
.
├── app
│   ...
│   └── build.gradle.kts
└── settings.gradle.kts
----
=====
====

This is the recommended project structure for starting any Gradle project.
The <<build_init_plugin#build_init_plugin,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.
====
include::sample[dir="snippets/multiproject/basic-multiproject/groovy",files="settings.gradle[]"]
include::sample[dir="snippets/multiproject/basic-multiproject/kotlin",files="settings.gradle.kts[]"]
====

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
include::{snippetsPath}/multiproject/basic-multiproject/tests/projects.out[]
----

Let's say the `app` subproject is a Java application by applying the <<application_plugin#application_plugin,application plugin>> and configuring the main class:
====
include::sample[dir="snippets/multiproject/basic-multiproject/groovy",files="app/build.gradle[]"]
include::sample[dir="snippets/multiproject/basic-multiproject/kotlin",files="app/build.gradle.kts[]"]
.app/src/main/java/com/example/Hello.java
[source, java]
----
include::{snippetsPath}/multiproject/basic-multiproject/groovy/app/src/main/java/com/example/Hello.java[]
----
====

We can then run the application by executing the `run` task from the <<application_plugin#application_plugin,application plugin>>.
----
> gradle -q run
include::{snippetsPath}/multiproject/basic-multiproject/tests/run.out[]
----

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

[[sec:adding_subprojects]]
== 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:
====
include::sample[dir="snippets/multiproject/multiple-subprojects/groovy",files="settings.gradle[]"]
include::sample[dir="snippets/multiproject/multiple-subprojects/kotlin",files="settings.gradle.kts[]"]
====

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

.Multi-project build with two subprojects
====
[.multi-language-sample]
=====
.Project layout
[source, groovy]
----
.
├── app
│   ...
│   └── build.gradle
├── lib
│   ...
│   └── build.gradle
└── settings.gradle
----
=====
[.multi-language-sample]
=====
.Project layout
[source, kotlin]
----
.
├── app
│   ...
│   └── build.gradle.kts
├── lib
│   ...
│   └── build.gradle.kts
└── settings.gradle.kts
----
=====
====


Next, will explore how build logic can be <<sharing_build_logic_between_subprojects#sharing_build_logic_between_subprojects,shared between subprojects>>
and how subprojects can <<declaring_dependencies_between_subprojects#declaring_dependencies_between_subprojects,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 <<command_line_interface.adoc#sec:name_abbreviation,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).
