From b85c275c8f7eabc26fc15c6a80f9e2170c9d7c57 Mon Sep 17 00:00:00 2001 From: Alexey Tsvetkov Date: Wed, 9 Aug 2023 14:25:35 +0200 Subject: [PATCH] Set Kotlin/Native cache kind based on Kotlin version Resolves #2046 Resolves #2386 --- .../org/jetbrains/compose/ComposePlugin.kt | 3 + .../internal/ComposeProjectProperties.kt | 22 ++-- .../configureNativeCompilerCaching.kt | 114 ++++++++++++++++++ .../internal/utils/IosGradleProperties.kt | 4 +- .../internal/utils/KGPPropertyProvider.kt | 35 ++++++ .../compose/internal/utils/fileUtils.kt | 13 +- .../compose/internal/utils/gradleUtils.kt | 11 ++ .../compose/internal/utils/providerUtils.kt | 2 +- .../tests/integration/GradlePluginTest.kt | 26 ++++ .../compose/test/utils/TestKotlinVersions.kt | 2 + .../compose/test/utils/TestProjects.kt | 1 + .../misc/nativeCacheKind/build.gradle | 27 +++++ .../misc/nativeCacheKind/gradle.properties | 1 + .../misc/nativeCacheKind/settings.gradle | 12 ++ .../src/commonMain/kotlin/App.kt | 10 ++ 15 files changed, 268 insertions(+), 15 deletions(-) create mode 100644 gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/experimental/internal/configureNativeCompilerCaching.kt create mode 100644 gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/internal/utils/KGPPropertyProvider.kt create mode 100644 gradle-plugins/compose/src/test/test-projects/misc/nativeCacheKind/build.gradle create mode 100644 gradle-plugins/compose/src/test/test-projects/misc/nativeCacheKind/gradle.properties create mode 100644 gradle-plugins/compose/src/test/test-projects/misc/nativeCacheKind/settings.gradle create mode 100644 gradle-plugins/compose/src/test/test-projects/misc/nativeCacheKind/src/commonMain/kotlin/App.kt diff --git a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/ComposePlugin.kt b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/ComposePlugin.kt index 041a68bb4a6..1fd2edcf6bd 100644 --- a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/ComposePlugin.kt +++ b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/ComposePlugin.kt @@ -21,6 +21,7 @@ import org.jetbrains.compose.desktop.preview.internal.initializePreview import org.jetbrains.compose.experimental.dsl.ExperimentalExtension import org.jetbrains.compose.experimental.internal.configureExperimentalTargetsFlagsCheck import org.jetbrains.compose.experimental.internal.configureExperimental +import org.jetbrains.compose.experimental.internal.configureNativeCompilerCaching import org.jetbrains.compose.experimental.uikit.internal.resources.configureSyncTask import org.jetbrains.compose.internal.KOTLIN_MPP_PLUGIN_ID import org.jetbrains.compose.internal.mppExt @@ -32,6 +33,7 @@ import org.jetbrains.kotlin.gradle.plugin.getKotlinPluginVersion import org.jetbrains.kotlin.gradle.dsl.KotlinCompile import org.jetbrains.kotlin.gradle.dsl.KotlinJsCompile import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType +import java.util.* internal val composeVersion get() = ComposeBuildConfig.composeVersion @@ -52,6 +54,7 @@ class ComposePlugin : Plugin { composeExtension.extensions.create("web", WebExtension::class.java) project.plugins.apply(ComposeCompilerKotlinSupportPlugin::class.java) + project.configureNativeCompilerCaching() project.afterEvaluate { configureDesktop(project, desktopExtension) diff --git a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/desktop/application/internal/ComposeProjectProperties.kt b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/desktop/application/internal/ComposeProjectProperties.kt index ab1011bc808..08123a41254 100644 --- a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/desktop/application/internal/ComposeProjectProperties.kt +++ b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/desktop/application/internal/ComposeProjectProperties.kt @@ -7,7 +7,7 @@ package org.jetbrains.compose.desktop.application.internal import org.gradle.api.provider.Provider import org.gradle.api.provider.ProviderFactory -import org.jetbrains.compose.internal.utils.findProperty +import org.jetbrains.compose.internal.utils.valueOrNull import org.jetbrains.compose.internal.utils.toBooleanProvider internal object ComposeProperties { @@ -23,32 +23,32 @@ internal object ComposeProperties { internal const val CHECK_JDK_VENDOR = "compose.desktop.packaging.checkJdkVendor" fun isVerbose(providers: ProviderFactory): Provider = - providers.findProperty(VERBOSE).toBooleanProvider(false) + providers.valueOrNull(VERBOSE).toBooleanProvider(false) fun preserveWorkingDir(providers: ProviderFactory): Provider = - providers.findProperty(PRESERVE_WD).toBooleanProvider(false) + providers.valueOrNull(PRESERVE_WD).toBooleanProvider(false) fun macSign(providers: ProviderFactory): Provider = - providers.findProperty(MAC_SIGN).toBooleanProvider(false) + providers.valueOrNull(MAC_SIGN).toBooleanProvider(false) fun macSignIdentity(providers: ProviderFactory): Provider = - providers.findProperty(MAC_SIGN_ID) + providers.valueOrNull(MAC_SIGN_ID) fun macSignKeychain(providers: ProviderFactory): Provider = - providers.findProperty(MAC_SIGN_KEYCHAIN) + providers.valueOrNull(MAC_SIGN_KEYCHAIN) fun macSignPrefix(providers: ProviderFactory): Provider = - providers.findProperty(MAC_SIGN_PREFIX) + providers.valueOrNull(MAC_SIGN_PREFIX) fun macNotarizationAppleID(providers: ProviderFactory): Provider = - providers.findProperty(MAC_NOTARIZATION_APPLE_ID) + providers.valueOrNull(MAC_NOTARIZATION_APPLE_ID) fun macNotarizationPassword(providers: ProviderFactory): Provider = - providers.findProperty(MAC_NOTARIZATION_PASSWORD) + providers.valueOrNull(MAC_NOTARIZATION_PASSWORD) fun macNotarizationAscProvider(providers: ProviderFactory): Provider = - providers.findProperty(MAC_NOTARIZATION_ASC_PROVIDER) + providers.valueOrNull(MAC_NOTARIZATION_ASC_PROVIDER) fun checkJdkVendor(providers: ProviderFactory): Provider = - providers.findProperty(CHECK_JDK_VENDOR).toBooleanProvider(true) + providers.valueOrNull(CHECK_JDK_VENDOR).toBooleanProvider(true) } \ No newline at end of file diff --git a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/experimental/internal/configureNativeCompilerCaching.kt b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/experimental/internal/configureNativeCompilerCaching.kt new file mode 100644 index 00000000000..2695e33c3b3 --- /dev/null +++ b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/experimental/internal/configureNativeCompilerCaching.kt @@ -0,0 +1,114 @@ +/* + * Copyright 2020-2023 JetBrains s.r.o. and respective authors and developers. + * Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE.txt file. + */ + +package org.jetbrains.compose.experimental.internal + +import org.gradle.api.Project +import org.jetbrains.compose.internal.KOTLIN_MPP_PLUGIN_ID +import org.jetbrains.compose.internal.mppExt +import org.jetbrains.compose.internal.utils.KGPPropertyProvider +import org.jetbrains.compose.internal.utils.configureEachWithType +import org.jetbrains.kotlin.gradle.plugin.getKotlinPluginVersion +import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget +import org.jetbrains.kotlin.konan.target.presetName + +private const val PROJECT_CACHE_KIND_PROPERTY_NAME = "kotlin.native.cacheKind" +private const val COMPOSE_NATIVE_MANAGE_CACHE_KIND = "compose.kotlin.native.manageCacheKind" +private const val NONE_VALUE = "none" + +internal fun Project.configureNativeCompilerCaching() { + if (findProperty(COMPOSE_NATIVE_MANAGE_CACHE_KIND) == "false") return + + plugins.withId(KOTLIN_MPP_PLUGIN_ID) { + val kotlinVersion = kotlinVersionNumbers(this) + mppExt.targets.configureEachWithType { + assertCacheKindUserValueIsNotNone() + configureTargetCompilerCache(kotlinVersion) + } + } +} + +private fun KotlinNativeTarget.assertCacheKindUserValueIsNotNone() { + // To determine cache kind KGP checks kotlin.native.cacheKind. first, then kotlin.native.cacheKind + // For each property it tries to read Project.property, then checks local.properties + // See https://github.com/JetBrains/kotlin/blob/d4d30dcfcf1afb083f09279c6f1ba05031efeabb/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/PropertiesProvider.kt#L416 + val cacheKindProperties = listOf(targetCacheKindPropertyName, PROJECT_CACHE_KIND_PROPERTY_NAME) + val propertyProviders = listOf( + KGPPropertyProvider.GradleProperties(project), + KGPPropertyProvider.LocalProperties(project) + ) + + for (cacheKindProperty in cacheKindProperties) { + for (provider in propertyProviders) { + val value = provider.valueOrNull(cacheKindProperty) + if (value != null) { + if (value.equals(NONE_VALUE, ignoreCase = true)) { + project.logger.warn(cacheKindPropertyWarningMessage(cacheKindProperty, provider)) + } + return + } + } + } +} + +private fun cacheKindPropertyWarningMessage( + cacheKindProperty: String, + provider: KGPPropertyProvider +) = """ + |Warning: '$cacheKindProperty' is explicitly set to `none`. + |This option significantly slows the Kotlin/Native compiler. + |Compose Multiplatform Gradle plugin can set this property automatically, + |when it is necessary. + | * Recommended action: remove explicit '$cacheKindProperty=$NONE_VALUE' from ${provider.location}. + | * Alternative action: if you are sure you need '$cacheKindProperty=$NONE_VALUE', disable + |this warning by adding '$COMPOSE_NATIVE_MANAGE_CACHE_KIND=false' to your 'gradle.properties'. +""".trimMargin() + +private fun KotlinNativeTarget.configureTargetCompilerCache(kotlinVersion: KotlinVersionNumbers) { + val (majorVer, minorVer, patchVer) = kotlinVersion + // See comments in https://youtrack.jetbrains.com/issue/KT-57329 + // When: + // KotlinVersion < 1.9.0, => set cacheKind=none + // 1.9.0 <= KotlinVersion < 1.9.20 => add -Xlazy-ir-for-caches=disable + // KotlinVersion >= 1.9.20 => do nothing, everything should work as is + when { + majorVer < 1 || majorVer == 1 && minorVer < 9 -> { + disableKotlinNativeCache() + } + majorVer == 1 && minorVer == 9 && patchVer < 20 -> { + disableLazyIrForCaches() + } + else -> {} + } +} + +private val KotlinNativeTarget.targetCacheKindPropertyName: String + get() = "$PROJECT_CACHE_KIND_PROPERTY_NAME.${konanTarget.presetName}" +private fun KotlinNativeTarget.disableKotlinNativeCache() { + if (project.hasProperty(targetCacheKindPropertyName)) { + project.setProperty(targetCacheKindPropertyName, NONE_VALUE) + } else { + project.extensions.extraProperties.set(targetCacheKindPropertyName, NONE_VALUE) + } +} + +private fun KotlinNativeTarget.disableLazyIrForCaches() { + compilations.configureEach { compilation -> + compilation.kotlinOptions.freeCompilerArgs += listOf("-Xlazy-ir-for-caches=disable") + } +} + +private data class KotlinVersionNumbers(val major: Int, val minor: Int, val patch: Int) + +private fun kotlinVersionNumbers(project: Project): KotlinVersionNumbers { + val version = project.getKotlinPluginVersion() + val m = Regex("(\\d+)\\.(\\d+)\\.(\\d+)").find(version) ?: error("Kotlin version has unexpected format: '$version'") + val (_, majorPart, minorPart, patchPart) = m.groupValues + return KotlinVersionNumbers( + major = majorPart.toIntOrNull() ?: error("Could not parse major part '$majorPart' of Kotlin plugin version: '$version'"), + minor = minorPart.toIntOrNull() ?: error("Could not parse minor part '$minorPart' of Kotlin plugin version: '$version'"), + patch = patchPart.toIntOrNull() ?: error("Could not parse patch part '$patchPart' of Kotlin plugin version: '$version'"), + ) +} \ No newline at end of file diff --git a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/experimental/uikit/internal/utils/IosGradleProperties.kt b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/experimental/uikit/internal/utils/IosGradleProperties.kt index bfacedbf39e..fa5829b21d4 100644 --- a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/experimental/uikit/internal/utils/IosGradleProperties.kt +++ b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/experimental/uikit/internal/utils/IosGradleProperties.kt @@ -7,12 +7,12 @@ package org.jetbrains.compose.experimental.uikit.internal.utils import org.gradle.api.provider.Provider import org.gradle.api.provider.ProviderFactory -import org.jetbrains.compose.internal.utils.findProperty +import org.jetbrains.compose.internal.utils.valueOrNull import org.jetbrains.compose.internal.utils.toBooleanProvider internal object IosGradleProperties { const val SYNC_RESOURCES_PROPERTY = "org.jetbrains.compose.ios.resources.sync" fun syncResources(providers: ProviderFactory): Provider = - providers.findProperty(SYNC_RESOURCES_PROPERTY).toBooleanProvider(true) + providers.valueOrNull(SYNC_RESOURCES_PROPERTY).toBooleanProvider(true) } \ No newline at end of file diff --git a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/internal/utils/KGPPropertyProvider.kt b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/internal/utils/KGPPropertyProvider.kt new file mode 100644 index 00000000000..bef38b4a257 --- /dev/null +++ b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/internal/utils/KGPPropertyProvider.kt @@ -0,0 +1,35 @@ +/* + * Copyright 2020-2023 JetBrains s.r.o. and respective authors and developers. + * Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE.txt file. + */ + +package org.jetbrains.compose.internal.utils + +import org.gradle.api.Project +import java.util.* + +/** + * Reads Kotlin Gradle plugin properties. + * + * Kotlin Gradle plugin supports reading property from two sources: + * 1. Gradle properties. Normally located in gradle.properties file, + * but can also be provided via command-line, /gradle.properties + * or can be set via Gradle API. + * 2. local.properties file. local.properties file is not supported by Gradle out-of-the-box. + * Nevertheless, it became a widespread convention. + */ +internal abstract class KGPPropertyProvider { + abstract fun valueOrNull(propertyName: String): String? + abstract val location: String + + class GradleProperties(private val project: Project) : KGPPropertyProvider() { + override fun valueOrNull(propertyName: String): String? = project.findProperty(propertyName)?.toString() + override val location: String = "gradle.properties" + } + + class LocalProperties(project: Project) : KGPPropertyProvider() { + private val localProperties: Properties by lazyLoadProperties(project.localPropertiesFile) + override fun valueOrNull(propertyName: String): String? = localProperties.getProperty(propertyName) + override val location: String = "local.properties" + } +} \ No newline at end of file diff --git a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/internal/utils/fileUtils.kt b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/internal/utils/fileUtils.kt index ed4dcec5ed2..cb1cc91f4b7 100644 --- a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/internal/utils/fileUtils.kt +++ b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/internal/utils/fileUtils.kt @@ -12,6 +12,7 @@ import org.gradle.api.file.FileSystemOperations import org.gradle.api.file.RegularFile import org.gradle.api.provider.Provider import java.io.File +import java.util.* internal fun Provider.toDir(project: Project): Provider = project.layout.dir(map { File(it) }) @@ -55,4 +56,14 @@ internal fun FileSystemOperations.clearDirs(vararg dirs: Provider>.ioFiles(): Array = - let { providers -> Array(size) { i -> providers[i].ioFile } } \ No newline at end of file + let { providers -> Array(size) { i -> providers[i].ioFile } } + +internal fun lazyLoadProperties(propertiesFile: File): Lazy = lazy { + Properties().apply { + if (propertiesFile.isFile) { + propertiesFile.inputStream().use { + load(it) + } + } + } +} \ No newline at end of file diff --git a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/internal/utils/gradleUtils.kt b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/internal/utils/gradleUtils.kt index 570262ba67b..4b418218910 100644 --- a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/internal/utils/gradleUtils.kt +++ b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/internal/utils/gradleUtils.kt @@ -5,6 +5,7 @@ package org.jetbrains.compose.internal.utils +import org.gradle.api.DomainObjectCollection import org.gradle.api.Project import org.gradle.api.artifacts.Configuration import org.gradle.api.logging.Logger @@ -61,3 +62,13 @@ internal fun Project.detachedDependency( internal fun Configuration.excludeTransitiveDependencies(): Configuration = apply { isTransitive = false } + +internal inline fun DomainObjectCollection<*>.configureEachWithType( + crossinline fn: SubT.() -> Unit +) { + configureEach { + if (it is SubT) { + it.fn() + } + } +} diff --git a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/internal/utils/providerUtils.kt b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/internal/utils/providerUtils.kt index 955b49dd140..07bd94dd3bc 100644 --- a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/internal/utils/providerUtils.kt +++ b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/internal/utils/providerUtils.kt @@ -30,7 +30,7 @@ internal inline fun Provider.toProperty(objects: ObjectFactory): internal inline fun Task.provider(noinline fn: () -> T): Provider = project.provider(fn) -internal fun ProviderFactory.findProperty(prop: String): Provider = +internal fun ProviderFactory.valueOrNull(prop: String): Provider = provider { gradleProperty(prop).forUseAtConfigurationTimeSafe().orNull } diff --git a/gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/tests/integration/GradlePluginTest.kt b/gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/tests/integration/GradlePluginTest.kt index f32fde4f746..faa6c5657cb 100644 --- a/gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/tests/integration/GradlePluginTest.kt +++ b/gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/tests/integration/GradlePluginTest.kt @@ -108,6 +108,32 @@ class GradlePluginTest : GradlePluginTestBase() { } } + @Test + fun nativeCacheKind() { + Assumptions.assumeTrue(currentOS == OS.MacOS) + fun nativeCacheKindProject(kotlinVersion: String) = testProject( + TestProjects.nativeCacheKind, + defaultTestEnvironment.copy(kotlinVersion = kotlinVersion, useGradleConfigurationCache = false) + ) + + val task = ":linkDebugFrameworkIosX64" + with(nativeCacheKindProject(kotlinVersion = TestKotlinVersions.v1_8_20)) { + gradle(task, "--info").checks { + check.taskSuccessful(task) + check.logDoesntContain("-Xauto-cache-from=") + } + } + testWorkDir.deleteRecursively() + testWorkDir.mkdirs() + with(nativeCacheKindProject(kotlinVersion = TestKotlinVersions.v1_9_0) ) { + gradle(task, "--info").checks { + check.taskSuccessful(task) + check.logContains("-Xauto-cache-from=") + check.logContains("-Xlazy-ir-for-caches=disable") + } + } + } + @Test fun skikoWasm() = with( testProject( diff --git a/gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/utils/TestKotlinVersions.kt b/gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/utils/TestKotlinVersions.kt index bfa4c103363..5dc8a2c5558 100644 --- a/gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/utils/TestKotlinVersions.kt +++ b/gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/utils/TestKotlinVersions.kt @@ -7,4 +7,6 @@ package org.jetbrains.compose.test.utils object TestKotlinVersions { val Default = TestProperties.composeCompilerCompatibleKotlinVersion + val v1_8_20 = "1.8.20" + val v1_9_0 = "1.9.0" } \ No newline at end of file diff --git a/gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/utils/TestProjects.kt b/gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/utils/TestProjects.kt index 8ca826726a4..1b516f6f2ca 100644 --- a/gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/utils/TestProjects.kt +++ b/gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/utils/TestProjects.kt @@ -26,4 +26,5 @@ object TestProjects { const val jvmPreview = "misc/jvmPreview" const val iosResources = "misc/iosResources" const val iosMokoResources = "misc/iosMokoResources" + const val nativeCacheKind = "misc/nativeCacheKind" } \ No newline at end of file diff --git a/gradle-plugins/compose/src/test/test-projects/misc/nativeCacheKind/build.gradle b/gradle-plugins/compose/src/test/test-projects/misc/nativeCacheKind/build.gradle new file mode 100644 index 00000000000..1e43a147b8e --- /dev/null +++ b/gradle-plugins/compose/src/test/test-projects/misc/nativeCacheKind/build.gradle @@ -0,0 +1,27 @@ +plugins { + id "org.jetbrains.kotlin.multiplatform" + id "org.jetbrains.compose" +} + +kotlin { + iosX64 { + binaries.framework { + isStatic = true + baseName = "shared" + } + } + iosArm64 { + binaries.framework { + isStatic = true + baseName = "shared" + } + } + + sourceSets { + commonMain { + dependencies { + implementation(compose.runtime) + } + } + } +} \ No newline at end of file diff --git a/gradle-plugins/compose/src/test/test-projects/misc/nativeCacheKind/gradle.properties b/gradle-plugins/compose/src/test/test-projects/misc/nativeCacheKind/gradle.properties new file mode 100644 index 00000000000..689880ee3f4 --- /dev/null +++ b/gradle-plugins/compose/src/test/test-projects/misc/nativeCacheKind/gradle.properties @@ -0,0 +1 @@ +org.jetbrains.compose.experimental.uikit.enabled=true \ No newline at end of file diff --git a/gradle-plugins/compose/src/test/test-projects/misc/nativeCacheKind/settings.gradle b/gradle-plugins/compose/src/test/test-projects/misc/nativeCacheKind/settings.gradle new file mode 100644 index 00000000000..a270b9409b9 --- /dev/null +++ b/gradle-plugins/compose/src/test/test-projects/misc/nativeCacheKind/settings.gradle @@ -0,0 +1,12 @@ +pluginManagement { + plugins { + id 'org.jetbrains.kotlin.multiplatform' version 'KOTLIN_VERSION_PLACEHOLDER' + id 'org.jetbrains.compose' version 'COMPOSE_GRADLE_PLUGIN_VERSION_PLACEHOLDER' + } + repositories { + mavenLocal() + gradlePluginPortal() + maven { url "https://maven.pkg.jetbrains.space/kotlin/p/kotlin/dev" } + } +} +rootProject.name = "nativeCacheKind" \ No newline at end of file diff --git a/gradle-plugins/compose/src/test/test-projects/misc/nativeCacheKind/src/commonMain/kotlin/App.kt b/gradle-plugins/compose/src/test/test-projects/misc/nativeCacheKind/src/commonMain/kotlin/App.kt new file mode 100644 index 00000000000..2fe6d0719f4 --- /dev/null +++ b/gradle-plugins/compose/src/test/test-projects/misc/nativeCacheKind/src/commonMain/kotlin/App.kt @@ -0,0 +1,10 @@ +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue + +@Composable +fun App() { + var text by remember { mutableStateOf("Hello, World!") } +}