Gradle is a build tool mainly used for Kotlin, Java and other JVM languages. The best way to use it is with the IntelliJ IDEA IDE.

It also supports other languages like Swift and C/C++

Extending Gradle

Tasks

  • Copy
  • Exec
  • Zip
  • Delete

Gradle Docs — Task types

Plugins

Script plugin Defined in build.gradle.kts Local plugin
Precompiled script plugin Defined in Convention plugin Local plugin
Binary plugin Defined in Project Standard

Gradle Docs — Types of Plugins

Plugin Development Build Script

build.gradle.kts
plugins {
1 collapsed line
`java`

Apply a JVM language plugin

`java-gradle-plugin`

Apply the Gradle plugin development plugin
Gradle Docs — Gradle Plugin Development Plugin

}
gradlePlugin {

The Gradle plugin development plugin can be configured here
Gradle Docs — Gradle Plugin Development Extension

3 collapsed lines
website = "https://github.com/OWNER/REPO"
vcsUrl = "https://github.com/OWNER/REPO.git"
plugins {
val pluginName by registering {
id = "me.username.plugin-name"
implementationClass = "me.username.PluginName"
3 collapsed lines
displayName = "Plugin Name"
description = "Describe the plugin"
tags = setOf()
}
}
}

Gradle Docs — Gradle Plugin Development Plugin · Usage

Plugin class

GradlePlugin.kt
package me.username.plugin
import org.gradle.api.Plugin
class GradlePlugin: Plugin<Project> {
override fun apply(project: Project) {
val extension = project.extensions.create(
"extensionName",
GradleExtension::class.java
)
}
}
build.gradle.kts
plugins {
apply("me.username.plugin-name")
}

Extension class

GradleExtension.kt
package me.username.plugin
import org.gradle.api.Action
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.model.ObjectFactory
import org.gradle.api.provider.Property
import org.gradle.api.provider.SetProperty
import org.gradle.api.provider.MapProperty
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.InputDirectory
import org.gradle.api.tasks.InputFile
import org.gradle.api.tasks.Nested
import org.gradle.api.tasks.Optional
import javax.inject.Inject
abstract class GradleExtension {
@get:Input
abstract val property: Property<String>
@get:Input
@get:Optional
abstract val optionalProperty: Property<String>
@get:Input
abstract val propertySet: SetProperty<String>
@get:Input
abstract val propertyMap: MapProperty<String, String>
// files
@get:InputFile
abstract val fileProperty: RegularFileProperty
@get:InputDirectory
abstract val dirProperty: DirectoryProperty
}
abstract class AdvancedGradleExtension
@Inject constructor(private val objects: ObjectFactory) {
// nested properties
@get:Nested
abstract val nestedProperties: NestedProperties
fun nestedProperties(action: Action<in NestedProperties>) {
action.execute(nestedProperties)
}
// nested properties list
@get:Input
val nestedPropertiesList = objects.setProperty(NestedPropertyItem::class.java)
fun nestedPropertiesList(action: Action<NestedPropertyList>) {
val container = objects.newInstance(NestedPropertyList::class.java)
action.execute(container)
nestedPropertiesList.addAll(container.items)
}
}
abstract class NestedPropertyList
@Inject constructor(private val objects: ObjectFactory) {
val items = mutableSetOf<NestedPropertyItem>()
fun property(action: Action<NestedPropertyItem>) {
val license = objects.newInstance(NestedPropertyItem::class.java)
action.execute(license)
items.add(license)
}
}
abstract class NestedPropertyItem {
@get:Input
abstract val property: Property<String>
}
abstract class NestedProperties {
@get:Input
abstract val property: Property<String>
}

Gradle Docs — Annotating inputs and outputs
Gradle Docs — Property convention

Task class


  • plugins

    • init/config/exec
    • local/published
    • bin/script
    • tasks
    • property/providers
    • extensions
  • projct templates

    • gradle init
    • intellij

https://www.jetbrains.com/help/idea/gradle-settings.html

Build Lifecycle

  • Initialization (evaluate settings.gradle.kts)
  • Configuration (evaluate **/gradle.build.kts)
  • Execution (execute tasks) (doFirst, doLast)

Task

  • Project
    • build — build directory configurable
    • gradle
      • wrapper
      • libs.versions.toml
    • src/sourceSet — source directory (default src/main and src/test) configurable
      • source — source code directories (per language java, kotlin …)
      • resources — resource files directory (configs, data, assets, scripts)
    • settings.gradle.kts — project configuration script (name & modules)
    • build.gradle.kts — build configuration script

Minimal project structure

  • Project
    • build — build directory configurable
    • src/sourceSet — source directory (default src/main and src/test) configurable
      • source — source code directories (per language java, kotlin …)
      • resources — resource files directory (configs, data, assets, scripts)
    • settings.gradle.kts — project configuration script (name & modules)
    • build.gradle.kts — build configuration script

Minimal Gradle Wrapper project structure

  • Project

    • Gradle Wrapper
    • gradle/wrapper
      • gradle-wrapper.jar — downloader
      • gradle-wrapper.properties — version
    • gradlew — executable for Linux/MacOS
    • gradlew.bat — executable for Windows

    • Project
    • build — build directory
    • src — source directory
      • sourceSet
        • source
        • resources
    • settings.gradle.kts — project configuration script (name & modules)
    • build.gradle.kts — build configuration script

Complete project structure

  • gradle
    • wrapper Gradle Wrapper
      • gradle-wrapper.jar Gradle Wrapper downloader
      • gradle-wrapper.properties Gradle Wrapper version
    • libs.versions.toml
  • build
  • src
    • sourceSet
      • source
      • resources
  • gradle.properties
  • settings.gradle.kts
  • build.gradle.kts
  • gradlew Gradle Wrapper executable for Linux/MacOS
  • gradlew.bat Gradle Wrapper executable for Windows

Tasks


Gradle Build Script

Build script.

build.gradle.kts

/** Plugins list */
plugins { ... }
/** */
repositories {
/* common repositories */
mavenCentral() // https://repo.maven.apache.org/maven2
...
}
/** Dependency list */
dependencies {
"group:name:version" // module
// version:
// 0.0 <- >= equal or greater
// 0.0!! <- == strictly
// 0.+ <-
// 0.0-SNAPSHOT <-
project(":module")
// dependency configurations
implementation(...)
api(...)
runtimeOnly(...)
compileOnly(...)
}
// ---
subprojects { ... }
allprojects { ... }
// configure existing task
tasks.named<Test>("test") {
}
// register new task
tasks.register("task-name") {
group = "Custom"
description = "A lovely greeting task."
dependsOn("other-task")
doFirst { ... }
doLast { ... }
}

IntelliJ: Advanced Settings -> Build Tools. Gradle -> Download sources

Common Gradle Build Scripts

~ source set tasks
* lifecycle tasks

Build log

Executing ':classes :testClasses'…
> Task :compileJava
> Task :processResources
> Task :classes
> Task :compileTestJava
> Task :processTestResources
> Task :testClasses
BUILD SUCCESSFUL

Source Sets

  • main — source code compiled into jar
  • test — test source code

Java (Simple)

build.gradle.kts

plugins {
id("java")
}
sourceSets {
/** move src/main -> src */
main {
java {
setSrcDirs(listOf("src/java"))
}
resources {
setSrcDirs(listOf("src/resources"))
}
}
/** remove src/test */
test {
java {
setSrcDirs(emptyList<String>())
}
resources {
setSrcDirs(emptyList<String>())
}
}
}
tasks {
/** skip :testClasses */
testClasses {
enabled = false
}
/** skip :compileTestJava */
compileTestJava {
enabled = false
}
/** skip :processTestResources */
processTestResources {
enabled = false
}
}
├─ settings.gradle.kts
├─ build.gradle.kts
└─ src
├─ java
└─ resources

Java Library

build.gradle.kts

plugins {
`java-library`
}

+ api() dependency configuration


Projects

root project -> sub project

  • Build
  • Dependencies

projects plugins, tasks (input -> action -> output)

UP-TO-DATE REUSED SKIPPED OUTPUT-REUSED

x

  • latest version
  • ides, gradle init

Gradle Settings Script

settings.gradle.kts

/*
* See https://docs.gradle.org/current/userguide/settings_file_basics.html
* See https://docs.gradle.org/current/userguide/plugins_intermediate.html#sec:plugin_management
*/
pluginManagement {
plugins { ... }
resolutionStrategy { ... }
repositories { ... }
}
/** Root Project name (usually same as root folder) */
rootProject.name = "root-project"
/** Sub projects (folder names) */
include("sub-project-a", "sub-project-b", "sub-project-c")

Publishing


Extending Gradle

Custom Tasks

(input -> action -> output)

https://docs.gradle.org/current/userguide/writing_tasks_intermediate.html build.gradle.kts

// Extend the DefaultTask class to create a HelloTask class
abstract class HelloTask : DefaultTask() {
@TaskAction
fun hello() {
println("hello from HelloTask")
}
}
// Register the hello Task with type HelloTask
tasks.register<HelloTask>("hello") {
group = "Custom tasks"
description = "A lovely greeting task."
}

Custom Plugins

Multi-Project Build buildSrc

Must be in the root project

├─ settings.gradle.kts
└─ buildSrc
├─ build.gradle.kts
└─ src/main/kotlin
└─ myproject.java-conventions.gradle.kts

Composite Build build-logic

Can be in any sub-projects

├─ build.gradle.kts
└─ build-logic
├─ settings.gradle.kts
├─ build.gradle.kts
└─ src/main/kotlin
└─ myproject.java-conventions.gradle.kts

Pre-Compiled Script Plugin

Binary Plugin

build.gradle.kts

abstract class SamplePlugin : Plugin<Project> {
override fun apply(project: Project) {
project.tasks.register("ScriptPlugin") {
doLast {
println("Hello world from the build file!")
}
}
}
}
apply<SamplePlugin>()
plugins {
id("myproject.java-conventions")
}

https://docs.gradle.org/current/userguide/pre_compiled_script_plugin_advanced.html

Community/Local/Custom Plugins

Convention Plugins

Plugin Extensions

java {}

Dataflow API / Actions

buildSrc https://docs.gradle.org/current/userguide/plugins_intermediate.html#sec:buildsrc_plugins_dsl

Multi-Project Builds <> Composite Builds buildSrc <> build-logic https://docs.gradle.org/current/userguide/multi_project_builds_intermediate.html

Optimization

Transitive Dependencies

Incremental Builds https://docs.gradle.org/current/userguide/gradle_optimizations.html#sec:incremental_builds_basics

Build Caching https://docs.gradle.org/current/userguide/gradle_optimizations.html#sec:build_caching_basics

Build Scan https://docs.gradle.org/current/userguide/build_scans.html

Task Classification: Actionable task <> Lifecycle task

Gradle Build Lifecycle (init > config > exec) https://docs.gradle.org/current/userguide/build_lifecycle_intermediate.html

Managed Types https://docs.gradle.org/current/userguide/gradle_managed_types_intermediate.html

GRADLE_USER_HOME ~/.gradle or C:\Users\<USERNAME>\.gradle https://docs.gradle.org/current/userguide/gradle_directories_intermediate.html#gradle_user_home

Constrait versions https://docs.gradle.org/current/userguide/dependencies_intermediate.html#sec:enforce_constrain_versions

Init script https://docs.gradle.org/current/userguide/init_scripts.html#init_scripts

System properties

Gradle Docs — System properties reference
Oracle Docs — System Properties

  • Gradle Properties
  • System Properties
  • Project properties

Reference

Gradle Wrapper

Version Catalog

Settings Script

Build Script

Tasks

Plugins

Optimization

This website is currently available on Desktop only
Let @Stephcraft know on Discord you'd like a Mobile version

Join Discord