From 5d0324bc7baf1f4978ba5dff814c50f9f0293032 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Sat, 20 Aug 2022 19:42:19 +0300 Subject: [PATCH] Universal native configuration --- CHANGELOG.md | 3 +- gradle/libs.versions.toml | 10 +- gradle/wrapper/gradle-wrapper.properties | 2 +- .../kscience/gradle/KScienceCommonPlugin.kt | 4 +- .../kscience/gradle/KScienceExtension.kt | 96 +++++++++++++++---- .../kscience/gradle/KScienceNativePlugin.kt | 48 ++-------- .../kscience/gradle/commonConfigurations.kt | 88 +++++++++++++---- 7 files changed, 168 insertions(+), 83 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6f986d6..53969d4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,11 +10,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Add `-Xjdk-release` key ### Changed -- Kotlin 1.7.10 +- Kotlin 1.7.20-Beta - Versions update - Project group changed to `space.kscience` ### Deprecated +- FX configuration ### Removed diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 23bbb5a..c859c44 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,19 +1,19 @@ [versions] -tools = "0.12.0-kotlin-1.7.20-Beta" +tools = "0.12.1-kotlin-1.7.20-Beta" kotlin = "1.7.20-Beta" atomicfu = "0.18.2" binary-compatibility-validator = "0.10.1" changelog = "1.3.1" -dokka = "1.7.0" -kotlin-jupyter = "0.11.0-125" +dokka = "1.7.10" +kotlin-jupyter = "0.11.0-142" kotlinx-benchmark = "0.4.4" kotlinx-cli = "0.3.5" -kotlinx-coroutines = "1.6.3" +kotlinx-coroutines = "1.6.4" kotlinx-datetime = "0.4.0" kotlinx-html = "0.7.5" kotlinx-knit = "0.4.0" kotlinx-nodejs = "0.0.7" -kotlinx-serialization = "1.3.3" +kotlinx-serialization = "1.4.0-RC" ktor = "2.0.3" xmlutil = "0.84.2" yamlkt = "0.12.0" diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index aa991fc..8049c68 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/src/main/kotlin/space/kscience/gradle/KScienceCommonPlugin.kt b/src/main/kotlin/space/kscience/gradle/KScienceCommonPlugin.kt index 562aaad..4e42b22 100644 --- a/src/main/kotlin/space/kscience/gradle/KScienceCommonPlugin.kt +++ b/src/main/kotlin/space/kscience/gradle/KScienceCommonPlugin.kt @@ -4,7 +4,5 @@ import org.gradle.api.Plugin import org.gradle.api.Project public open class KScienceCommonPlugin : Plugin { - override fun apply(project: Project): Unit = project.configureKScience( - KotlinVersion(1, 7, 10) - ) + override fun apply(project: Project): Unit = project.configureKScience() } diff --git a/src/main/kotlin/space/kscience/gradle/KScienceExtension.kt b/src/main/kotlin/space/kscience/gradle/KScienceExtension.kt index 75c36d5..3afa58b 100644 --- a/src/main/kotlin/space/kscience/gradle/KScienceExtension.kt +++ b/src/main/kotlin/space/kscience/gradle/KScienceExtension.kt @@ -9,6 +9,8 @@ import org.jetbrains.kotlin.gradle.dsl.KotlinJsProjectExtension import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension import org.jetbrains.kotlin.gradle.dsl.KotlinProjectExtension import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget +import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinJsTargetDsl +import org.jetbrains.kotlin.gradle.targets.jvm.KotlinJvmTarget import org.jetbrains.kotlin.gradle.tasks.KotlinCompile import org.jetbrains.kotlinx.jupyter.api.plugin.tasks.JupyterApiResourcesTask import space.kscience.gradle.internal.defaultPlatform @@ -43,7 +45,8 @@ public enum class DependencySourceSet(public val setName: String, public val suf } -public class KScienceExtension(public val project: Project) { +public open class KScienceExtension(public val project: Project) { + /** * Use coroutines-core with default version or [version] */ @@ -90,6 +93,7 @@ public class KScienceExtension(public val project: Project) { /** * Add platform-specific JavaFX dependencies with given list of [FXModule]s */ + @Deprecated("Use manual FX configuration") public fun useFx( vararg modules: FXModule, configuration: DependencyConfiguration = DependencyConfiguration.COMPILE_ONLY, @@ -123,14 +127,6 @@ public class KScienceExtension(public val project: Project) { dependencyConfiguration = configuration ) - /** - * Apply jupyter plugin - */ - @Deprecated("Use jupyterLibrary") - public fun useJupyter() { - project.plugins.apply("org.jetbrains.kotlin.jupyter.api") - } - /** * Apply jupyter plugin and add entry point for the jupyter library. * If left empty applies a plugin without declaring library producers @@ -174,10 +170,10 @@ public class KScienceExtension(public val project: Project) { /** * Add context receivers to this project and all subprojects */ - public fun withContextReceivers(){ - project.allprojects{ - tasks.withType{ - kotlinOptions{ + public fun withContextReceivers() { + project.allprojects { + tasks.withType { + kotlinOptions { freeCompilerArgs = freeCompilerArgs + "-Xcontext-receivers" } } @@ -185,8 +181,76 @@ public class KScienceExtension(public val project: Project) { } } -internal fun Project.registerKScienceExtension() { - if (extensions.findByType() == null) { - extensions.add("kscience", KScienceExtension(this)) +public enum class KotlinNativePreset { + linuxX64, + mingwX64, + macosX64, + iosX64, + iosArm64 +} + +public data class KScienceNativeTarget( + val preset: KotlinNativePreset, + val targetName: String = preset.name, + val targetConfiguration: KotlinNativeTarget.() -> Unit = { }, +) { + public companion object { + public val linuxX64: KScienceNativeTarget = KScienceNativeTarget(KotlinNativePreset.linuxX64) + public val mingwX64: KScienceNativeTarget = KScienceNativeTarget(KotlinNativePreset.mingwX64) + public val macosX64: KScienceNativeTarget = KScienceNativeTarget(KotlinNativePreset.macosX64) + public val iosX64: KScienceNativeTarget = KScienceNativeTarget(KotlinNativePreset.iosX64) + public val iosArm64: KScienceNativeTarget = KScienceNativeTarget(KotlinNativePreset.iosArm64) + } +} + +public class KScienceNativeConfiguration { + internal var targets: MutableMap = listOf( + KScienceNativeTarget.linuxX64, + KScienceNativeTarget.mingwX64, + KScienceNativeTarget.macosX64, + KScienceNativeTarget.iosX64, + KScienceNativeTarget.iosArm64, + ).associateBy { it.preset }.toMutableMap() + + public fun targets(vararg target: KScienceNativeTarget) { + targets = target.associateBy { it.preset }.toMutableMap() + } + + public fun target(target: KScienceNativeTarget) { + targets[target.preset] = target + } +} + +public open class KScienceMppExtension(project: Project) : KScienceExtension(project) { + internal var jvmConfiguration: ((KotlinJvmTarget) -> Unit)? = { } + + /** + * Custom configuration for JVM target. If null - disable JVM target + */ + public fun jvm(block: KotlinJvmTarget.() -> Unit) { + jvmConfiguration = block + } + + internal var jsConfiguration: ((KotlinJsTargetDsl) -> Unit)? = { } + + /** + * Custom configuration for JS target. If null - disable JS target + */ + public fun js(block: KotlinJsTargetDsl.() -> Unit) { + jsConfiguration = block + } + + internal var nativeConfiguration: KScienceNativeConfiguration? = null + + public fun native(block: KScienceNativeConfiguration.() -> Unit = {}) { + nativeConfiguration = KScienceNativeConfiguration().apply(block) + } +} + + +internal inline fun Project.registerKScienceExtension(constructor: (Project) -> T): T { + extensions.findByType()?.let { return it } + return constructor(this).also { + extensions.add("kscience", it) } } diff --git a/src/main/kotlin/space/kscience/gradle/KScienceNativePlugin.kt b/src/main/kotlin/space/kscience/gradle/KScienceNativePlugin.kt index 63198c9..232e653 100644 --- a/src/main/kotlin/space/kscience/gradle/KScienceNativePlugin.kt +++ b/src/main/kotlin/space/kscience/gradle/KScienceNativePlugin.kt @@ -2,8 +2,7 @@ package space.kscience.gradle import org.gradle.api.Plugin import org.gradle.api.Project -import org.gradle.kotlin.dsl.* -import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension +import org.gradle.kotlin.dsl.hasPlugin public class KScienceNativePlugin : Plugin { override fun apply(project: Project): Unit = project.run { @@ -13,47 +12,14 @@ public class KScienceNativePlugin : Plugin { plugins.apply("org.jetbrains.kotlin.multiplatform") } - if (!plugins.hasPlugin(KScienceCommonPlugin::class)) { - logger.info("KScience plugin is not resolved. Adding it automatically") - apply() + registerKScienceExtension(::KScienceMppExtension).apply { + native() } - configure { - val nativeTargets = setOf( - linuxX64(), - mingwX64(), - macosX64(), - iosX64(), - iosArm64() - ) - - sourceSets { - val commonMain = findByName("commonMain")!! - val commonTest = findByName("commonTest")!! - - val nativeMain by creating { - dependsOn(commonMain) - } - - val nativeTest by creating { - //should NOT depend on nativeMain because automatic dependency by plugin - dependsOn(commonTest) - } - - configure(nativeTargets) { - compilations["main"]?.apply { - configure(kotlinSourceSets) { - dependsOn(nativeMain) - } - } - - compilations["test"]?.apply { - configure(kotlinSourceSets) { - dependsOn(nativeTest) - } - } - } - } + if (!plugins.hasPlugin(KScienceCommonPlugin::class)) { + configureKScience() + } else { + error("KScience native plugin must be applied instead of common") } } } diff --git a/src/main/kotlin/space/kscience/gradle/commonConfigurations.kt b/src/main/kotlin/space/kscience/gradle/commonConfigurations.kt index 6f3f4bc..97434e0 100644 --- a/src/main/kotlin/space/kscience/gradle/commonConfigurations.kt +++ b/src/main/kotlin/space/kscience/gradle/commonConfigurations.kt @@ -9,23 +9,30 @@ import org.jetbrains.dokka.gradle.DokkaPlugin import org.jetbrains.kotlin.gradle.dsl.KotlinJsProjectExtension import org.jetbrains.kotlin.gradle.dsl.KotlinJvmProjectExtension import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension +import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTargetWithHostTests import org.jetbrains.kotlin.gradle.tasks.KotlinCompile import space.kscience.gradle.internal.applyRepos import space.kscience.gradle.internal.applySettings import space.kscience.gradle.internal.fromJsDependencies -private val defaultJvmArgs: List = listOf("-Xjvm-default=all", "-Xlambdas=indy", "-Xjdk-release=${KScienceVersions.JVM_TARGET}") +private val defaultKotlinJvmArgs: List = + listOf("-Xjvm-default=all", "-Xlambdas=indy", "-Xjdk-release=${KScienceVersions.JVM_TARGET}") + +private fun resolveKotlinVersion():KotlinVersion { + val (major, minor, patch) = KScienceVersions.kotlinVersion.split(".", "-") + return KotlinVersion(major.toInt(),minor.toInt(),patch.toInt()) +} public fun Project.configureKScience( - kotlinVersion: KotlinVersion, + kotlinVersion: KotlinVersion = resolveKotlinVersion(), ) { - //Common configuration - registerKScienceExtension() repositories.applyRepos() //Configuration for K-JVM plugin pluginManager.withPlugin("org.jetbrains.kotlin.jvm") { + registerKScienceExtension(::KScienceExtension) + //logger.info("Applying KScience configuration for JVM project") configure { sourceSets.all { @@ -44,7 +51,7 @@ public fun Project.configureKScience( tasks.withType { kotlinOptions { jvmTarget = KScienceVersions.JVM_TARGET.toString() - freeCompilerArgs = freeCompilerArgs + defaultJvmArgs + freeCompilerArgs = freeCompilerArgs + defaultKotlinJvmArgs } } @@ -58,12 +65,14 @@ public fun Project.configureKScience( } pluginManager.withPlugin("org.jetbrains.kotlin.js") { + registerKScienceExtension(::KScienceExtension) + //logger.info("Applying KScience configuration for JS project") configure { js(IR) { browser { commonWebpackConfig { - cssSupport{ + cssSupport { enabled = true } } @@ -96,23 +105,31 @@ public fun Project.configureKScience( } pluginManager.withPlugin("org.jetbrains.kotlin.multiplatform") { + val configuration = registerKScienceExtension(::KScienceMppExtension) + configure { - jvm { - compilations.all { - kotlinOptions { - jvmTarget = KScienceVersions.JVM_TARGET.toString() - freeCompilerArgs = freeCompilerArgs + defaultJvmArgs + configuration.jvmConfiguration?.let { jvmConfiguration -> + jvm { + compilations.all { + kotlinOptions { + jvmTarget = KScienceVersions.JVM_TARGET.toString() + freeCompilerArgs = freeCompilerArgs + defaultKotlinJvmArgs + } } + jvmConfiguration(this) } } - js(IR) { - browser { - commonWebpackConfig { - cssSupport{ - enabled = true + configuration.jsConfiguration?.let { jsConfiguration -> + js(IR) { + browser { + commonWebpackConfig { + cssSupport { + enabled = true + } } } + jsConfiguration(this) } } @@ -141,6 +158,45 @@ public fun Project.configureKScience( implementation(kotlin("test-js")) } } + + configuration.nativeConfiguration?.let { nativeConfiguration -> + val nativeTargets: List = nativeConfiguration.targets.values.mapNotNull { nativeTarget -> + when (nativeTarget.preset) { + KotlinNativePreset.linuxX64 -> linuxX64(nativeTarget.targetName, nativeTarget.targetConfiguration) + KotlinNativePreset.mingwX64 -> linuxX64(nativeTarget.targetName, nativeTarget.targetConfiguration) + KotlinNativePreset.macosX64 -> linuxX64(nativeTarget.targetName, nativeTarget.targetConfiguration) + KotlinNativePreset.iosX64 -> linuxX64(nativeTarget.targetName, nativeTarget.targetConfiguration) + KotlinNativePreset.iosArm64 -> linuxX64(nativeTarget.targetName, nativeTarget.targetConfiguration) + else -> { + logger.error("Native preset ${nativeTarget.preset} not recognised.") + null + } + } + } + + val nativeMain by creating { + dependsOn(commonMain) + } + + val nativeTest by creating { + //should NOT depend on nativeMain because automatic dependency by plugin + dependsOn(commonTest) + } + + configure(nativeTargets) { + compilations["main"]?.apply { + configure(kotlinSourceSets) { + dependsOn(nativeMain) + } + } + + compilations["test"]?.apply { + configure(kotlinSourceSets) { + dependsOn(nativeTest) + } + } + } + } } sourceSets.all {