Lukasz Kalnik
ProAndroidDev
Published in
4 min readJun 6, 2021

--

Image by Free-Photos on Pixabay

NOTE: As mentioned in a comment to this article, Gradle 7 offers version catalogs as incubating feature which are a much better solution to this problem!

Dependencies in Gradle composite build

In Gradle projects with multiple subprojects quite often the subprojects use common dependencies. We want to make sure that all the dependencies have the same version and save us some typing. Until recently the common way to define the versions of these dependencies was in the buildSrc subproject.

This is now discouraged because every change to buildSrc causes the whole project to be rebuilt. This doesn’t allow us to take advantage of build caching and is a big time waste. Please refer to the linked article for very convincing benchmarks comparing build times with and without buildSrc .

The aforementioned article also mentions how to solve this problem by using Gradle composite builds. For your custom Gradle plugins simply create an included build in your project and put your plugin code there.

For the dependencies list the article recommends to create a dependencies plugin and also put it in the included build. However I struggled a bit with the exact steps how to implement it, that’s why I decided to write down an easy to follow how-to guide.

I have also created an example project where I use Gradle composite build. This is the exact commit where I moved the dependency versions from buildSrc to an included build in the gradlePlugins directory.

Create a gradlePlugins subproject

In your project’s root directory create a subproject for all your plugins. I named it gradlePlugins :

You need to register this subproject in settings.gradle.kts as an includeBuild :

includeBuild("gradlePlugins")

Now this directory is registered as a regular Gradle project and we can work in it.

Configure gradlePlugins build file

Create a build.gradle.kts file inside gradlePlugins . In this file you need to configure the Kotlin DSL and set repositories (this is important as for some reason Gradle doesn’t reuse here the repositories you defined in your root project build.gradle.kts ):

Now we can migrate our dependency versions to gradlePlugins project.

Create DependenciesPlugin

Inside the gradlePlugins project create first the src/main/kotlin directory. It should be recognized by IntelliJ as a source directory and marked blue (if not make sure you have synced your last Gradle file changes).

Inside this directory create a package for your plugins. I named it like my application main package with the gradle subpackage appended at the end:

As you see I also created a class file for my DependenciesPlugin . Let’s see what we need to put there.

DependenciesPlugin source code

As you see this is just an empty Gradle plugin (the apply() method doesn’t do anything). It ‘s just a container for the companion object where I can now put all the dependency versions I want to reuse:

Next step will be to tell Gradle how we want to access this plugin in other subprojects.

Register DependenciesPlugin

To register created plugin we have to modify gradlePlugins/build.gradle.kts . We need to give this plugin an id so that we can apply it in other subprojects, and we need to tell what class is implementing this plugin’s logic (this is the class we just created).

We can do it inside the gradlePlugin closure:

Now that plugin is already known in our project, let’s make use of it.

Apply DependenciesPlugin

In my project I have dependency on the Koin library in two subprojects: androidApp and shared (it’s a Kotlin Multiplatform project).

Let’s take as an example the androidApp/build.gradle.kts . We need to do three things to use our DependenciesPlugin.koinVersion here.

  1. Apply the DependenciesPlugin inside the plugins block
  2. Import the package of the DependenciesPlugin companion object
  3. Use the DependenciesPlugin.koinVersion inside dependencies as the version number for Koin

It all looks like this:

Now we can use the DependenciesPlugin in the same way in the shared subproject and all other subprojects.

--

--

Android Developer making the Internet of Things accessible @grandcentrix