Gradle 103: Build Life Cycle

Shivam
5 min readMar 29, 2020

--

In the first blog post, we discussed the need for a build system and features of Gradle build tool. In the second blog post, we learned about the Gradle basics like build script files and their usage. In the same blog post, we have also covered the details about property types and property files.

In this blog post, we are going to cover the Gradle build life cycle and its three phases: initialisation, configuration, and execution. Understanding the Gradle life cycle is very important to learn the working of Gradle. Let’s begin.

Initialisation

During the initialisation phase, Gradle will perform the following things:

  • At first, Gradle will create a gradle instance to represent the build, then it evaluates the init scripts and make them available in the build process.
  • Next, It will create instance of root project named rootProject and add all properties(Project + System) received from command line and gradle.properties file in it.
  • Then in the next step, to determine which projects are going to take part in the build process, Gradle creates Settings instance for the build and configures this instance using the settings.gradle or settings.gradle.kts script file. At this stage, both gradle and rootProject instances are available in the settings file.
  • Now for each specified modules/sub-project in the settings file, Gradle will create a project instance.
  • A module/sub-project specified in the settings file may or may not have its own build.gradle file, In the next step, Gradle will evaluate the build.gradle or build.gradle.kts if present against the project instance of that module.

There is a one-to-one relationship between a project and a build.gradle file. During build initialisation, Gradle assembles a project object for each project which is to participate in the build.

Configuration

As we know the Gradle build is a collection of plugins and plugin is a collection of tasks. We are going to learn both plugin and task in detail in upcoming post, till then, you can think of plugin as a class and task as a function/method in object oriented programming. A task may have actions and configurations. Configuration section contains everything written outside any build script block and task.

Gradle performs following things during the configuration phase:

  • Creates the tasks list and prepares a Directed Acyclic Graph(DAG) of all tasks of the build. This DAG is used to represent all tasks and its dependencies. Gradle will fail the build if there is any cyclic dependency between the tasks.
  • All the configuration sections of all build files and tasks will get executed against the project objects created in the Initialisation phase.

Note -only the configuration block of the task will execute in this phase and not the actions.

Execution

This phase is a final phase of build process, in this phase Gradle executes all tasks(actions in the task) as per their order based on DAG.

That’s too much theory Bro, show me some code.

Okay, let’s us create a simple example to understand the build life-cycle and we will add some log statements to track the execution flow. You can access the code used below on Github here.

  • First, Create a init.gradle.kts in the USER_HOME/.gradle/ directory. Add a simple log statement to understand when init script gets executed.
  • Now, create a gradle.properties in the project’s root directory to hold some user defined properties. Here, we will create greetMessage property and assign value “Hello World” to it. Note that, here greetMessage is called as project property, and we can also declare system properties here:
  • Now, it is time to create a settings.gradle.kts file - create settings file in the project’s root directory and add following code snippet in it, remember we can add/register all projects which are going to be part of build here. Also, both types of properties are accessible in settings file:
  • Now, create a build.gradle.kts file in the project’s root directory and add following code snippet in it, this file will be treated as the build file for root project where we can add common build script level things and shared dependencies. Note in the root directory build file both instances rootProject and project are same:
  • To understand the build life cycle better, we will create one sub-project named app (create an app directory in root directory), then create a build.gradle.kts file in the app directory and add following code snippet in it, Notethis file will be considered specific to project instance named app:

As we have created one sub-project named app inside project GradleLearning, the Gradle will create one rootProject(GradleLearning) instance and two project instances one for GradleLearning project and one for app module.

In build.gradle.kts of GradleLearning both rootProject and project instances points to same instance of GradleLearning. And in build.gradle.kts of app module rootProject instance points to GradleLearning and project instance points to itself.

That’s it, now execute command gradle build from command line in the root project directory and you will get the following output on the screen:

The directory structure of the project is as follows:

For better understanding clone this project from GitHub and tweak its file on your local machine.

--

--

Shivam

Product Engineer @ Gojek. Likes to write on Productivity, Android App Development, Kotlin, Software Engineering, etc.