In Gradle, an automated build system, the buildSrc approach has already become the standard for implementing custom plugins and tasks, as well as creating common configurations such as lists of dependencies and versions. But it has a significant drawback: when changing, the buildSrc
assembly cache becomes invalid.
Gradle — , . , buildSrc
.
Gradle
Gradle Android Android Studio. : Android- , , , Eclipse Android-. .
Gradle Groovy ( ) Stack Overflow. , build.gradle
.
, - . build.gradle
. , , , . , build.gradle
.
// projectRoot/build.gradle
public void configureAndroid(Project project) {
project.android {
compileSdkVersion 9
}
}
// projectRoot/app/build.gradle
configureAndroid(this)
android {
// Module specific configuration
}
, . build.gradle
. data
, core
, domain
presentation
, : Gradle .
// projectRoot/android.gradle
project.android {
compileSdkVersion 9
}
// projectRoot/app/build.gradle
apply from: '../android.gradle'
IDE, . build.gradle
plugins { }
, .
, , , , buildSrc . buildSrc
. JVM-, IDE. : ( JUnit ) , Gradle . , , Gradle?!
buildSrc
, . buildSrc
. remote , . , . , Gradle , .
: compile
(Java-) -> report
( ). compile
JavaCompile
, Java-. report
— , : buildSrc
build.gradle
.
report
, -. buildSrc
- compile
report
, compile
. build.gradle
report
. , - compile
, . Gradle , report
, , .
, compile
? buildSrc
.
, . , , build.gradle
. . , , Gradle-. (included) .
buildSrc
, buildSrc
Gradle . ( , Android Gradle plugin). Gradle .
, . , classpath. , FROM-CACHE
. , .
Gradle , . , UP-TO-DATE
.
buildSrc
Reaktive . :
, . , .
. buildSrc
buildSrc2
. buildSrc
, . classpath . buildSrc
, . Gradle , settings.gradle
:
// projectRoot/settings.gradle.kts
pluginManagement {
repositories {
google()
jcenter()
gradlePluginPortal()
}
}
includeBuild("buildSrc2")
// include(":module")
buildscript { repositories { } }
. includeBuild
Gradle buildSrc2
.
buildSrc2
? .
// projectRoot/buildSrc2/build.gradle.kts
plugins {
`kotlin-dsl`
`java-gradle-plugin`
}
gradlePlugin {
// ,
plugins.register("class-loader-plugin") {
id = "class-loader-plugin"
implementationClass = "com.example.ClassLoaderPlugin"
}
// , ,
}
java-gradle-plugin
properties
, . java-gradle-plugin
.
buildSrc
, , Gradle-.
// ClassLoaderPlugin.kt
class ClassLoaderPlugin: Plugin<Project> {
override fun apply(target: Project) {
// no-op
}
}
// Deps.kt
object Deps {
const val kotlinStdLib = "..."
}
class-loader-plugin
Deps
. .
// projectRoot/app/build.gradle
plugins {
id 'class-loader-plugin'
}
dependencies {
implementation(Deps.kotlinStdLib)
}
build.gradle
setupMultiplatformLibrary.
// projectRoot/build.gradle
void setupMultiplatformLibrary(Project project) {
project.apply plugin: 'org.jetbrains.kotlin.multiplatform'
project.kotlin {
sourceSets {
commonMain {
dependencies {
implementation Deps.kotlin.stdlib.common
}
}
commonTest {
dependencies {
implementation Deps.kotlin.test.common
implementation Deps.kotlin.test.annotationsCommon
}
}
}
}
}
. Kotlin Multiplatform .
Gradle- :
// projectRoot/buildSrc2/build.gradle.kts
dependencies {
// Kotlin Gradle plugin,
implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.72")
}
gradlePlugin {
//
plugins.register("mpp-configuration") {
id = "mpp-configuration"
implementationClass = "com.badoo.reaktive.configuration.MppConfigurationPlugin"
}
}
// MppConfigurationPlugin.kt
class MppConfigurationPlugin : Plugin<Project> {
override fun apply(target: Project) {
// "kotlin" "android"
target.extensions.create("configuration", MppConfigurationExtension::class.java, target)
// , , Kotlin
setupMultiplatformLibrary(target)
}
private fun setupMultiplatformLibrary(target: Project) {
// project.apply plugin: 'org.jetbrains.kotlin.multiplatform'
target.apply(plugin = "org.jetbrains.kotlin.multiplatform")
// project.kotlin {
target.extensions.configure(KotlinMultiplatformExtension::class.java) {
sourceSets {
maybeCreate("commonMain").dependencies { implementation(Deps.kotlin.stdlib.common) }
maybeCreate("commonTest").dependencies {
implementation(Deps.kotlin.test.common)
implementation(Deps.kotlin.test.annotationsCommon)
}
}
}
}
}
setupAllTargetsWithDefaultSourceSets isLinuxArm32HfpEnabled
. linuxArm32Hfp
, . linuxArm32Hfp
, . project.name
, . , .
// MppConfigurationExtension.kt
open class MppConfigurationExtension @Inject constructor(
private val project: Project
) {
var isLinuxArm32HfpEnabled: Boolean = false
private set
// , ARM32
fun enableLinuxArm32Hfp() {
if (isLinuxArm32HfpEnabled) return
project.plugins.findPlugin(MppConfigurationPlugin::class.java)?.setupLinuxArm32HfpTarget(project)
isLinuxArm32HfpEnabled = true
}
}
// MppConfigurationPlugin.kt
class MppConfigurationPlugin : Plugin<Project> {
override fun apply(target: Project) {
target.extensions.create("configuration", MppConfigurationExtension::class.java, target)
...
}
fun setupLinuxArm32HfpTarget(project: Project) {
if (!Target.shouldDefineTarget(project, Target.LINUX)) return
project.kotlin {
linuxArm32Hfp()
sourceSets {
maybeCreate("linuxArm32HfpMain").dependsOn(getByName("linuxCommonMain"))
maybeCreate("linuxArm32HfpTest").dependsOn(getByName("linuxCommonTest"))
}
}
}
}
, (disableLinuxArm32Hfp()
), Kotlin ( ). mpp-configuration
configuration
.
// projectRoot/reaktive/build.gradle
plugins {
id 'mpp-configuration'
}
//
configuration {
enableLinuxArm32Hfp()
}
.
Binary compatibility validator, . binary-compatibility.gradle build.gradle
. , .
// projectRoot/binary-compatibility.gradle
if (Target.shouldDefineTarget(target, Target.ALL_LINUX_HOSTED)) {
apply plugin: kotlinx.validation.BinaryCompatibilityValidatorPlugin
apiValidation {
ignoredProjects += [
'benchmarks',
'jmh',
'sample-mpp-module',
'sample-android-app',
'sample-js-browser-app',
'sample-linuxx64-app',
'sample-ios-app',
'sample-macos-app'
]
}
}
.
// projectRoot/buildSrc2/build.gradle.kts
dependencies {
// Binary Compatibility Plugin
implementation("org.jetbrains.kotlinx:binary-compatibility-validator:0.2.3")
}
gradlePlugin {
//
plugins.register("binary-compatibility-configuration") {
id = "binary-compatibility-configuration"
implementationClass = "com.badoo.reaktive.compatibility.BinaryCompatibilityConfigurationPlugin"
}
}
// BinaryCompatibilityConfigurationPlugin.kt
class BinaryCompatibilityConfigurationPlugin : Plugin<Project> {
override fun apply(target: Project) {
if (Target.shouldDefineTarget(target, Target.ALL_LINUX_HOSTED)) {
target.apply(plugin = "binary-compatibility-validator")
target.extensions.configure(ApiValidationExtension::class) {
ignoredProjects.addAll(
listOf(
"benchmarks",
"jmh",
"sample-mpp-module",
"sample-android-app",
"sample-js-browser-app",
"sample-linuxx64-app",
"sample-ios-app",
"sample-macos-app"
)
)
}
}
}
}
build.gradle
.
// projectRoot/build.gradle
plugins {
id 'binary-compatibility-configuration'
}
. , , , . . .
// rootProject/dependencies/build.gradle.kts
plugins {
`kotlin-dsl`
`java-gradle-plugin`
}
//
group = "com.badoo.reaktive.dependencies"
version = "SNAPSHOT"
repositories {
jcenter()
}
gradlePlugin {
// ,
plugins.register("dependencies") {
id = "dependencies"
implementationClass = "com.badoo.reaktive.dependencies.DependenciesPlugin"
}
}
Deps
. . settings.gradle
includeBuild("dependencies")
. dependencies
Deps
.
// projectRoot/buildSrc2/build.gradle.kts
import com.badoo.reaktive.dependencies.Deps
plugins {
`kotlin-dsl`
`java-gradle-plugin`
id("dependencies")
}
dependencies {
// Deps
implementation(Deps.kotlin.plugin)
// implementation(implementation("com.badoo.reaktive.dependencies:dependencies:SNAPSHOT"))
}
// , implementation("com.badoo.reaktive.dependencies:dependencies:SNAPSHOT"),
kotlin.sourceSets.getByName("main").kotlin.srcDir("../dependencies/src/main/kotlin")
, , IDEA ( ). , Deps
buildSrc2
, , buildSrc2
. , , . implementation("com.badoo.reaktive.dependencies:dependencies:SNAPSHOT")
.
dependencies
.
buildSrc
. , plugins { }
apply plugin: 'id'
. plugins
, Groovy- . , . , .
, :
apply plugin: 'android-library'
android {
compileSdkVersion 30
}
apply plugin: 'custom-plugin'
class CustomPlugin: Plugin<Project> {
override fun apply(target: Project) {
target.logger.warn(
target.extentions.getByType(BaseExtension::class)
.compileSdkVersion.toString()
)
}
}
compileSdkVersion
. 30
. plugins { }
.
plugins {
id 'android-library'
id 'custom-plugin'
}
android {
compileSdkVersion 30
}
null
, custom-plugin
android
. :
-
apply plugin: 'custom-plugin'
. , -. -
project.afterEvaluate { }
. : ,afterEvaluate
afterEvaluate
. - API, . Gradle API, .
buildSrc
, Gradle. . Groovy-, plugins { }
. , .