From 13ec9cee89ff938024b84f0c338c8852f30ee9a3 Mon Sep 17 00:00:00 2001 From: AJ Alt Date: Sat, 7 Sep 2024 18:20:12 +0000 Subject: [PATCH] Make mordant-omnibus publish on all MPP targets (#228) --- .../kotlin/mordant-js-conventions.gradle.kts | 2 +- .../kotlin/mordant-mpp-conventions.gradle.kts | 6 +---- .../mordant-native-conventions.gradle.kts | 10 -------- ...mordant-native-core-conventions.gradle.kts | 25 ++----------------- mordant-coroutines/build.gradle.kts | 1 + mordant-omnibus/api/mordant-omnibus.api | 0 mordant-omnibus/build.gradle.kts | 10 +++++++- .../ajalt/mordant/internal/OmibusInternal.kt | 4 +++ mordant/build.gradle.kts | 23 +++++++++++++++++ .../ajalt/mordant/internal/MppInternal.jvm.kt | 13 ++++++++-- 10 files changed, 52 insertions(+), 42 deletions(-) create mode 100644 mordant-omnibus/api/mordant-omnibus.api create mode 100644 mordant-omnibus/src/commonMain/kotlin/com/github/ajalt/mordant/internal/OmibusInternal.kt diff --git a/buildSrc/src/main/kotlin/mordant-js-conventions.gradle.kts b/buildSrc/src/main/kotlin/mordant-js-conventions.gradle.kts index fa442add7..490f3bc2a 100644 --- a/buildSrc/src/main/kotlin/mordant-js-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/mordant-js-conventions.gradle.kts @@ -20,7 +20,7 @@ kotlin { sourceSets { val jsCommonMain by creating { dependsOn(commonMain.get()) } jsMain.get().dependsOn(jsCommonMain) - getByName("wasmJsMain").dependsOn(jsCommonMain) + wasmJsMain.get().dependsOn(jsCommonMain) } } diff --git a/buildSrc/src/main/kotlin/mordant-mpp-conventions.gradle.kts b/buildSrc/src/main/kotlin/mordant-mpp-conventions.gradle.kts index b1e206bc7..28a69e3fb 100644 --- a/buildSrc/src/main/kotlin/mordant-mpp-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/mordant-mpp-conventions.gradle.kts @@ -1,9 +1,5 @@ plugins { id("mordant-kotlin-conventions") - id("mordant-js-conventions") id("mordant-native-conventions") -} - -kotlin { - jvm() + id("mordant-js-conventions") } diff --git a/buildSrc/src/main/kotlin/mordant-native-conventions.gradle.kts b/buildSrc/src/main/kotlin/mordant-native-conventions.gradle.kts index 97e280421..4f49e2e9d 100644 --- a/buildSrc/src/main/kotlin/mordant-native-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/mordant-native-conventions.gradle.kts @@ -1,5 +1,4 @@ plugins { - kotlin("multiplatform") id("mordant-native-core-conventions") } @@ -12,13 +11,4 @@ kotlin { watchosArm64() watchosX64() watchosSimulatorArm64() - - sourceSets { - for (target in listOf( - "tvosX64", "tvosArm64", "tvosSimulatorArm64", - "watchosArm32", "watchosArm64", "watchosX64", "watchosSimulatorArm64", - )) { - sourceSets.getByName(target + "Main").kotlin.srcDirs("src/posixSharedMain/kotlin") - } - } } diff --git a/buildSrc/src/main/kotlin/mordant-native-core-conventions.gradle.kts b/buildSrc/src/main/kotlin/mordant-native-core-conventions.gradle.kts index 780a11077..2ede79131 100644 --- a/buildSrc/src/main/kotlin/mordant-native-core-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/mordant-native-core-conventions.gradle.kts @@ -3,6 +3,8 @@ plugins { } kotlin { + applyDefaultHierarchyTemplate() + linuxX64() linuxArm64() macosX64() @@ -21,27 +23,4 @@ kotlin { // watchosDeviceArm64() // watchosX64() // watchosSimulatorArm64() - - applyDefaultHierarchyTemplate() - - // https://kotlinlang.org/docs/multiplatform-hierarchy.html#see-the-full-hierarchy-template - sourceSets { - val posixMain by creating { dependsOn(nativeMain.get()) } - linuxMain.get().dependsOn(posixMain) - appleMain.get().dependsOn(posixMain) - val appleNonDesktopMain by creating { dependsOn(appleMain.get()) } - for (target in listOf(iosMain, tvosMain, watchosMain)) { - target.get().dependsOn(appleNonDesktopMain) - } - // Kotlin 2.0 changed the way MPP is compiled, so instead of copying shared sources to each - // target, it compiles intermediate sources separately. That means that code that previously - // compiled is broken due to errors like "declaration is using numbers with different bit - // widths". So we copy the shared sources to each target manually. - for (target in listOf( - "linuxX64", "linuxArm64", - "macosX64", "macosArm64", - )) { - sourceSets.getByName(target + "Main").kotlin.srcDirs("src/posixSharedMain/kotlin") - } - } } diff --git a/mordant-coroutines/build.gradle.kts b/mordant-coroutines/build.gradle.kts index add6b4fa1..1a6231a90 100644 --- a/mordant-coroutines/build.gradle.kts +++ b/mordant-coroutines/build.gradle.kts @@ -4,6 +4,7 @@ plugins { } kotlin { + jvm() sourceSets { commonMain.dependencies { api(project(":mordant")) diff --git a/mordant-omnibus/api/mordant-omnibus.api b/mordant-omnibus/api/mordant-omnibus.api new file mode 100644 index 000000000..e69de29bb diff --git a/mordant-omnibus/build.gradle.kts b/mordant-omnibus/build.gradle.kts index c76bf60bd..35e79c71e 100644 --- a/mordant-omnibus/build.gradle.kts +++ b/mordant-omnibus/build.gradle.kts @@ -1,10 +1,18 @@ +import org.jetbrains.kotlin.gradle.targets.js.dsl.ExperimentalWasmDsl + +// We don't use all the conventions plugins here since applying the mpp=convention results in +// "IllegalStateException: Configuration already finalized for previous property values" plugins { - id("mordant-kotlin-conventions") + kotlin("multiplatform") + id("mordant-native-conventions") id("mordant-publishing-conventions") } kotlin { jvm() + js { nodejs() } // we don't have any code, but it's an error not to pick aa JS environment + @OptIn(ExperimentalWasmDsl::class) + wasmJs { nodejs() } sourceSets { commonMain.dependencies { api(project(":mordant")) diff --git a/mordant-omnibus/src/commonMain/kotlin/com/github/ajalt/mordant/internal/OmibusInternal.kt b/mordant-omnibus/src/commonMain/kotlin/com/github/ajalt/mordant/internal/OmibusInternal.kt new file mode 100644 index 000000000..a7b3ba75b --- /dev/null +++ b/mordant-omnibus/src/commonMain/kotlin/com/github/ajalt/mordant/internal/OmibusInternal.kt @@ -0,0 +1,4 @@ +package com.github.ajalt.mordant.internal + +// This intentionally empty file is a workaround for KT-52344, which fails to publish a target with +// no source files diff --git a/mordant/build.gradle.kts b/mordant/build.gradle.kts index 5153aa2c3..097d0c35c 100644 --- a/mordant/build.gradle.kts +++ b/mordant/build.gradle.kts @@ -4,6 +4,7 @@ plugins { } kotlin { + jvm() sourceSets { all { languageSettings.optIn("kotlinx.cinterop.ExperimentalForeignApi") @@ -19,5 +20,27 @@ kotlin { jvmTest.dependencies { api(libs.systemrules) } + // Kotlin 2.0 changed the way MPP is compiled, so instead of copying shared sources to each + // target, it compiles intermediate sources separately. That means that code that previously + // compiled is broken due to errors like "declaration is using numbers with different bit + // widths". So we copy the shared sources to each target manually. + sourceSets { + // https://kotlinlang.org/docs/multiplatform-hierarchy.html#see-the-full-hierarchy-template + val posixMain by creating { dependsOn(nativeMain.get()) } + linuxMain.get().dependsOn(posixMain) + appleMain.get().dependsOn(posixMain) + val appleNonDesktopMain by creating { dependsOn(appleMain.get()) } + for (target in listOf(iosMain, tvosMain, watchosMain)) { + target.get().dependsOn(appleNonDesktopMain) + } + for (target in listOf( + "linuxX64", "linuxArm64", + "macosX64", "macosArm64", + "tvosX64", "tvosArm64", "tvosSimulatorArm64", + "watchosArm32", "watchosArm64", "watchosX64", "watchosSimulatorArm64", + )) { + sourceSets.getByName(target + "Main").kotlin.srcDirs("src/posixSharedMain/kotlin") + } + } } } diff --git a/mordant/src/jvmMain/kotlin/com/github/ajalt/mordant/internal/MppInternal.jvm.kt b/mordant/src/jvmMain/kotlin/com/github/ajalt/mordant/internal/MppInternal.jvm.kt index 314873410..452b6ba6c 100644 --- a/mordant/src/jvmMain/kotlin/com/github/ajalt/mordant/internal/MppInternal.jvm.kt +++ b/mordant/src/jvmMain/kotlin/com/github/ajalt/mordant/internal/MppInternal.jvm.kt @@ -157,15 +157,24 @@ internal actual fun readFileIfExists(filename: String): String? { } } +private const val DUMB_RAW_MODE_ERROR = """Cannot find terminal interface that supports raw mode. + +You need at least one of the `:mordant-jvm-*` modules on your classpath. +The `:mordant` module includes all of them as transitive dependencies. +If you're using `:mordant-core` instead, you need to add one or more manually. +If you're using only `:mordant-jvm-ffm`, make sure you're running with JVM 22+, and are passing +`--enable-native-access=ALL-UNNAMED` as a JVM argument. +""" + private object DumbTerminalInterface : StandardTerminalInterface() { override fun stdoutInteractive(): Boolean = true override fun stdinInteractive(): Boolean = true override fun getTerminalSize(): Size? = null override fun enterRawMode(mouseTracking: MouseTracking): AutoCloseable { - throw UnsupportedOperationException("Cannot enter raw mode on this system") + throw UnsupportedOperationException(DUMB_RAW_MODE_ERROR) } override fun readInputEvent(timeout: TimeMark, mouseTracking: MouseTracking): InputEvent? { - throw UnsupportedOperationException("Cannot read input on this system") + throw UnsupportedOperationException(DUMB_RAW_MODE_ERROR) } }