Hello Guys, I'm working on a multi-module Kotlin M...
# gradle
b
Hello Guys, I'm working on a multi-module Kotlin Multiplatform (KMP) project targeting both iOS and Android. I'm attempting to upgrade the Kotlin version from 1.9.23 to 2.0.21, which requires the integration of the Compose Compiler Plugin. Here's the structure of my project: • Feature Modules: shared modules where ViewModel and DI logic are in commonMain. The Android UI is implemented in androidMain. • iOS UI: All iOS-specific UI code is contained within the iosApp package. After upgrading the Kotlin version, I've added the Compose Compiler Plugin to: • The root project's build.gradle file. • Each module's build.gradle file where Compose is used, including the shared feature modules. However, after making these changes: • Android builds and runs without issues. • iOS compilation fails with errors. asking for Compose Runtime dependency.(pls check image) Right now, I'm not trying to use compose code inside SwiftUI but might try to do so in the future 😅. So why iOS is failing with compose related issue
t
Have you applied new Compose Compiler Gradle Plugin?
b
Hello @tapchicoma, Yes, I did
Copy code
[versions]
kotlin = "2.0.21"
[plugins]
compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }

//root gradle
plugins {
    alias(libs.plugins.compose.compiler) apply false
    ...
}
also using convention plugin all feature modules also have the plugin compose plugin:
Copy code
class ComposeConventionPlugin: Plugin<Project> {
    override fun apply(target: Project) {
        with(target){
            with(pluginManager){
                apply(libs.findPlugin("com-google-devtools-ksp").get().get().pluginId)
                apply(libs.findPlugin("compose-compiler").get().get().pluginId)
            }
            val libraryExtension = extensions.getByType<LibraryExtension>()
            configureComposeAndroid(libraryExtension)
        }
    }
}
feature plugin
Copy code
class FeatureConventionPlugin: Plugin<Project> {
    override fun apply(target: Project) {
        with(target){
            with(pluginManager) {
                apply(libs.findPlugin("supply.base").get().get().pluginId)
                apply(libs.findPlugin("supply.compose").get().get().pluginId) // here
                apply(libs.findPlugin("supply.library").get().get().pluginId)
            }
plugins registered as:
Copy code
gradlePlugin {
    plugins {
        register("compose") {
            id = "supply.compose"
            implementationClass = "ComposeConventionPlugin"
        }
        register("feature") {
            id = "supply.feature"
            implementationClass = "FeatureConventionPlugin"
        }
here in Toml:
Copy code
supply-feature = { id = "supply.feature", version = "unspecified" }
and finally inside feature gradle:
Copy code
plugins {
    alias(libs.plugins.supply.feature)
}
t
ah, it is about compose runtime - it seems you are missing
androidx.compose.runtime
dependency in ios source set. If you could share a Gradle build scan with error - I could check it
b
yes, I did not add
androidx.compose.runtime
to ios source set. I should? didn't know
t
try to add it to the common dependencies
b
I added but it could not identify it. here is error from Xcode:
all feature modules have this same error. this is just one of them
Showing Recent Messages
Copy code
* What went wrong:

Execution failed for task ':feature:agent:category:kspKotlinIosSimulatorArm64'.

Could not resolve all files for configuration ':feature:agent:category:iosSimulatorArm64CompileKlibraries'.

  > Could not resolve androidx.compose.runtime:runtime:1.7.5.

   Required by:

     project :feature:agent:category

   > No matching variant of androidx.compose.runtime:runtime:1.7.5 was found. The consumer was configured to find a library for use during 'kotlin-api', preferably optimized for non-jvm, as well as attribute 'org.jetbrains.kotlin.native.target' with value 'ios_simulator_arm64', attribute 'org.jetbrains.kotlin.platform.type' with value 'native' but:

     - Variant 'androidxSourcesElements':

       - Incompatible because this component declares documentation for use during 'androidx-multiplatform-docs' and the consumer needed a library for use during 'kotlin-api'

       - Other compatible attributes:

         - Doesn't say anything about its target Java environment (preferred optimized for non-jvm)

         - Doesn't say anything about org.jetbrains.kotlin.native.target (required 'ios_simulator_arm64')

         - Doesn't say anything about org.jetbrains.kotlin.platform.type (required 'native')

     - Variant 'jvmStubsApiElements-published' declares a library for use during compile-time:

       - Incompatible because this component declares a component, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'jvm' and the consumer needed a component, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'native'

       - Other compatible attributes:

         - Doesn't say anything about its target Java environment (preferred optimized for non-jvm)

         - Doesn't say anything about org.jetbrains.kotlin.native.target (required 'ios_simulator_arm64')

     - Variant 'jvmStubsRuntimeElements-published' declares a library for use during runtime:

       - Incompatible because this component declares a component, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'jvm' and the consumer needed a component, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'native'

       - Other compatible attributes:

         - Doesn't say anything about its target Java environment (preferred optimized for non-jvm)

         - Doesn't say anything about org.jetbrains.kotlin.native.target (required 'ios_simulator_arm64')

     - Variant 'jvmStubsSourcesElements-published' declares a component for use during runtime:

       - Incompatible because this component declares documentation, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'jvm' and the consumer needed a library, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'native'

       - Other compatible attributes:

         - Doesn't say anything about its target Java environment (preferred optimized for non-jvm)

         - Doesn't say anything about org.jetbrains.kotlin.native.target (required 'ios_simulator_arm64')

     - Variant 'libraryVersionMetadata':

       - Incompatible because this component declares documentation for use during 'library-version-metadata' and the consumer needed a library for use during 'kotlin-api'

       - Other compatible attributes:

         - Doesn't say anything about its target Java environment (preferred optimized for non-jvm)

         - Doesn't say anything about org.jetbrains.kotlin.native.target (required 'ios_simulator_arm64')

         - Doesn't say anything about org.jetbrains.kotlin.platform.type (required 'native')

     - Variant 'linuxx64StubsApiElements-published' declares a library for use during 'kotlin-api', as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'native':

       - Incompatible because this component declares a component, as well as attribute 'org.jetbrains.kotlin.native.target' with value 'linux_x64' and the consumer needed a component, as well as attribute 'org.jetbrains.kotlin.native.target' with value 'ios_simulator_arm64'

       - Other compatible attribute:

         - Doesn't say anything about its target Java environment (preferred optimized for non-jvm)

     - Variant 'linuxx64StubsSourcesElements-published' declares a component, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'native':

       - Incompatible because this component declares documentation for use during 'kotlin-runtime', as well as attribute 'org.jetbrains.kotlin.native.target' with value 'linux_x64' and the consumer needed a library for use during 'kotlin-api', as well as attribute 'org.jetbrains.kotlin.native.target' with value 'ios_simulator_arm64'

       - Other compatible attribute:

         - Doesn't say anything about its target Java environment (preferred optimized for non-jvm)

     - Variant 'metadataApiElements' declares a library:

       - Incompatible because this component declares a component for use during 'kotlin-metadata', as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'common' and the consumer needed a component for use during 'kotlin-api', as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'native'

       - Other compatible attributes:

         - Doesn't say anything about its target Java environment (preferred optimized for non-jvm)

         - Doesn't say anything about org.jetbrains.kotlin.native.target (required 'ios_simulator_arm64')

     - Variant 'metadataSourcesElements':

       - Incompatible because this component declares documentation for use during 'kotlin-runtime', as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'common' and the consumer needed a library for use during 'kotlin-api', as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'native'

       - Other compatible attributes:

         - Doesn't say anything about its target Java environment (preferred optimized for non-jvm)

         - Doesn't say anything about org.jetbrains.kotlin.native.target (required 'ios_simulator_arm64')

     - Variant 'releaseApiElements-published' declares a library for use during compile-time:

       - Incompatible because this component declares a component, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'androidJvm' and the consumer needed a component, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'native'

       - Other compatible attributes:

         - Doesn't say anything about its target Java environment (preferred optimized for non-jvm)

         - Doesn't say anything about org.jetbrains.kotlin.native.target (required 'ios_simulator_arm64')

     - Variant 'releaseRuntimeElements-published' declares a library for use during runtime:

       - Incompatible because this component declares a component, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'androidJvm' and the consumer needed a component, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'native'

       - Other compatible attributes:

         - Doesn't say anything about its target Java environment (preferred optimized for non-jvm)

         - Doesn't say anything about org.jetbrains.kotlin.native.target (required 'ios_simulator_arm64')

     - Variant 'releaseSourcesElements-published' declares a component for use during runtime:

       - Incompatible because this component declares documentation, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'androidJvm' and the consumer needed a library, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'native'

       - Other compatible attributes:

         - Doesn't say anything about its target Java environment (preferred optimized for non-jvm)

         - Doesn't say anything about org.jetbrains.kotlin.native.target (required 'ios_simulator_arm64')



* Try:

Review the variant matching algorithm at <https://docs.gradle.org/8.7/userguide/variant_attributes.html#sec:abm_algorithm>.

No matching variant errors are explained in more detail at <https://docs.gradle.org/8.7/userguide/variant_model.html#sub:variant-no-match>.

Run with --stacktrace option to get the stack trace.

Run with --info or --debug option to get more log output.

Run with --scan to get full insights.

Get more help at <https://help.gradle.org>.
Before adding it to the ios source set. I had following error log:
Copy code
Showing Recent Messages
Task :feature:agent:order:compileKotlinIosSimulatorArm64

Failed to load native library:libjansi.jnilib. The native library file at /Users/cdti/.gradle/native/jansi/1.18/osx/libjansi.jnilib is not executable, make sure that the directory is mounted on a partition without the noexec flag, or set the jansi.tmpdir system property to point to a proper location. osinfo: Mac/arm64

java.lang.UnsatisfiedLinkError: /Users/cdti/.gradle/native/jansi/1.18/osx/libjansi.jnilib: dlopen(/Users/cdti/.gradle/native/jansi/1.18/osx/libjansi.jnilib, 0x0001): tried: '/Users/cdti/.gradle/native/jansi/1.18/osx/libjansi.jnilib' (mach-o file, but is an incompatible architecture (have 'x86_64', need 'arm64e' or 'arm64')), '/System/Volumes/Preboot/Cryptexes/OS/Users/cdti/.gradle/native/jansi/1.18/osx/libjansi.jnilib' (no such file), '/Users/cdti/.gradle/native/jansi/1.18/osx/libjansi.jnilib' (mach-o file, but is an incompatible architecture (have 'x86_64', need 'arm64e' or 'arm64'))



Task :feature:warehouse:remaining:compileKotlinIosSimulatorArm64 FAILED

androidx.compose.compiler.plugins.kotlin.IncompatibleComposeRuntimeVersionException: The Compose Compiler requires the Compose Runtime to be on the class path, but none could be found. The compose compiler plugin you are using (version 1.5.14) expects a minimum runtime version of 1.0.0.



 * Source files: ViewmodelModule.kt, WarehouseOperationsViewModel.kt, WarehouseRemainingViewModel.kt, WarehouseStockProductViewModel.kt

 * Compiler version: 2.0.21

 * Output kind: LIBRARY



Compilation failed: The Compose Compiler requires the Compose Runtime to be on the class path, but none could be found. The compose compiler plugin you are using (version 1.5.14) expects a minimum runtime version of 1.0.0.

	at androidx.compose.compiler.plugins.kotlin.VersionChecker.noRuntimeOnClasspathError(VersionChecker.kt:221)

	at androidx.compose.compiler.plugins.kotlin.VersionChecker.check(VersionChecker.kt:193)

	at androidx.compose.compiler.plugins.kotlin.ComposeIrGenerationExtension.generate(ComposeIrGenerationExtension.kt:73)

	at org.jetbrains.kotlin.fir.pipeline.ConvertToIrKt.applyIrGenerationExtensions(convertToIr.kt:442)

	at org.jetbrains.kotlin.fir.pipeline.Fir2IrPipeline.runActualizationPipeline(convertToIr.kt:246)

	at org.jetbrains.kotlin.fir.pipeline.Fir2IrPipeline.convertToIrAndActualize(convertToIr.kt:130)

	at org.jetbrains.kotlin.fir.pipeline.ConvertToIrKt.convertToIrAndActualize(convertToIr.kt:99)

	at org.jetbrains.kotlin.fir.pipeline.ConvertToIrKt.convertToIrAndActualize$default(convertToIr.kt:72)

	at org.jetbrains.kotlin.backend.konan.Fir2IrKt.fir2Ir(Fir2Ir.kt:99)

	at org.jetbrains.kotlin.backend.konan.driver.phases.Fir2IrKt.Fir2IrPhase$lambda$1(Fir2Ir.kt:32)

	at org.jetbrains.kotlin.backend.common.phaser.PhaseBuildersKt$createSimpleNamedCompilerPhase$1.phaseBody(PhaseBuilders.kt:69)

	at org.jetbrains.kotlin.backend.common.phaser.SimpleNamedCompilerPhase.phaseBody(CompilerPhase.kt:226)

	at org.jetbrains.kotlin.backend.common.phaser.AbstractNamedCompilerPhase.invoke(CompilerPhase.kt:113)

	at org.jetbrains.kotlin.backend.konan.driver.PhaseEngine.runPhase(Machinery.kt:120)

	at org.jetbrains.kotlin.backend.konan.driver.PhaseEngine.runPhase$default(Machinery.kt:111)

	at org.jetbrains.kotlin.backend.konan.driver.phases.Fir2IrKt.runFir2Ir(Fir2Ir.kt:36)

	at org.jetbrains.kotlin.backend.konan.driver.DynamicCompilerDriver.serializeKLibK2(DynamicCompilerDriver.kt:130)

	at org.jetbrains.kotlin.backend.konan.driver.DynamicCompilerDriver.produceKlib(DynamicCompilerDriver.kt:111)

	at org.jetbrains.kotlin.backend.konan.driver.DynamicCompilerDriver.run$lambda$2$lambda$1$lambda$0(DynamicCompilerDriver.kt:44)

	at org.jetbrains.kotlin.backend.konan.driver.PhaseEngine$Companion$startTopLevel$topLevelPhase$1.phaseBody(Machinery.kt:79)

	at org.jetbrains.kotlin.backend.konan.driver.PhaseEngine$Companion$startTopLevel$topLevelPhase$1.phaseBody(Machinery.kt:73)

	at org.jetbrains.kotlin.backend.common.phaser.SimpleNamedCompilerPhase.phaseBody(CompilerPhase.kt:226)

	at org.jetbrains.kotlin.backend.common.phaser.AbstractNamedCompilerPhase.invoke(CompilerPhase.kt:113)

	at org.jetbrains.kotlin.backend.konan.driver.PhaseEngine$Companion.startTopLevel(Machinery.kt:86)

	at org.jetbrains.kotlin.backend.konan.driver.DynamicCompilerDriver.run(DynamicCompilerDriver.kt:37)

	at org.jetbrains.kotlin.backend.konan.KonanDriver.run(KonanDriver.kt:135)

	at org.jetbrains.kotlin.cli.bc.K2Native.runKonanDriver(K2Native.kt:157)

	at org.jetbrains.kotlin.cli.bc.K2Native.doExecute(K2Native.kt:65)

	at org.jetbrains.kotlin.cli.bc.K2Native.doExecute(K2Native.kt:34)

	at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:103)

	at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:49)

	at org.jetbrains.kotlin.cli.common.CLITool.exec(CLITool.kt:101)

	at org.jetbrains.kotlin.cli.common.CLITool.exec(CLITool.kt:79)

	at org.jetbrains.kotlin.cli.common.CLITool.exec(CLITool.kt:43)

	at org.jetbrains.kotlin.cli.common.CLITool$Companion.doMainNoExit(CLITool.kt:180)

	at org.jetbrains.kotlin.cli.common.CLITool$Companion.doMainNoExit$default(CLITool.kt:173)

	at org.jetbrains.kotlin.cli.common.CLITool$Companion.doMain(CLITool.kt:167)

	at org.jetbrains.kotlin.cli.bc.K2Native$Companion.main$lambda$0(K2Native.kt:180)

	at org.jetbrains.kotlin.util.UtilKt.profileIf(Util.kt:22)

	at org.jetbrains.kotlin.util.UtilKt.profile(Util.kt:16)

	at org.jetbrains.kotlin.cli.bc.K2Native$Companion.main(K2Native.kt:179)

	at org.jetbrains.kotlin.cli.bc.K2NativeKt.main(K2Native.kt:210)

	at org.jetbrains.kotlin.cli.utilities.MainKt$main$1.invoke(main.kt:44)

	at org.jetbrains.kotlin.cli.utilities.MainKt$main$1.invoke(main.kt:44)

	at org.jetbrains.kotlin.cli.utilities.MainKt.mainImpl(main.kt:20)

	at org.jetbrains.kotlin.cli.utilities.MainKt.main(main.kt:44)
@tapchicoma well, adding composeMultiplatform and compose.runtime fixed one feature module. Now I try to add it to all feature modules. But enabling composeMultiplatform might bring other challenges🥶
Copy code
plugins {
    alias(libs.plugins.supply.feature)
    alias(libs.plugins.composeMultiplatform)
}

kotlin{
    sourceSets {
        commonMain{
            dependencies {
                api(libs.moko.paging)
                api(compose.runtime)
            }
        }
    }
}
yeah, it bring other errors 😞
Finally, problem solved. I added
composeMultiplatform
plugin and also
api(compose.runtime)
which brings errors: Swift cannot differenciate which @State to use. I don't know exact where it is coming from but inside my shared module there is @State. So I added @SwiftUICore before state
@SwiftUICore.State *var* orderNavigator: OrderNavigator = .idle
now it knows. It is obviously not the best solution but for know I don't have any other solution. I'm guessing it is because of 3rd party libraries I have: moko resources moko paging moko network moko network engine moko mvvm russhwolf settings ...