Selection DSL¶
supports { } — the module's supported set¶
plugins {
kotlin("multiplatform")
id("com.rsicarelli.kmptargets") version "0.1.0-SNAPSHOT"
}
kmpTargets {
supports { mobile + web - iosX64 } // presets and leaves compose freely
}
Every preset (all, mobile, apple, web, jvmFamily, …) and every leaf (jvm, iosArm64, linuxX64, …) is in scope inside the block; + unions, - subtracts. No imports, no strings. Full vocabulary: Targets Reference.
Build-logic and callers that need raw values use the overload:
Explicit by default¶
A module that never calls supports registers nothing — like plain KGP, where every target is declared by hand. To build whatever the developer currently selects:
The selection is global (the kmptargets.targets property — see Selection Layers); there is no per-module selection block. The plugin registers selection ∩ supported per module.
A project-wide default for when kmptargets.targets is unset can be set from build-logic via the defaultSelection property; any actual kmptargets.targets value overrides it.
Eagerness and ordering¶
supports registers eagerly — the moment it runs. Two rules follow:
- Apply everything first. Plugins that influence registration (most importantly AGP for
androidTarget— see Advisories) must be applied beforesupports { }runs. - Call it before anything reads
kotlin.targets. Code that snapshots the target container earlier sees a stale view. Build-logic should preferonRegistered, which is ordering-immune.
Calling supports more than once unions — a registered target can't be retracted. A later call registers only its delta and re-checks the AGP guard.
Renaming the JVM target¶
Projects with a legacy kotlin.jvm("desktop") target can keep that name — source dirs (src/desktopMain), artifact suffixes, and task names (compileKotlinDesktop) included:
kmpTargets {
targetName(jvm, "desktop") // must come BEFORE supports { } — registration is eager and one-way
supports { mobile + jvm }
}
- Selection token unchanged. Builds still select with
jvm(or thedesktopalias). Only the registered Gradle target, its source sets, and the artifact suffix follow the custom name. - jvm leaf only.
androidTarget's name is fixed by AGP; native/web names are derived by KGP.targetNamefails loud on any other leaf, on a blank name, and when called aftersupports { }already registered the jvm leaf. - Hierarchy unaffected. KGP's matchers key off the platform type, so the minimal template attaches a renamed target like a plain
jvm. - Introspection.
kmpTargetsInfoprintsjvm (registered as: desktop); build-logic readsRegisteredTarget.gradleName. A hardcodedcompileKotlinJvmin CI matches zero tasks under the rename — the umbrella tasks wire the realcompileKotlinDesktop.
The desktop-named sample runs jvm + iosArm64 with the jvm leaf renamed to desktop.
Escape hatch: mixing with raw KGP¶
supports { } and explicit kotlin { } target calls coexist — the plugin registers through plain KGP APIs. The escape-hatch-dsl sample keeps a raw kotlin.jvm { } block next to supports { jvm + linuxX64 } for target-level configuration the DSL doesn't model.
Related¶
- Selection Layers — where the global selection comes from
- Build Logic — wrapping the DSL in your own convention plugins