1

I've generally run into trouble trying to modularize gradle builds, so we tend to duplicate a lot of config code in multi-module builds. Trying again, I have a script plugin that currently just does some config. It applies the Kotlin Multiplatform plugin, then defines some targets.

Here is the script. 'kmp-targets.gradle.kts'

plugins {
    kotlin("multiplatform") version "1.7.10"
}

kotlin {
    macosX64()
    macosArm64()
    iosX64()
//more targets...
}

From the main 'build.gradle.kts' file, I apply the script with the following:

apply(from = "kmp-targets.gradle.kts")

Trying to run that gets the following error:

* Exception is:
ScriptCompilationException(errors=[ScriptCompilationError(message=Unresolved reference. None of the following candidates is applicable because of receiver type mismatch: 
public fun DependencyHandler.kotlin(module: String, version: String? = ...): Any defined in org.gradle.kotlin.dsl
public fun PluginDependenciesSpec.kotlin(module: String): PluginDependencySpec defined in org.gradle.kotlin.dsl, location=/Users/kgalligan/.gradle/.tmp/gradle-kotlin-dsl-1245824212137716677.tmp/kmp-targets.gradle.kts (7:1)), ScriptCompilationError(message=Unresolved reference: macosX64, location=/Users/kgalligan/.gradle/.tmp/gradle-kotlin-dsl-1245824212137716677.tmp/kmp-targets.gradle.kts (8:5)), ScriptCompilationError(message=Unresolved reference: macosArm64, location=/Users/kgalligan/.gradle/.tmp/gradle-kotlin-dsl-1245824212137716677.tmp/kmp-targets.gradle.kts (9:5)), ScriptCompilationError(message=Unresolved reference: iosX64, location=/Users/kgalligan/.gradle/.tmp/gradle-kotlin-dsl-1245824212137716677.tmp/kmp-targets.gradle.kts (10:5)), ScriptCompilationError(message=Unresolved reference: iosArm64, location=/Users/kgalligan/.gradle/.tmp/gradle-kotlin-dsl-1245824212137716677.tmp/kmp-targets.gradle.kts (11:5)), ScriptCompilationError(message=Unresolved reference: iosArm32, location=/Users/kgalligan/.gradle/.tmp/gradle-kotlin-dsl-1245824212137716677.tmp/kmp-targets.gradle.kts (12:5)), ScriptCompilationError(message=Unresolved reference: iosSimulatorArm64, location=/Users/kgalligan/.gradle/.tmp/gradle-kotlin-dsl-1245824212137716677.tmp/kmp-targets.gradle.kts (13:5)), ScriptCompilationError(message=Unresolved reference: watchosArm32, location=/Users/kgalligan/.gradle/.tmp/gradle-kotlin-dsl-1245824212137716677.tmp/kmp-targets.gradle.kts (14:5)), ScriptCompilationError(message=Unresolved reference: watchosArm64, location=/Users/kgalligan/.gradle/.tmp/gradle-kotlin-dsl-1245824212137716677.tmp/kmp-targets.gradle.kts (15:5)), ScriptCompilationError(message=Unresolved reference: watchosSimulatorArm64, location=/Users/kgalligan/.gradle/.tmp/gradle-kotlin-dsl-1245824212137716677.tmp/kmp-targets.gradle.kts (16:5)), ScriptCompilationError(message=Unresolved reference: watchosX86, location=/Users/kgalligan/.gradle/.tmp/gradle-kotlin-dsl-1245824212137716677.tmp/kmp-targets.gradle.kts (17:5)), ScriptCompilationError(message=Unresolved reference: watchosX64, location=/Users/kgalligan/.gradle/.tmp/gradle-kotlin-dsl-1245824212137716677.tmp/kmp-targets.gradle.kts (18:5)), ScriptCompilationError(message=Unresolved reference: tvosArm64, location=/Users/kgalligan/.gradle/.tmp/gradle-kotlin-dsl-1245824212137716677.tmp/kmp-targets.gradle.kts (19:5)), ScriptCompilationError(message=Unresolved reference: tvosSimulatorArm64, location=/Users/kgalligan/.gradle/.tmp/gradle-kotlin-dsl-1245824212137716677.tmp/kmp-targets.gradle.kts (20:5)), ScriptCompilationError(message=Unresolved reference: tvosX64, location=/Users/kgalligan/.gradle/.tmp/gradle-kotlin-dsl-1245824212137716677.tmp/kmp-targets.gradle.kts (21:5)), ScriptCompilationError(message=Unresolved reference: mingwX64, location=/Users/kgalligan/.gradle/.tmp/gradle-kotlin-dsl-1245824212137716677.tmp/kmp-targets.gradle.kts (23:5)), ScriptCompilationError(message=Unresolved reference: mingwX86, location=/Users/kgalligan/.gradle/.tmp/gradle-kotlin-dsl-1245824212137716677.tmp/kmp-targets.gradle.kts (24:5)), ScriptCompilationError(message=Unresolved reference: linuxX64, location=/Users/kgalligan/.gradle/.tmp/gradle-kotlin-dsl-1245824212137716677.tmp/kmp-targets.gradle.kts (25:5)), ScriptCompilationError(message=Unresolved reference: linuxArm32Hfp, location=/Users/kgalligan/.gradle/.tmp/gradle-kotlin-dsl-1245824212137716677.tmp/kmp-targets.gradle.kts (26:5)), ScriptCompilationError(message=Unresolved reference: linuxMips32, location=/Users/kgalligan/.gradle/.tmp/gradle-kotlin-dsl-1245824212137716677.tmp/kmp-targets.gradle.kts (27:5)), ScriptCompilationError(message=Unresolved reference: androidNativeArm32, location=/Users/kgalligan/.gradle/.tmp/gradle-kotlin-dsl-1245824212137716677.tmp/kmp-targets.gradle.kts (29:5)), ScriptCompilationError(message=Unresolved reference: androidNativeArm64, location=/Users/kgalligan/.gradle/.tmp/gradle-kotlin-dsl-1245824212137716677.tmp/kmp-targets.gradle.kts (30:5)), ScriptCompilationError(message=Unresolved reference: androidNativeX86, location=/Users/kgalligan/.gradle/.tmp/gradle-kotlin-dsl-1245824212137716677.tmp/kmp-targets.gradle.kts (31:5)), ScriptCompilationError(message=Unresolved reference: androidNativeX64, location=/Users/kgalligan/.gradle/.tmp/gradle-kotlin-dsl-1245824212137716677.tmp/kmp-targets.gradle.kts (32:5))])
    at org.gradle.kotlin.dsl.support.KotlinCompilerKt.compileKotlinScriptModuleTo(KotlinCompiler.kt:187)
    at org.gradle.kotlin.dsl.support.KotlinCompilerKt.compileKotlinScriptToDirectory(KotlinCompiler.kt:148)
    at org.gradle.kotlin.dsl.execution.ResidualProgramCompiler$compileScript$1.invoke(ResidualProgramCompiler.kt:708)
    at org.gradle.kotlin.dsl.execution.ResidualProgramCompiler$compileScript$1.invoke(ResidualProgramCompiler.kt:85)

etc...

It complains about the kotlin block.

If I change the script to Groovy, 'kmp-targets.gradle', it works.

apply plugin: 'org.jetbrains.kotlin.multiplatform'

kotlin {
    macosX64()
    macosArm64()
    iosX64()
//more targets...
}

To be complete, I tried changing the kts script to apply the multiplatform plugin in a way similar to what I'm doing in the Groovy one, and that also fails.

apply(plugin = "org.jetbrains.kotlin.multiplatform")

kotlin {
    macosX64()
    macosArm64()
    iosX64()
//more targets...
}

The sample code is in the Kermit repo in a branch: https://github.com/touchlab/Kermit/tree/kpg/CleanGradle

The Kotlin script is at kermit/kmp-targets.gradle.kts. It is applied from kermit/build.gradle.kts.

Kevin Galligan
  • 16,159
  • 5
  • 42
  • 62
  • 1
    The Gradle Kotlin DSL accessors aren't available in `apply()`'d plugins. Have you looked into buildSrc convention plugins? https://stackoverflow.com/a/72139946/4161471 – aSemy Sep 07 '22 at 19:28
  • I'll take a look, thanks! I saw that SO answer at one point, but I was rather confused about how the different types of plugins work. – Kevin Galligan Sep 07 '22 at 20:22
  • A working example might help? Kotest is a Kotlin Multiplatform project with a good buildSrc plugins set up https://github.com/kotest/kotest/tree/v5.4.2/buildSrc – aSemy Sep 07 '22 at 20:52
  • Basically there are two ways of applying plugins. `apply()` is legacy (or only for very small scripts). As you've found it's missing some nice features. The replacement is the `plugins {}` block. – aSemy Sep 07 '22 at 20:53
  • There are also two ways of creating plugins. One is more like traditional JVM development, where you extend from Gradle library interfaces to create plugins and tasks. This is more useful if you're going to publish a plugin, because it's less scripty and easier to structure the project. The other is [pre-compiled script plugins](https://docs.gradle.org/current/userguide/custom_plugins.html#sec:precompiled_plugins), which look a *lot* more like `build.gradle.kts` scripts. They're more useful for buildSrc plugins, and often are easier to read because they look like `build.gradle.kts` files. – aSemy Sep 07 '22 at 20:58
  • I've done a fair bit of the binary "traditional" method, but it was either that or one big build script and copy/paste. I just never really wanted to invest more time into learning better Gradle. However, I occasionally see really good project config from somebody who clearly knows what they're doing, so we're trying to up our game a bit :) – Kevin Galligan Sep 09 '22 at 01:20

0 Answers0