Hi, when I try to bump kotlin version from `1.9.21...
# multiplatform
e
Hi, when I try to bump kotlin version from
1.9.21
to
1.9.23
or
2.0.0
in a KMM project I am getting errors. For
1.9.23
the error is
Copy code
org.gradle.api.InvalidUserCodeException: Build was configured to prefer settings repositories over project repositories but repository 'ivy' was added by build file 'app/build.gradle.kts'
	...
and for `2.0.0`:
Copy code
* What went wrong:
java.lang.ExceptionInInitializerError (no error message)
> org.jetbrains.kotlin.konan.target.KonanTarget$IOS_ARM32
The gradle plugin version is
8.3.1
. What can be the reason? 🧵
The first error with 1.9.23 is gone if I comment iOS targets in the gradle config inside convention plugin:
Copy code
kotlin {
    androidTarget()
    iosX64()
    iosArm64()
    iosSimulatorArm64()
a
Hi 👋 Have you set centralised repositories in your
settings.gradle.kts
?
When using KGP 2.0, and centralised repost, for native targets you can remove the custom repos https://youtrack.jetbrains.com/issue/KT-51379 For JS targets you'll have to add the Yarn and Npm repos https://youtrack.jetbrains.com/issue/KT-55620
e
@Adam S Here is my config:
Copy code
import java.net.URI

pluginManagement {
    repositories {
        maven("<https://maven.pkg.jetbrains.space/public/p/compose/dev>")
        google()
        mavenCentral()
        gradlePluginPortal()
    }
    includeBuild("buildsystem/convention")
}

dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
        maven("<https://maven.pkg.jetbrains.space/public/p/compose/dev>")
    }
}
a
update
dependencyResolutionManagement {}
to include the Yarn and NPM repos:
Copy code
dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)

    repositories {
        google()
        mavenCentral()
        maven("<https://maven.pkg.jetbrains.space/public/p/compose/dev>")

        //region Declare the Node.js & Yarn download repositories
        // <https://youtrack.jetbrains.com/issue/KT-55620/>
        exclusiveContent {
            forRepository {
                ivy("<https://nodejs.org/dist/>") {
                    name = "Node Distributions at $url"
                    patternLayout { artifact("v[revision]/[artifact](-v[revision]-[classifier]).[ext]") }
                    metadataSources { artifact() }
                    content { includeModule("org.nodejs", "node") }
                }
            }
            filter { includeGroup("org.nodejs") }
        }

        exclusiveContent {
            forRepository {
                ivy("<https://github.com/yarnpkg/yarn/releases/download>") {
                    name = "Yarn Distributions at $url"
                    patternLayout { artifact("v[revision]/[artifact](-v[revision]).[ext]") }
                    metadataSources { artifact() }
                    content { includeModule("com.yarnpkg", "yarn") }
                }
            }
            filter { includeGroup("com.yarnpkg") }
        }
        //endregion
    }
}
e
@Adam S Do you know why is this not necessary for 1.9.21 and necessary for 1.9.23?
🤷 1
a
Happening with me as well when we updated the Kotlin to 1.9.24. But strange thing is that it works perfectly in my laptop but gives the error on my co-worker's laptop. We tried updating dependencyResolutionManagement rule to PREFER_SETTING. But then, we're getting another issue
Copy code
An exception occurred applying plugin request [id: 'compositebuild.multiplatform.root']
> Failed to apply plugin 'compositebuild.multiplatform.root'.
   > Could not resolve all dependencies for configuration ':kmm_umbrella:detachedConfiguration4'.
      > Could not find :kotlin-native-prebuilt-macos-aarch64:1.9.24.
        Required by:
            project :kmm_umbrella
The project builds and runs perfectly in my device though.
e
I tried to add this:
Copy code
// workaround for <https://youtrack.jetbrains.com/issue/KT-51379>
        exclusiveContent {
            forRepository {
                ivy("<https://download.jetbrains.com/kotlin/native/builds>") {
                    name = "Kotlin Native"
                    patternLayout {

                        // example download URLs:
                        // <https://download.jetbrains.com/kotlin/native/builds/releases/1.7.20/linux-x86_64/kotlin-native-prebuilt-linux-x86_64-1.7.20.tar.gz>
                        // <https://download.jetbrains.com/kotlin/native/builds/releases/1.7.20/windows-x86_64/kotlin-native-prebuilt-windows-x86_64-1.7.20.zip>
                        // <https://download.jetbrains.com/kotlin/native/builds/releases/1.7.20/macos-x86_64/kotlin-native-prebuilt-macos-x86_64-1.7.20.tar.gz>
                        listOf(
                            "iosX64",
                            "iosArm64",
                            "iosSimulatorArm64",
                            "macos-x86_64",
                            "macos-aarch64",
                            "osx-x86_64",
                            "osx-aarch64",
                            "linux-x86_64",
                            "windows-x86_64",
                        ).forEach { os ->
                            listOf("dev", "releases").forEach { stage ->
                                artifact("$stage/[revision]/$os/[artifact]-[revision].[ext]")
                            }
                        }
                    }
                    metadataSources { artifact() }
                }
            }
            filter { includeModuleByRegex(".*", ".*kotlin-native-prebuilt.*") }
        }
And it didn’t give any affect
@Abhijeet Kumar do you have iOS target in the project? What additional configuration do you use?
a
Yes. We have iOS targets. And if we comment out all the iOS targets then the error is replaced by something diff(related to one of the mpp package manager we use for exporting XCFramework for iOS) We're on AGP 8.4.0, and this is what our plugin for kmm module looks like.
Copy code
class KotlinMultiplatformConventionPlugin : Plugin<Project> {

    override fun apply(target: Project) = with(target) {
        val libs = extensions.getByType<VersionCatalogsExtension>().named("libs")

        with(pluginManager) {
            apply("org.jetbrains.kotlin.multiplatform")
            apply("org.jetbrains.kotlin.native.cocoapods")
        }

        version = libs.findVersion("kmm_root_module_version")


        extensions.configure<KotlinMultiplatformExtension>() {
            applyDefaultHierarchyTemplate()

            if (pluginManager.hasPlugin("com.android.library")) {
                androidTarget()
            }

            listOf(
             //   iosX64(), -- iOS simulator running on Intel-based Macs.
                iosArm64(), // --  physical iOS devices (iPhones, iPads) using the Arm64 architecture.
             //   iosSimulatorArm64(), -- iOS simulator running on Apple Silicon Macs (M1, M2, etc.).
            ).forEach { target ->
                target.binaries.framework {
                    baseName = path.substring(1).replace(':', '-')
                }
            }
        }

        extensions.configure<KotlinMultiplatformExtension> {
            androidTarget{
                compilations.all {
                    kotlinOptions {
                        jvmTarget = "1.8"
                    }
                }
            }
        }

        extensions.configure<LibraryExtension> {
            compileSdk = Versions.COMPILE_SDK
            defaultConfig.minSdk = Versions.MIN_SDK

            compileOptions {
                sourceCompatibility = JavaVersion.VERSION_1_8
                targetCompatibility = JavaVersion.VERSION_1_8
            }
        }
    }
}
Found a very dirty workaround for this which worked for our project. While searching for other open source project that are running KMP on gradle 8.4.0 with Kotlin target as 1.9.24, came across this https://github.com/thomaskioko/tv-maniac. After cloning this in the dev system it downloaded bunch of dependencies that are shared by our project and after full successful gradle sync of the project, we did gradle sync in our project and that worked. Will probably look into this why this worked over the weekend.
a
@Abhijeet Kumar if you're using Kotlin 1.x, and you use
dependencyResolutionManagement {}
with
repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS)
or
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
, then you should specify the Kotlin/Native repos https://youtrack.jetbrains.com/issue/KT-51379/Build-fails-when-using-RepositoriesMode.FAILONPROJECTREPOS-with-kotlin-multiplatform-projects#focus=Comments-27-6548690.0-0
e
@Adam S I did it with no result. Could you please check my code above?
a
Ah yes, I see. I think that
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
will always fail when using Kotlin 1.x and native targets, or when using Kotlin 1.x or 2.x with JS targets. Instead use
repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS)
.
e
@Adam S Hopefully Kotlin v2 should fix that
a
yes, I think it does. So for Kotlin 2.x with native targets, and no JS targets, then there's no need for a custom Ivy repos. So you can just add
mavenCentral()
and
FAIL_ON_PROJECT_REPOS
.
👍 1
To summarise how to make KGP (Kotlin Gradle Plugin) work with centralised repositories declarations: • "I'm using KGP 1.x or 2.x, and JS targets" → You must use
RepositoriesMode.PREFER_SETTINGS
, and add Node/Yarn Ivy repos, and Maven Central • "I'm using KGP 1.x and Native and/or JS targets" → You must use
RepositoriesMode.PREFER_SETTINGS
, and add Kotlin/Native Ivy repos, and add Node/Yarn Ivy repos, and Maven Central • "I'm using KGP 2.x and Native targets (no JS targets)" → You may use any
RepositoriesMode
, and add Maven Central
🔥 2
💪 2
🙌 1
a
Thanks a ton! @Adam S. This worked!
a
you're welcome!
222 Views