Skip to content

Instantly share code, notes, and snippets.

@Dico200
Created January 18, 2019 02:30
Show Gist options
  • Save Dico200/5fc32558391798d4ceb919e654aedb3b to your computer and use it in GitHub Desktop.
Save Dico200/5fc32558391798d4ceb919e654aedb3b to your computer and use it in GitHub Desktop.
Kotlin Multiplatform Project dsl tools for (for Kotlin version 1.3.11)
@file:Suppress("UNCHECKED_CAST")
import org.gradle.api.Project
import org.gradle.api.plugins.ExtensionAware
import org.gradle.kotlin.dsl.get
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
import org.jetbrains.kotlin.gradle.plugin.*
import org.jetbrains.kotlin.gradle.plugin.mpp.*
import org.jetbrains.kotlin.gradle.plugin.sources.DefaultKotlinSourceSet
import kotlin.reflect.KProperty
import org.gradle.api.NamedDomainObjectCollection as NdoCollection
import org.gradle.api.NamedDomainObjectContainer as NdoContainer
internal typealias Presets = NdoCollection<KotlinTargetPreset<*>>
internal typealias Targets = NdoCollection<KotlinTarget>
val Presets.jvm get() = this["jvm"] as KotlinJvmTargetPreset
val Presets.js get() = this["js"] as KotlinJsTargetPreset
val Presets.linuxX64 get() = this["linuxX64"] as KotlinNativeTargetPreset
val Presets.macosX64 get() = this["macosX64"] as KotlinNativeTargetPreset
val Presets.mingwX64 get() = this["mingwX64"] as KotlinNativeTargetPreset
val Presets.iosX64 get() = this["iosX64"] as KotlinNativeTargetPreset
val <T : KotlinCompilation> NdoCollection<T>.main get() = this["main"]
internal val hostOs by lazy { System.getProperty("os.name") }
val isLinux get() = hostOs == "Linux"
val isMacos get() = hostOs == "Mac OS X"
val isWindows get() = hostOs.startsWith("Windows")
val Presets.host
get() = when {
isLinux -> linuxX64
isMacos -> macosX64
isWindows -> mingwX64
else -> error("Unknown host platform '$hostOs'")
}
fun <T : KotlinTarget> Targets.fromPreset(preset: KotlinTargetPreset<T>, name: String, handler: T.() -> Unit = {}): T {
val target = preset.createTarget(name)
add(target)
handler(target)
return target
}
fun <T : KotlinTarget> Targets.gettingTyped(configure: T.() -> Unit) =
KotlinTargetDelegateProvider(this, configure)
class KotlinTargetDelegateProvider<T : KotlinTarget>(val targets: Targets, val configure: T.() -> Unit) {
operator fun getValue(thisRef: Any?, property: KProperty<*>): T =
(targets.getByName(property.name) as T).apply(configure)
}
val KotlinMultiplatformExtension.extensions get() = (this as ExtensionAware).extensions
fun KotlinMultiplatformExtension.`sourceSets`(configure: NdoContainer<KotlinSourceSet>.() -> Unit): Unit =
extensions.configure("sourceSets", configure)
fun KotlinMultiplatformExtension.`targets`(configure: NdoContainer<KotlinTarget>.() -> Unit): Unit =
extensions.configure("targets", configure)
val NdoContainer<KotlinSourceSet>.commonMain get() = getByName("commonMain")
val NdoContainer<KotlinSourceSet>.iosMain get() = getByName("iosMain")
val NdoContainer<KotlinSourceSet>.jvmMain get() = getByName("jvmMain")
operator fun KotlinSourceSet.invoke(configure: KotlinSourceSet.() -> Unit) {
configure()
}
class KotlinDefaultConfigureProperties(val presets: Presets) {
var hasJvm = true
var hasIos = true
val dependencyProjects = mutableListOf<Project>()
fun dependsOn(project: Project) {
dependencyProjects.add(project)
}
/*
fun dependencies(configure: KotlinDependencyHandler.() -> Unit) {
TODO("not implemented")
}
*/
}
private val KotlinDefaultConfigureProperties.targets
get() = listOf(presets.jvm.takeIf { hasJvm }, presets.iosX64.takeIf { hasIos }).filterNotNull()
fun KotlinMultiplatformExtension.defaultConfigure(configure: KotlinDefaultConfigureProperties.() -> Unit = {}) {
val props = KotlinDefaultConfigureProperties(presets).apply(configure)
targets {
for (preset in props.targets) {
val name = when (preset.name) {
"jvm", "androidJvm" -> "jvm"
"iosX64", "iosArm64" -> "ios"
else -> throw IllegalArgumentException()
}
fromPreset(preset, name) {
if (platformType == KotlinPlatformType.native) {
this as KotlinNativeTarget
compilations.main.outputKinds(NativeOutputKind.FRAMEWORK)
}
}
}
}
sourceSets {
forEach {
it.languageSettings.apply {
apiVersion = "1.3"
languageVersion = "1.3"
useExperimentalAnnotation("kotlin.Experimental")
}
}
getByName("commonMain").apply {
dependencies {
commonDependencies()
for (project in props.dependencyProjects) {
api(project)
}
}
}
for (target in targets) {
if (target.platformType == KotlinPlatformType.common) continue
target.compilations.main.apply {
for (sourceSet in sourceSets) {
sourceSet as DefaultKotlinSourceSet
if (!sourceSet.displayName.startsWith(name)) continue
val compilationName = sourceSet.displayName.substring(name.length)
sourceSet.dependsOn(getByName("common$compilationName"))
}
dependencies {
when (target.name) {
"jvm" -> jvmDependencies()
"androidJvm" -> androidDependencies()
"iosX64", "iosArm64" -> nativeDependencies()
}
}
}
}
}
}
private fun KotlinDependencyHandler.commonDependencies() {
api("org.jetbrains.kotlin:kotlin-stdlib-common")
api("org.jetbrains.kotlinx:kotlinx-coroutines-core-common:$coroutinesVersion")
}
private fun KotlinDependencyHandler.jvmDependencies() {
api("org.jetbrains.kotlin:kotlin-stdlib")
api("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutinesVersion")
}
private fun KotlinDependencyHandler.androidDependencies() {
api("org.jetbrains.kotlin:kotlin-stdlib-android")
api("org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutinesVersion")
}
private fun KotlinDependencyHandler.nativeDependencies() {
api("org.jetbrains.kotlin:kotlin-stdlib-native")
api("org.jetbrains.kotlinx:kotlinx-coroutines-core-native:$coroutinesVersion")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment