Compare commits

...

11 Commits

63 changed files with 396 additions and 153 deletions

View File

@@ -1,5 +1,26 @@
# Changelog # Changelog
## 0.31.1
* `Coroutines`:
* `SmartRWLocker`:
* Fix of `unlockWrite`, `lockWrite` and `releaseRead` calls to pass correct number of permits
* `SmartMutex`:
* Fix `unlock` call
* `SmartSemaphore`:
* Fix same issues to avoid cancellation exceptions handling errors and several other problems
## 0.31.0
* `Versions`:
* `Kotlin`: `2.3.21` -> `2.4.10`
* `SQLite`: `3.53.2.1` -> `3.53.4.0`
* `KSP`: `2.3.9` -> `2.3.11`
* `Exposed`: `1.3.0` -> `1.5.0`
* `NMCP`: `1.5.0` -> `1.6.1`
* `AndroidX AppCompat`: `1.7.1` -> `1.8.0`
* `AndroidX Fragment`: `1.8.9` -> `1.9.0`
## 0.30.1 ## 0.30.1
* `Versions`: * `Versions`:

View File

@@ -1,7 +1,7 @@
plugins { plugins {
id "org.jetbrains.kotlin.multiplatform" id "org.jetbrains.kotlin.multiplatform"
id "org.jetbrains.kotlin.plugin.serialization" id "org.jetbrains.kotlin.plugin.serialization"
id "com.android.library" id "com.android.kotlin.multiplatform.library"
} }
apply from: "$mppAndroidProject" apply from: "$mppAndroidProject"

View File

@@ -1,7 +1,7 @@
plugins { plugins {
id "org.jetbrains.kotlin.multiplatform" id "org.jetbrains.kotlin.multiplatform"
id "org.jetbrains.kotlin.plugin.serialization" id "org.jetbrains.kotlin.plugin.serialization"
id "com.android.library" id "com.android.kotlin.multiplatform.library"
} }
apply from: "$mppAndroidProject" apply from: "$mppAndroidProject"

View File

@@ -1,7 +1,7 @@
plugins { plugins {
id "org.jetbrains.kotlin.multiplatform" id "org.jetbrains.kotlin.multiplatform"
id "org.jetbrains.kotlin.plugin.serialization" id "org.jetbrains.kotlin.plugin.serialization"
id "com.android.library" id "com.android.kotlin.multiplatform.library"
alias(libs.plugins.jb.compose) alias(libs.plugins.jb.compose)
alias(libs.plugins.kt.jb.compose) alias(libs.plugins.kt.jb.compose)
} }

View File

@@ -1,7 +1,7 @@
plugins { plugins {
id "org.jetbrains.kotlin.multiplatform" id "org.jetbrains.kotlin.multiplatform"
id "org.jetbrains.kotlin.plugin.serialization" id "org.jetbrains.kotlin.plugin.serialization"
id "com.android.library" id "com.android.kotlin.multiplatform.library"
} }
apply from: "$mppAndroidProject" apply from: "$mppAndroidProject"

View File

@@ -1,7 +1,7 @@
plugins { plugins {
id "org.jetbrains.kotlin.multiplatform" id "org.jetbrains.kotlin.multiplatform"
id "org.jetbrains.kotlin.plugin.serialization" id "org.jetbrains.kotlin.plugin.serialization"
id "com.android.library" id "com.android.kotlin.multiplatform.library"
alias(libs.plugins.jb.compose) alias(libs.plugins.jb.compose)
alias(libs.plugins.kt.jb.compose) alias(libs.plugins.kt.jb.compose)
} }

View File

@@ -1,7 +1,7 @@
plugins { plugins {
id "org.jetbrains.kotlin.multiplatform" id "org.jetbrains.kotlin.multiplatform"
id "org.jetbrains.kotlin.plugin.serialization" id "org.jetbrains.kotlin.plugin.serialization"
id "com.android.library" id "com.android.kotlin.multiplatform.library"
} }
apply from: "$mppJvmJsWasmJsAndroidLinuxMingwLinuxArm64Project" apply from: "$mppJvmJsWasmJsAndroidLinuxMingwLinuxArm64Project"

View File

@@ -1,7 +1,7 @@
plugins { plugins {
id "org.jetbrains.kotlin.multiplatform" id "org.jetbrains.kotlin.multiplatform"
id "org.jetbrains.kotlin.plugin.serialization" id "org.jetbrains.kotlin.plugin.serialization"
id "com.android.library" id "com.android.kotlin.multiplatform.library"
} }
apply from: "$mppJvmJsWasmJsAndroidLinuxMingwLinuxArm64Project" apply from: "$mppJvmJsWasmJsAndroidLinuxMingwLinuxArm64Project"

View File

@@ -1,7 +1,7 @@
plugins { plugins {
id "org.jetbrains.kotlin.multiplatform" id "org.jetbrains.kotlin.multiplatform"
id "org.jetbrains.kotlin.plugin.serialization" id "org.jetbrains.kotlin.plugin.serialization"
id "com.android.library" id "com.android.kotlin.multiplatform.library"
} }
apply from: "$mppJvmJsWasmJsAndroidLinuxMingwLinuxArm64Project" apply from: "$mppJvmJsWasmJsAndroidLinuxMingwLinuxArm64Project"
@@ -13,7 +13,7 @@ kotlin {
api libs.klock api libs.klock
} }
} }
jvmMain { jvmAndAndroidMain {
dependencies { dependencies {
api project(":micro_utils.coroutines") api project(":micro_utils.coroutines")
} }

View File

@@ -1,7 +1,7 @@
plugins { plugins {
id "org.jetbrains.kotlin.multiplatform" id "org.jetbrains.kotlin.multiplatform"
id "org.jetbrains.kotlin.plugin.serialization" id "org.jetbrains.kotlin.plugin.serialization"
id "com.android.library" id "com.android.kotlin.multiplatform.library"
alias(libs.plugins.jb.compose) alias(libs.plugins.jb.compose)
alias(libs.plugins.kt.jb.compose) alias(libs.plugins.kt.jb.compose)
} }

View File

@@ -1,7 +1,7 @@
plugins { plugins {
id "org.jetbrains.kotlin.multiplatform" id "org.jetbrains.kotlin.multiplatform"
id "org.jetbrains.kotlin.plugin.serialization" id "org.jetbrains.kotlin.plugin.serialization"
id "com.android.library" id "com.android.kotlin.multiplatform.library"
} }
apply from: "$mppJvmJsWasmJsAndroidLinuxMingwLinuxArm64Project" apply from: "$mppJvmJsWasmJsAndroidLinuxMingwLinuxArm64Project"

View File

@@ -1,7 +1,7 @@
plugins { plugins {
id "org.jetbrains.kotlin.multiplatform" id "org.jetbrains.kotlin.multiplatform"
id "org.jetbrains.kotlin.plugin.serialization" id "org.jetbrains.kotlin.plugin.serialization"
id "com.android.library" id "com.android.kotlin.multiplatform.library"
alias(libs.plugins.jb.compose) alias(libs.plugins.jb.compose)
alias(libs.plugins.kt.jb.compose) alias(libs.plugins.kt.jb.compose)
} }

View File

@@ -1,5 +1,6 @@
package dev.inmo.micro_utils.coroutines package dev.inmo.micro_utils.coroutines
import kotlinx.coroutines.NonCancellable
import kotlinx.coroutines.currentCoroutineContext import kotlinx.coroutines.currentCoroutineContext
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.asStateFlow
@@ -7,6 +8,7 @@ import kotlinx.coroutines.flow.first
import kotlinx.coroutines.isActive import kotlinx.coroutines.isActive
import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock import kotlinx.coroutines.sync.withLock
import kotlinx.coroutines.withContext
import kotlin.contracts.ExperimentalContracts import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.InvocationKind import kotlin.contracts.InvocationKind
import kotlin.contracts.contract import kotlin.contracts.contract
@@ -92,8 +94,8 @@ sealed interface SmartMutex {
* If [isLocked] == true - will change it to false and return true. If current call will not unlock this * If [isLocked] == true - will change it to false and return true. If current call will not unlock this
* [SmartMutex] - false * [SmartMutex] - false
*/ */
suspend fun unlock(): Boolean { suspend fun unlock(): Boolean = withContext(NonCancellable) {
return if (_lockStateFlow.value) { if (_lockStateFlow.value) {
internalChangesMutex.withLock { internalChangesMutex.withLock {
if (_lockStateFlow.value) { if (_lockStateFlow.value) {
_lockStateFlow.value = false _lockStateFlow.value = false

View File

@@ -1,6 +1,8 @@
package dev.inmo.micro_utils.coroutines package dev.inmo.micro_utils.coroutines
import kotlinx.coroutines.CancellationException import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.NonCancellable
import kotlinx.coroutines.withContext
import kotlin.contracts.ExperimentalContracts import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.InvocationKind import kotlin.contracts.InvocationKind
import kotlin.contracts.contract import kotlin.contracts.contract
@@ -21,6 +23,7 @@ class SmartRWLocker(private val readPermits: Int = Int.MAX_VALUE, writeIsLocked:
val readSemaphore: SmartSemaphore.Immutable = _readSemaphore.immutable() val readSemaphore: SmartSemaphore.Immutable = _readSemaphore.immutable()
val writeMutex: SmartMutex.Immutable = _writeMutex.immutable() val writeMutex: SmartMutex.Immutable = _writeMutex.immutable()
/** /**
* Do lock in [readSemaphore] inside of [writeMutex] locking * Do lock in [readSemaphore] inside of [writeMutex] locking
*/ */
@@ -32,8 +35,8 @@ class SmartRWLocker(private val readPermits: Int = Int.MAX_VALUE, writeIsLocked:
/** /**
* Release one read permit in [readSemaphore] * Release one read permit in [readSemaphore]
*/ */
suspend fun releaseRead(): Boolean { suspend fun releaseRead(): Boolean = withContext(NonCancellable) {
return _readSemaphore.release() _readSemaphore.release()
} }
/** /**
@@ -44,7 +47,9 @@ class SmartRWLocker(private val readPermits: Int = Int.MAX_VALUE, writeIsLocked:
try { try {
_readSemaphore.acquire(readPermits) _readSemaphore.acquire(readPermits)
} catch (e: CancellationException) { } catch (e: CancellationException) {
_writeMutex.unlock() withContext(NonCancellable) {
_writeMutex.unlock()
}
throw e throw e
} }
} }
@@ -52,9 +57,9 @@ class SmartRWLocker(private val readPermits: Int = Int.MAX_VALUE, writeIsLocked:
/** /**
* Unlock [writeMutex] * Unlock [writeMutex]
*/ */
suspend fun unlockWrite(): Boolean { suspend fun unlockWrite(): Boolean = withContext(NonCancellable) {
return _writeMutex.unlock().also { _writeMutex.unlock().also { unlocked ->
if (it) { if (unlocked) {
_readSemaphore.release(readPermits) _readSemaphore.release(readPermits)
} }
} }

View File

@@ -1,5 +1,6 @@
package dev.inmo.micro_utils.coroutines package dev.inmo.micro_utils.coroutines
import kotlinx.coroutines.NonCancellable
import kotlinx.coroutines.currentCoroutineContext import kotlinx.coroutines.currentCoroutineContext
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.asStateFlow
@@ -8,6 +9,7 @@ import kotlinx.coroutines.isActive
import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.Semaphore import kotlinx.coroutines.sync.Semaphore
import kotlinx.coroutines.sync.withLock import kotlinx.coroutines.sync.withLock
import kotlinx.coroutines.withContext
import kotlin.contracts.ExperimentalContracts import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.InvocationKind import kotlin.contracts.InvocationKind
import kotlin.contracts.contract import kotlin.contracts.contract
@@ -76,7 +78,9 @@ sealed interface SmartSemaphore {
} }
} while (shouldContinue && currentCoroutineContext().isActive) } while (shouldContinue && currentCoroutineContext().isActive)
} catch (e: Throwable) { } catch (e: Throwable) {
release(acquiredPermits) if (acquiredPermits > 0) {
release(acquiredPermits)
}
throw e throw e
} }
} }
@@ -107,9 +111,9 @@ sealed interface SmartSemaphore {
*/ */
suspend fun tryAcquire(permits: Int = 1): Boolean { suspend fun tryAcquire(permits: Int = 1): Boolean {
val checkedPermits = checkedPermits(permits) val checkedPermits = checkedPermits(permits)
return if (_freePermitsStateFlow.value < checkedPermits) { return if (_freePermitsStateFlow.value >= checkedPermits) {
internalChangesMutex.withLock { internalChangesMutex.withLock {
if (_freePermitsStateFlow.value < checkedPermits) { if (_freePermitsStateFlow.value >= checkedPermits) {
_freePermitsStateFlow.value -= checkedPermits _freePermitsStateFlow.value -= checkedPermits
true true
} else { } else {
@@ -125,12 +129,12 @@ sealed interface SmartSemaphore {
* If [freePermits] == true - will change it to false and return true. If current call will not unlock this * If [freePermits] == true - will change it to false and return true. If current call will not unlock this
* [SmartSemaphore] - false * [SmartSemaphore] - false
*/ */
suspend fun release(permits: Int = 1): Boolean { suspend fun release(permits: Int = 1): Boolean = withContext(NonCancellable) {
val checkedPermits = checkedPermits(permits) val checkedPermits = checkedPermits(permits)
return if (_freePermitsStateFlow.value < this.maxPermits) { if (_freePermitsStateFlow.value < maxPermits) {
internalChangesMutex.withLock { internalChangesMutex.withLock {
if (_freePermitsStateFlow.value < this.maxPermits) { if (_freePermitsStateFlow.value < maxPermits) {
_freePermitsStateFlow.value = minOf(_freePermitsStateFlow.value + checkedPermits, this.maxPermits) _freePermitsStateFlow.value = minOf(_freePermitsStateFlow.value + checkedPermits, maxPermits)
true true
} else { } else {
false false

View File

@@ -0,0 +1,73 @@
import dev.inmo.micro_utils.coroutines.SmartMutex
import dev.inmo.micro_utils.coroutines.withLock
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.awaitCancellation
import kotlinx.coroutines.cancel
import kotlinx.coroutines.cancelAndJoin
import kotlinx.coroutines.currentCoroutineContext
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch
import kotlinx.coroutines.test.runTest
import kotlin.test.Test
import kotlin.test.assertFalse
import kotlin.test.assertTrue
import kotlin.time.Duration.Companion.seconds
class SmartMutexTests {
@Test
fun cancelledUnlockCompletesUnderContention() = runTest(timeout = 5.seconds) {
val mutex = SmartMutex.Mutable()
// Delegate this acquisition's release to another coroutine. The
// unconfined collector runs while lock() still holds its internal mutex.
val releaser = launch(Dispatchers.Unconfined) {
mutex.lockStateFlow.first { it }
currentCoroutineContext().cancel()
mutex.unlock()
}
// Keep acquisition on the normal test dispatcher so the collector
// attempts cancelled cleanup before the internal mutex is released.
mutex.lock()
releaser.join()
assertTrue(releaser.isCancelled)
assertFalse(mutex.isLocked, "Cancellation must not prevent the delegated unlock")
assertTrue(mutex.tryLock())
assertTrue(mutex.unlock())
}
@Test
fun cancellingWithLockBodyReleasesMutex() = runTest(timeout = 5.seconds) {
val mutex = SmartMutex.Mutable()
val holder = launch(Dispatchers.Unconfined) {
mutex.withLock {
awaitCancellation()
}
}
assertTrue(mutex.isLocked)
holder.cancelAndJoin()
assertFalse(mutex.isLocked)
}
@Test
fun cancelledWaiterDoesNotEnterOrReleaseHeldMutex() = runTest(timeout = 5.seconds) {
val mutex = SmartMutex.Mutable()
var entered = false
mutex.withLock {
val waiter = launch(Dispatchers.Unconfined) {
mutex.withLock {
entered = true
}
}
waiter.cancelAndJoin()
assertFalse(entered)
assertTrue(mutex.isLocked)
}
assertFalse(mutex.isLocked)
}
}

View File

@@ -9,6 +9,7 @@ import kotlin.test.assertEquals
import kotlin.test.assertFails import kotlin.test.assertFails
import kotlin.test.assertFalse import kotlin.test.assertFalse
import kotlin.test.assertTrue import kotlin.test.assertTrue
import kotlin.time.Duration.Companion.days
import kotlin.time.Duration.Companion.seconds import kotlin.time.Duration.Companion.seconds
class SmartRWLockerTests { class SmartRWLockerTests {
@@ -109,6 +110,59 @@ class SmartRWLockerTests {
} }
} }
@Test
fun failureOnReadFreeingRead() = runTest {
val locker = SmartRWLocker()
val job = launch {
locker.withReadAcquire {
while (isActive) {
delay(1.days)
}
}
}
locker.readSemaphore.permitsStateFlow.first {
it == locker.readSemaphore.maxPermits - 1
}
job.cancelAndJoin()
locker.readSemaphore.permitsStateFlow.first {
it == locker.readSemaphore.maxPermits
}
}
@Test
fun cancelledReaderReleasesPermitUnderContention() = runTest(timeout = 5.seconds) {
val locker = SmartRWLocker(readPermits = 2)
val reader = launch(Dispatchers.Unconfined) {
locker.withReadAcquire {
awaitCancellation()
}
}
assertEquals(1, locker.readSemaphore.freePermits)
// Observe the second acquisition synchronously while it still holds the
// semaphore's internal mutex. Cancelling the unconfined reader makes its
// cleanup contend for that mutex before the acquisition can release it.
val cancellation = launch(Dispatchers.Unconfined) {
locker.readSemaphore.permitsStateFlow.first { it == 0 }
reader.cancel()
}
// Keep this acquisition on the normal test dispatcher: making it
// unconfined would change the ordering that forces cleanup contention.
locker.withReadAcquire {
cancellation.join()
reader.join()
assertTrue(reader.isCancelled)
assertEquals(
1,
locker.readSemaphore.freePermits,
"The cancelled reader must release its permit while the other reader still holds one"
)
}
assertEquals(2, locker.readSemaphore.freePermits)
}
@Test @Test
fun simpleWithReadAcquireTest() { fun simpleWithReadAcquireTest() {
val locker = SmartRWLocker() val locker = SmartRWLocker()

View File

@@ -0,0 +1,104 @@
import dev.inmo.micro_utils.coroutines.SmartSemaphore
import dev.inmo.micro_utils.coroutines.withAcquire
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.awaitCancellation
import kotlinx.coroutines.cancelAndJoin
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch
import kotlinx.coroutines.test.runTest
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertFalse
import kotlin.test.assertTrue
import kotlin.time.Duration.Companion.seconds
class SmartSemaphoreTests {
@Test
fun cancelledHolderReleasesPermitUnderContention() = runTest(timeout = 5.seconds) {
val semaphore = SmartSemaphore.Mutable(permits = 2)
val holder = launch(Dispatchers.Unconfined) {
semaphore.withAcquire {
awaitCancellation()
}
}
assertEquals(1, semaphore.freePermits)
// The synchronous observer cancels the holder while the second
// acquisition still owns the semaphore's internal changes mutex.
val cancellation = launch(Dispatchers.Unconfined) {
semaphore.permitsStateFlow.first { it == 0 }
holder.cancel()
}
semaphore.withAcquire {
cancellation.join()
holder.join()
assertTrue(holder.isCancelled)
assertEquals(1, semaphore.freePermits, "The cancelled holder must return its permit")
}
assertEquals(2, semaphore.freePermits)
}
@Test
fun cancelledAcquireReturnsPartialPermitsUnderContention() = runTest(timeout = 5.seconds) {
// One permit belongs to another holder; the waiter can acquire two
// permits immediately, but must wait for the third.
val semaphore = SmartSemaphore.Mutable(permits = 3, acquiredPermits = 1)
lateinit var waiter: kotlinx.coroutines.Job
val cancellation = launch(Dispatchers.Unconfined) {
semaphore.permitsStateFlow.first { it == 1 }
waiter.cancel()
}
waiter = launch(Dispatchers.Unconfined) {
semaphore.acquire(3)
}
assertEquals(0, semaphore.freePermits)
assertFalse(waiter.isCompleted)
// Publishing this release resumes the observer while the internal
// mutex is held. The cancelled acquire must wait to roll back safely.
semaphore.release()
cancellation.join()
waiter.join()
assertTrue(waiter.isCancelled)
assertEquals(3, semaphore.freePermits, "Cancellation must return both partially acquired permits")
semaphore.withAcquire(3) {
assertEquals(0, semaphore.freePermits)
}
assertEquals(3, semaphore.freePermits)
}
@Test
fun cancelledAcquireWithoutPermitsDoesNotReleaseAnotherHoldersPermit() = runTest(timeout = 5.seconds) {
val semaphore = SmartSemaphore.Mutable(permits = 1, acquiredPermits = 1)
val waiter = launch(Dispatchers.Unconfined) {
semaphore.acquire()
}
assertFalse(waiter.isCompleted)
waiter.cancelAndJoin()
assertEquals(0, semaphore.freePermits, "A cancelled waiter that acquired nothing must release nothing")
assertTrue(semaphore.release())
assertEquals(1, semaphore.freePermits)
}
@Test
fun tryAcquireUsesAvailablePermits() = runTest {
val semaphore = SmartSemaphore.Mutable(permits = 3)
assertTrue(semaphore.tryAcquire(2))
assertEquals(1, semaphore.freePermits)
assertTrue(semaphore.tryAcquire())
assertEquals(0, semaphore.freePermits)
assertTrue(semaphore.release(3))
assertEquals(3, semaphore.freePermits)
}
@Test
fun tryAcquireWithInsufficientPermitsLeavesStateUnchanged() = runTest {
val semaphore = SmartSemaphore.Mutable(permits = 3, acquiredPermits = 2)
assertFalse(semaphore.tryAcquire(2))
assertEquals(1, semaphore.freePermits)
semaphore.acquire()
assertFalse(semaphore.tryAcquire())
assertEquals(0, semaphore.freePermits)
}
}

View File

@@ -1,7 +1,7 @@
plugins { plugins {
id "org.jetbrains.kotlin.multiplatform" id "org.jetbrains.kotlin.multiplatform"
id "org.jetbrains.kotlin.plugin.serialization" id "org.jetbrains.kotlin.plugin.serialization"
id "com.android.library" id "com.android.kotlin.multiplatform.library"
} }
apply from: "$mppJvmJsWasmJsAndroidLinuxMingwLinuxArm64Project" apply from: "$mppJvmJsWasmJsAndroidLinuxMingwLinuxArm64Project"
@@ -21,11 +21,3 @@ kotlin {
} }
} }
} }
android {
sourceSets {
main {
java.srcDirs += [ "src/jvmMain/kotlin" ]
}
}
}

View File

@@ -1,7 +1,7 @@
plugins { plugins {
id "org.jetbrains.kotlin.multiplatform" id "org.jetbrains.kotlin.multiplatform"
id "org.jetbrains.kotlin.plugin.serialization" id "org.jetbrains.kotlin.plugin.serialization"
id "com.android.library" id "com.android.kotlin.multiplatform.library"
id "org.jetbrains.dokka" id "org.jetbrains.dokka"
} }
@@ -11,13 +11,17 @@ repositories {
mavenCentral() mavenCentral()
} }
apply from: "$defaultAndroidSettings"
kotlin { kotlin {
jvm() jvm()
js(IR) { js(IR) {
browser() browser()
nodejs() nodejs()
} }
androidTarget {} android {
project.ext.configureAndroidTarget(delegate)
}
sourceSets { sourceSets {
commonMain { commonMain {
@@ -137,5 +141,3 @@ dokka {
// } // }
// } // }
//} //}
apply from: "$defaultAndroidSettings"

View File

@@ -1,7 +1,7 @@
plugins { plugins {
id "org.jetbrains.kotlin.multiplatform" id "org.jetbrains.kotlin.multiplatform"
id "org.jetbrains.kotlin.plugin.serialization" id "org.jetbrains.kotlin.plugin.serialization"
id "com.android.library" id "com.android.kotlin.multiplatform.library"
} }
apply from: "$mppJvmJsWasmJsAndroidLinuxMingwLinuxArm64Project" apply from: "$mppJvmJsWasmJsAndroidLinuxMingwLinuxArm64Project"

View File

@@ -1,7 +1,7 @@
plugins { plugins {
id "org.jetbrains.kotlin.multiplatform" id "org.jetbrains.kotlin.multiplatform"
id "org.jetbrains.kotlin.plugin.serialization" id "org.jetbrains.kotlin.plugin.serialization"
id "com.android.library" id "com.android.kotlin.multiplatform.library"
} }
apply from: "$mppJvmJsWasmJsAndroidLinuxMingwLinuxArm64Project" apply from: "$mppJvmJsWasmJsAndroidLinuxMingwLinuxArm64Project"

View File

@@ -1,11 +1,9 @@
kotlin.code.style=official kotlin.code.style=official
org.gradle.parallel=true org.gradle.parallel=true
kotlin.js.generate.externals=true
kotlin.incremental=true kotlin.incremental=true
kotlin.incremental.js=true kotlin.incremental.js=true
#kotlin.experimental.tryK2=true #kotlin.experimental.tryK2=true
android.useAndroidX=true android.useAndroidX=true
android.enableJetifier=true
org.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=2g org.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=2g
## https://github.com/google/ksp/issues/2491 ## https://github.com/google/ksp/issues/2491
@@ -18,5 +16,5 @@ crypto_js_version=4.1.1
# Project data # Project data
group=dev.inmo group=dev.inmo
version=0.30.1 version=0.31.1
android_code_version=316 android_code_version=318

View File

@@ -1,6 +1,6 @@
[versions] [versions]
kt = "2.3.21" kt = "2.4.10"
kt-serialization = "1.11.0" kt-serialization = "1.11.0"
kt-coroutines = "1.11.0" kt-coroutines = "1.11.0"
@@ -8,13 +8,13 @@ kotlinx-browser = "0.5.0"
kslog = "1.7.0" kslog = "1.7.0"
jb-compose = "1.11.1" jb-compose = "1.12.0"
jb-compose-material3 = "1.11.0-alpha07" jb-compose-material3 = "1.11.0-alpha07"
jb-compose-icons = "1.7.8" jb-compose-icons = "1.7.8"
jb-exposed = "1.3.0" jb-exposed = "1.5.0"
jb-dokka = "2.2.0" jb-dokka = "2.2.0"
sqlite = "3.53.2.1" sqlite = "3.53.4.0"
korlibs = "5.4.0" korlibs = "5.4.0"
uuid = "0.8.4" uuid = "0.8.4"
@@ -27,25 +27,25 @@ koin = "4.2.2"
okio = "3.18.1" okio = "3.18.1"
ksp = "2.3.9" ksp = "2.3.11"
kotlin-poet = "2.3.0" kotlin-poet = "2.3.0"
versions = "0.54.0" versions = "0.61.0"
nmcp = "1.5.0" nmcp = "1.6.1"
android-gradle = "8.12.+" android-gradle = "9.1.1"
dexcount = "4.0.0" dexcount = "4.0.0"
android-coreKtx = "1.19.0" android-coreKtx = "1.19.0"
android-recyclerView = "1.4.0" android-recyclerView = "1.4.0"
android-appCompat = "1.7.1" android-appCompat = "1.8.0"
android-fragment = "1.8.9" android-fragment = "1.9.0"
android-espresso = "3.7.0" android-espresso = "3.7.0"
android-test = "1.3.0" android-test = "1.3.0"
android-props-minSdk = "21" android-props-minSdk = "21"
android-props-compileSdk = "36" android-props-compileSdk = "37"
android-props-buildTools = "36.0.0" android-props-buildTools = "37.0.0"
[libraries] [libraries]
@@ -126,5 +126,5 @@ buildscript-android-dexcount = { module = "com.getkeepsafe.dexcount:dexcount-gra
jb-compose = { id = "org.jetbrains.compose", version.ref = "jb-compose" } jb-compose = { id = "org.jetbrains.compose", version.ref = "jb-compose" }
kt-jb-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kt" } kt-jb-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kt" }
versions = { id = "com.github.ben-manes.versions", version.ref = "versions" } versions = { id = "io.github.ben-manes.versions", version.ref = "versions" }
nmcp-aggregation = { id = "com.gradleup.nmcp.aggregation", version.ref = "nmcp" } nmcp-aggregation = { id = "com.gradleup.nmcp.aggregation", version.ref = "nmcp" }

View File

@@ -1,6 +1,6 @@
kotlin { kotlin {
sourceSets { sourceSets {
androidUnitTest { androidHostTest {
dependencies { dependencies {
implementation compose.uiTest implementation compose.uiTest
} }

View File

@@ -1,34 +1,18 @@
apply plugin: 'com.getkeepsafe.dexcount' apply plugin: 'com.getkeepsafe.dexcount'
android { ext.configureAndroidTarget = { target ->
compileSdkVersion libs.versions.android.props.compileSdk.get().toInteger() target.compileSdk = libs.versions.android.props.compileSdk.get().toInteger()
buildToolsVersion libs.versions.android.props.buildTools.get() target.buildToolsVersion = libs.versions.android.props.buildTools.get()
target.minSdk = libs.versions.android.props.minSdk.get().toInteger()
defaultConfig { target.namespace = "${project.group}.${project.name}"
minSdkVersion libs.versions.android.props.minSdk.get().toInteger() target.packaging {
compileSdkVersion libs.versions.android.props.compileSdk.get().toInteger() resources {
targetSdkVersion libs.versions.android.props.compileSdk.get().toInteger() excludes.add 'META-INF/kotlinx-serialization-runtime.kotlin_module'
versionCode "${android_code_version}".toInteger() excludes.add 'META-INF/kotlinx-serialization-cbor.kotlin_module'
versionName "$version" excludes.add 'META-INF/kotlinx-serialization-properties.kotlin_module'
namespace "${project.group}.${project.name}"
}
buildTypes {
release {
minifyEnabled false
}
debug {
debuggable true
} }
} }
target.compilerOptions.jvmTarget.set(
packagingOptions { target.compilerOptions.jvmTarget.get().class.fromTarget("17")
exclude 'META-INF/kotlinx-serialization-runtime.kotlin_module' )
exclude 'META-INF/kotlinx-serialization-cbor.kotlin_module'
exclude 'META-INF/kotlinx-serialization-properties.kotlin_module'
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
}
} }

View File

@@ -1,25 +1,31 @@
apply from: "$defaultAndroidSettings"
kotlin { kotlin {
androidTarget { android {
publishLibraryVariants( project.ext.configureAndroidTarget(delegate)
"release", withHostTest {}
"debug", withDeviceTest {}
)
compilations.all {
kotlinOptions {
jvmTarget = "17"
}
}
} }
sourceSets { sourceSets {
androidUnitTest { jvmAndAndroidMain {
dependsOn commonMain
kotlin.srcDir("src/jvmMain/kotlin")
resources.srcDir("src/jvmMain/resources")
}
jvmMain {
dependsOn jvmAndAndroidMain
kotlin.setSrcDirs([])
resources.setSrcDirs([])
}
androidHostTest {
dependencies { dependencies {
implementation kotlin('test-junit') implementation kotlin('test-junit')
implementation libs.android.test.junit implementation libs.android.test.junit
implementation libs.android.espresso implementation libs.android.espresso
} }
} }
androidInstrumentedTest { androidDeviceTest {
dependencies { dependencies {
implementation kotlin('test-junit') implementation kotlin('test-junit')
implementation libs.android.test.junit implementation libs.android.test.junit
@@ -27,8 +33,6 @@ kotlin {
} }
} }
androidMain.dependsOn jvmMain androidMain.dependsOn jvmAndAndroidMain
} }
} }
apply from: "$defaultAndroidSettings"

View File

@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-9.3.0-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-9.3.1-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

View File

@@ -1,7 +1,7 @@
plugins { plugins {
id "org.jetbrains.kotlin.multiplatform" id "org.jetbrains.kotlin.multiplatform"
id "org.jetbrains.kotlin.plugin.serialization" id "org.jetbrains.kotlin.plugin.serialization"
id "com.android.library" id "com.android.kotlin.multiplatform.library"
} }
apply from: "$mppJvmJsWasmJsAndroidLinuxMingwLinuxArm64Project" apply from: "$mppJvmJsWasmJsAndroidLinuxMingwLinuxArm64Project"
@@ -14,7 +14,7 @@ kotlin {
api libs.uuid api libs.uuid
} }
} }
jvmMain { jvmAndAndroidMain {
dependencies { dependencies {
api libs.kt.reflect api libs.kt.reflect
api project(":micro_utils.coroutines") api project(":micro_utils.coroutines")

View File

@@ -1,7 +1,7 @@
plugins { plugins {
id "org.jetbrains.kotlin.multiplatform" id "org.jetbrains.kotlin.multiplatform"
id "org.jetbrains.kotlin.plugin.serialization" id "org.jetbrains.kotlin.plugin.serialization"
id "com.android.library" id "com.android.kotlin.multiplatform.library"
id "com.google.devtools.ksp" id "com.google.devtools.ksp"
} }

View File

@@ -1,7 +1,7 @@
plugins { plugins {
id "org.jetbrains.kotlin.multiplatform" id "org.jetbrains.kotlin.multiplatform"
id "org.jetbrains.kotlin.plugin.serialization" id "org.jetbrains.kotlin.plugin.serialization"
id "com.android.library" id "com.android.kotlin.multiplatform.library"
} }
apply from: "$mppJvmJsWasmJsAndroidLinuxMingwLinuxArm64Project" apply from: "$mppJvmJsWasmJsAndroidLinuxMingwLinuxArm64Project"

View File

@@ -1,7 +1,7 @@
plugins { plugins {
id "org.jetbrains.kotlin.multiplatform" id "org.jetbrains.kotlin.multiplatform"
id "org.jetbrains.kotlin.plugin.serialization" id "org.jetbrains.kotlin.plugin.serialization"
id "com.android.library" id "com.android.kotlin.multiplatform.library"
id "com.google.devtools.ksp" id "com.google.devtools.ksp"
} }

View File

@@ -1,7 +1,7 @@
plugins { plugins {
id "org.jetbrains.kotlin.multiplatform" id "org.jetbrains.kotlin.multiplatform"
id "org.jetbrains.kotlin.plugin.serialization" id "org.jetbrains.kotlin.plugin.serialization"
id "com.android.library" id "com.android.kotlin.multiplatform.library"
} }
apply from: "$mppJvmJsWasmJsAndroidLinuxMingwLinuxArm64Project" apply from: "$mppJvmJsWasmJsAndroidLinuxMingwLinuxArm64Project"

View File

@@ -1,7 +1,7 @@
plugins { plugins {
id "org.jetbrains.kotlin.multiplatform" id "org.jetbrains.kotlin.multiplatform"
id "org.jetbrains.kotlin.plugin.serialization" id "org.jetbrains.kotlin.plugin.serialization"
id "com.android.library" id "com.android.kotlin.multiplatform.library"
id "com.google.devtools.ksp" id "com.google.devtools.ksp"
} }

View File

@@ -1,7 +1,7 @@
plugins { plugins {
id "org.jetbrains.kotlin.multiplatform" id "org.jetbrains.kotlin.multiplatform"
id "org.jetbrains.kotlin.plugin.serialization" id "org.jetbrains.kotlin.plugin.serialization"
id "com.android.library" id "com.android.kotlin.multiplatform.library"
} }
apply from: "$mppJvmJsWasmJsAndroidLinuxMingwLinuxArm64Project" apply from: "$mppJvmJsWasmJsAndroidLinuxMingwLinuxArm64Project"

View File

@@ -1,7 +1,7 @@
plugins { plugins {
id "org.jetbrains.kotlin.multiplatform" id "org.jetbrains.kotlin.multiplatform"
id "org.jetbrains.kotlin.plugin.serialization" id "org.jetbrains.kotlin.plugin.serialization"
id "com.android.library" id "com.android.kotlin.multiplatform.library"
id "com.google.devtools.ksp" id "com.google.devtools.ksp"
} }

View File

@@ -1,7 +1,7 @@
plugins { plugins {
id "org.jetbrains.kotlin.multiplatform" id "org.jetbrains.kotlin.multiplatform"
id "org.jetbrains.kotlin.plugin.serialization" id "org.jetbrains.kotlin.plugin.serialization"
id "com.android.library" id "com.android.kotlin.multiplatform.library"
} }
apply from: "$mppJvmJsWasmJsAndroidLinuxMingwLinuxArm64Project" apply from: "$mppJvmJsWasmJsAndroidLinuxMingwLinuxArm64Project"

View File

@@ -1,7 +1,7 @@
plugins { plugins {
id "org.jetbrains.kotlin.multiplatform" id "org.jetbrains.kotlin.multiplatform"
id "org.jetbrains.kotlin.plugin.serialization" id "org.jetbrains.kotlin.plugin.serialization"
id "com.android.library" id "com.android.kotlin.multiplatform.library"
} }
apply from: "$mppJvmJsWasmJsAndroidLinuxMingwLinuxArm64Project" apply from: "$mppJvmJsWasmJsAndroidLinuxMingwLinuxArm64Project"

View File

@@ -1,7 +1,7 @@
plugins { plugins {
id "org.jetbrains.kotlin.multiplatform" id "org.jetbrains.kotlin.multiplatform"
id "org.jetbrains.kotlin.plugin.serialization" id "org.jetbrains.kotlin.plugin.serialization"
id "com.android.library" id "com.android.kotlin.multiplatform.library"
} }
apply from: "$mppJvmJsWasmJsAndroidLinuxMingwLinuxArm64Project" apply from: "$mppJvmJsWasmJsAndroidLinuxMingwLinuxArm64Project"

View File

@@ -1,7 +1,7 @@
plugins { plugins {
id "org.jetbrains.kotlin.multiplatform" id "org.jetbrains.kotlin.multiplatform"
id "org.jetbrains.kotlin.plugin.serialization" id "org.jetbrains.kotlin.plugin.serialization"
id "com.android.library" id "com.android.kotlin.multiplatform.library"
} }
apply from: "$mppJvmJsWasmJsAndroidLinuxMingwLinuxArm64Project" apply from: "$mppJvmJsWasmJsAndroidLinuxMingwLinuxArm64Project"

View File

@@ -1,7 +1,7 @@
plugins { plugins {
id "org.jetbrains.kotlin.multiplatform" id "org.jetbrains.kotlin.multiplatform"
id "org.jetbrains.kotlin.plugin.serialization" id "org.jetbrains.kotlin.plugin.serialization"
id "com.android.library" id "com.android.kotlin.multiplatform.library"
} }
apply from: "$mppJvmJsWasmJsAndroidLinuxMingwLinuxArm64Project" apply from: "$mppJvmJsWasmJsAndroidLinuxMingwLinuxArm64Project"

View File

@@ -11,7 +11,7 @@ package dev.inmo.micro_utils.meta
RequiresOptIn.Level.WARNING RequiresOptIn.Level.WARNING
) )
@Target( @Target(
AnnotationTarget.FIELD, AnnotationTarget.PROPERTY,
) )
@Retention(AnnotationRetention.BINARY) @Retention(AnnotationRetention.BINARY)
annotation class MetaContainerRootMapWarning annotation class MetaContainerRootMapWarning

View File

@@ -1,7 +1,7 @@
plugins { plugins {
id "org.jetbrains.kotlin.multiplatform" id "org.jetbrains.kotlin.multiplatform"
id "org.jetbrains.kotlin.plugin.serialization" id "org.jetbrains.kotlin.plugin.serialization"
id "com.android.library" id "com.android.kotlin.multiplatform.library"
} }
apply from: "$mppJvmJsWasmJsAndroidLinuxMingwLinuxArm64Project" apply from: "$mppJvmJsWasmJsAndroidLinuxMingwLinuxArm64Project"

View File

@@ -1,7 +1,7 @@
plugins { plugins {
id "org.jetbrains.kotlin.multiplatform" id "org.jetbrains.kotlin.multiplatform"
id "org.jetbrains.kotlin.plugin.serialization" id "org.jetbrains.kotlin.plugin.serialization"
id "com.android.library" id "com.android.kotlin.multiplatform.library"
} }
apply from: "$mppJvmJsWasmJsAndroidLinuxMingwLinuxArm64Project" apply from: "$mppJvmJsWasmJsAndroidLinuxMingwLinuxArm64Project"

View File

@@ -1,7 +1,7 @@
plugins { plugins {
id "org.jetbrains.kotlin.multiplatform" id "org.jetbrains.kotlin.multiplatform"
id "org.jetbrains.kotlin.plugin.serialization" id "org.jetbrains.kotlin.plugin.serialization"
id "com.android.library" id "com.android.kotlin.multiplatform.library"
alias(libs.plugins.jb.compose) alias(libs.plugins.jb.compose)
alias(libs.plugins.kt.jb.compose) alias(libs.plugins.kt.jb.compose)
} }

View File

@@ -1,7 +1,7 @@
plugins { plugins {
id "org.jetbrains.kotlin.multiplatform" id "org.jetbrains.kotlin.multiplatform"
id "org.jetbrains.kotlin.plugin.serialization" id "org.jetbrains.kotlin.plugin.serialization"
id "com.android.library" id "com.android.kotlin.multiplatform.library"
} }
apply from: "$mppJvmJsWasmJsAndroidLinuxMingwLinuxArm64Project" apply from: "$mppJvmJsWasmJsAndroidLinuxMingwLinuxArm64Project"

View File

@@ -1,7 +1,7 @@
plugins { plugins {
id "org.jetbrains.kotlin.multiplatform" id "org.jetbrains.kotlin.multiplatform"
id "org.jetbrains.kotlin.plugin.serialization" id "org.jetbrains.kotlin.plugin.serialization"
id "com.android.library" id "com.android.kotlin.multiplatform.library"
} }
apply from: "$mppJvmJsWasmJsAndroidLinuxMingwLinuxArm64Project" apply from: "$mppJvmJsWasmJsAndroidLinuxMingwLinuxArm64Project"

View File

@@ -1,7 +1,7 @@
plugins { plugins {
id "org.jetbrains.kotlin.multiplatform" id "org.jetbrains.kotlin.multiplatform"
id "org.jetbrains.kotlin.plugin.serialization" id "org.jetbrains.kotlin.plugin.serialization"
id "com.android.library" id "com.android.kotlin.multiplatform.library"
} }
apply from: "$mppJvmJsWasmJsAndroidLinuxMingwLinuxArm64Project" apply from: "$mppJvmJsWasmJsAndroidLinuxMingwLinuxArm64Project"
@@ -17,7 +17,7 @@ kotlin {
} }
} }
jvmMain { jvmAndAndroidMain {
dependencies { dependencies {
api internalProject("micro_utils.common") api internalProject("micro_utils.common")
} }

View File

@@ -1,12 +1,14 @@
plugins { plugins {
id "org.jetbrains.kotlin.multiplatform" id "org.jetbrains.kotlin.multiplatform"
id "org.jetbrains.kotlin.plugin.serialization" id "org.jetbrains.kotlin.plugin.serialization"
id "com.android.library" id "com.android.kotlin.multiplatform.library"
} }
project.version = "$version" project.version = "$version"
project.group = "$group" project.group = "$group"
apply from: "$defaultAndroidSettings"
kotlin { kotlin {
jvm { jvm {
compilations.main { compilations.main {
@@ -23,12 +25,8 @@ kotlin {
browser() browser()
nodejs() nodejs()
} }
androidTarget { android {
compilations.all { project.ext.configureAndroidTarget(delegate)
kotlinOptions {
jvmTarget = "17"
}
}
} }
linuxX64() linuxX64()
mingwX64() mingwX64()
@@ -51,6 +49,11 @@ kotlin {
implementation kotlin('test-junit') implementation kotlin('test-junit')
} }
} }
androidMain {
dependencies {
implementation kotlin('test-junit')
}
}
jsMain { jsMain {
dependencies { dependencies {
implementation kotlin('test-js') implementation kotlin('test-js')
@@ -61,13 +64,10 @@ kotlin {
mingwX64Main.dependsOn nativeMain mingwX64Main.dependsOn nativeMain
linuxArm64Main.dependsOn nativeMain linuxArm64Main.dependsOn nativeMain
androidMain.dependsOn jvmMain
} }
} }
apply from: "$defaultAndroidSettings"
java { java {
sourceCompatibility = JavaVersion.VERSION_17 sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17 targetCompatibility = JavaVersion.VERSION_17
} }

View File

@@ -1,7 +1,7 @@
plugins { plugins {
id "org.jetbrains.kotlin.multiplatform" id "org.jetbrains.kotlin.multiplatform"
id "org.jetbrains.kotlin.plugin.serialization" id "org.jetbrains.kotlin.plugin.serialization"
id "com.android.library" id "com.android.kotlin.multiplatform.library"
id "com.google.devtools.ksp" id "com.google.devtools.ksp"
} }

View File

@@ -1,7 +1,7 @@
plugins { plugins {
id "org.jetbrains.kotlin.multiplatform" id "org.jetbrains.kotlin.multiplatform"
id "org.jetbrains.kotlin.plugin.serialization" id "org.jetbrains.kotlin.plugin.serialization"
id "com.android.library" id "com.android.kotlin.multiplatform.library"
} }
apply from: "$mppJvmJsWasmJsAndroidLinuxMingwLinuxArm64Project" apply from: "$mppJvmJsWasmJsAndroidLinuxMingwLinuxArm64Project"
@@ -20,4 +20,4 @@ kotlin {
} }
} }
} }
} }

View File

@@ -1,7 +1,7 @@
plugins { plugins {
id "org.jetbrains.kotlin.multiplatform" id "org.jetbrains.kotlin.multiplatform"
id "org.jetbrains.kotlin.plugin.serialization" id "org.jetbrains.kotlin.plugin.serialization"
id "com.android.library" id "com.android.kotlin.multiplatform.library"
} }
apply from: "$mppJvmJsWasmJsAndroidLinuxMingwLinuxArm64Project" apply from: "$mppJvmJsWasmJsAndroidLinuxMingwLinuxArm64Project"

View File

@@ -1,7 +1,7 @@
plugins { plugins {
id "org.jetbrains.kotlin.multiplatform" id "org.jetbrains.kotlin.multiplatform"
id "org.jetbrains.kotlin.plugin.serialization" id "org.jetbrains.kotlin.plugin.serialization"
id "com.android.library" id "com.android.kotlin.multiplatform.library"
} }
apply from: "$mppJvmJsWasmJsAndroidLinuxMingwLinuxArm64Project" apply from: "$mppJvmJsWasmJsAndroidLinuxMingwLinuxArm64Project"

View File

@@ -1,7 +1,7 @@
plugins { plugins {
id "org.jetbrains.kotlin.multiplatform" id "org.jetbrains.kotlin.multiplatform"
id "org.jetbrains.kotlin.plugin.serialization" id "org.jetbrains.kotlin.plugin.serialization"
id "com.android.library" id "com.android.kotlin.multiplatform.library"
} }
apply from: "$mppJvmJsWasmJsAndroidLinuxMingwLinuxArm64Project" apply from: "$mppJvmJsWasmJsAndroidLinuxMingwLinuxArm64Project"

View File

@@ -1,7 +1,7 @@
plugins { plugins {
id "org.jetbrains.kotlin.multiplatform" id "org.jetbrains.kotlin.multiplatform"
id "org.jetbrains.kotlin.plugin.serialization" id "org.jetbrains.kotlin.plugin.serialization"
id "com.android.library" id "com.android.kotlin.multiplatform.library"
} }
apply from: "$mppJvmJsWasmJsAndroidLinuxMingwLinuxArm64Project" apply from: "$mppJvmJsWasmJsAndroidLinuxMingwLinuxArm64Project"

View File

@@ -1,7 +1,7 @@
plugins { plugins {
id "org.jetbrains.kotlin.multiplatform" id "org.jetbrains.kotlin.multiplatform"
id "org.jetbrains.kotlin.plugin.serialization" id "org.jetbrains.kotlin.plugin.serialization"
id "com.android.library" id "com.android.kotlin.multiplatform.library"
} }
apply from: "$mppJvmJsWasmJsAndroidLinuxMingwLinuxArm64Project" apply from: "$mppJvmJsWasmJsAndroidLinuxMingwLinuxArm64Project"

View File

@@ -1,7 +1,7 @@
plugins { plugins {
id "org.jetbrains.kotlin.multiplatform" id "org.jetbrains.kotlin.multiplatform"
id "org.jetbrains.kotlin.plugin.serialization" id "org.jetbrains.kotlin.plugin.serialization"
id "com.android.library" id "com.android.kotlin.multiplatform.library"
} }
apply from: "$mppJvmJsWasmJsAndroidLinuxMingwLinuxArm64Project" apply from: "$mppJvmJsWasmJsAndroidLinuxMingwLinuxArm64Project"

View File

@@ -1,7 +1,7 @@
plugins { plugins {
id "org.jetbrains.kotlin.multiplatform" id "org.jetbrains.kotlin.multiplatform"
id "org.jetbrains.kotlin.plugin.serialization" id "org.jetbrains.kotlin.plugin.serialization"
id "com.android.library" id "com.android.kotlin.multiplatform.library"
} }
apply from: "$mppJvmJsWasmJsAndroidLinuxMingwLinuxArm64Project" apply from: "$mppJvmJsWasmJsAndroidLinuxMingwLinuxArm64Project"

View File

@@ -1,7 +1,7 @@
plugins { plugins {
id "org.jetbrains.kotlin.multiplatform" id "org.jetbrains.kotlin.multiplatform"
id "org.jetbrains.kotlin.plugin.serialization" id "org.jetbrains.kotlin.plugin.serialization"
id "com.android.library" id "com.android.kotlin.multiplatform.library"
} }
apply from: "$mppJvmJsWasmJsAndroidLinuxMingwLinuxArm64Project" apply from: "$mppJvmJsWasmJsAndroidLinuxMingwLinuxArm64Project"

View File

@@ -1,7 +1,7 @@
plugins { plugins {
id "org.jetbrains.kotlin.multiplatform" id "org.jetbrains.kotlin.multiplatform"
id "org.jetbrains.kotlin.plugin.serialization" id "org.jetbrains.kotlin.plugin.serialization"
id "com.android.library" id "com.android.kotlin.multiplatform.library"
} }
apply from: "$mppJvmJsWasmJsAndroidLinuxMingwLinuxArm64Project" apply from: "$mppJvmJsWasmJsAndroidLinuxMingwLinuxArm64Project"

View File

@@ -1,7 +1,7 @@
plugins { plugins {
id "org.jetbrains.kotlin.multiplatform" id "org.jetbrains.kotlin.multiplatform"
id "org.jetbrains.kotlin.plugin.serialization" id "org.jetbrains.kotlin.plugin.serialization"
id "com.android.library" id "com.android.kotlin.multiplatform.library"
alias(libs.plugins.compose) alias(libs.plugins.compose)
} }

View File

@@ -1,7 +1,7 @@
plugins { plugins {
id "org.jetbrains.kotlin.multiplatform" id "org.jetbrains.kotlin.multiplatform"
id "org.jetbrains.kotlin.plugin.serialization" id "org.jetbrains.kotlin.plugin.serialization"
id "com.android.library" id "com.android.kotlin.multiplatform.library"
} }
apply from: "$mppJvmJsWasmJsAndroidLinuxMingwLinuxArm64Project" apply from: "$mppJvmJsWasmJsAndroidLinuxMingwLinuxArm64Project"

View File

@@ -1,7 +1,7 @@
plugins { plugins {
id "org.jetbrains.kotlin.multiplatform" id "org.jetbrains.kotlin.multiplatform"
id "org.jetbrains.kotlin.plugin.serialization" id "org.jetbrains.kotlin.plugin.serialization"
id "com.android.library" id "com.android.kotlin.multiplatform.library"
} }
apply from: "$mppJvmJsWasmJsAndroidLinuxMingwLinuxArm64Project" apply from: "$mppJvmJsWasmJsAndroidLinuxMingwLinuxArm64Project"