https://kotlinlang.org logo
#multiplatform
Title
# multiplatform
v

Vlad

11/08/2023, 3:18 PM
I am trying to migrate my gradle to the gradle hierarchies. I am getting error:
Copy code
kotlin {
    androidTarget() // <-- please register this Android target
}
When if I put
androidTarget()
gradle says
Copy code
Unresolved reference: androidTarget
I cleaned my cache. And I have the template project from the Jetbrains wizzard tool which works just fine with androidTarget(). I am missing something I don't understand what exactly.
Copy code
kotlin.version=1.9.20
agp.version=8.1.2
distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip
Any hints?
Only difference from the working template project I see is that it uses gradle versions library, and I don't. But seems like I add correct plugins
p

Pablichjenkov

11/08/2023, 3:23 PM
I would say restart the IDE, do a cleanup, remove the .gradle .idea directories. Ensure the plugins are up to date
v

Vlad

11/08/2023, 3:24 PM
I also have buildSrc module because in there I hosted my custom libraries version with just kotlin objects. Dunno if it anyhow breaking my build
p

Pablichjenkov

11/08/2023, 3:27 PM
In theory it shouldn't unless 1.9.20 introduced something new but I haven't read anything in regards. What plugins are you applying to that gradle project?
Do you have this line applyDefaultHierarchyTemplate()
v

Vlad

11/08/2023, 3:28 PM
Copy code
kotlin("jvm").version(kotlinVersion)
        kotlin("multiplatform").version(kotlinVersion)
        kotlin("plugin.serialization").version(kotlinVersion)
        kotlin("native.cocoapods").version(kotlinVersion)
        kotlin("android").version(kotlinVersion)

        id("com.android.application").version(agpVersion)
        id("com.android.library").version(agpVersion)
        id("org.jetbrains.compose").version(composeVersion)
        id("com.google.gms.google-services").version(googleServicesVersion)
        id("dev.icerock.mobile.multiplatform-resources").version(mokoResVersion)
Nothing specific. Unless Moko somehow breaks everything 😄
Copy code
build.gradle.kts:18:5: Unresolved reference: applyDefaultHierarchyTemplate
The funny story is that
targetHierarchy.default()
says it is deprecated, use applyDefault.. But it can't be applied
p

Pablichjenkov

11/08/2023, 3:31 PM
That's the root project but for the specific subproject where the error happens
v

Vlad

11/08/2023, 3:31 PM
Copy code
plugins {
    kotlin("multiplatform")
    kotlin("plugin.serialization")
    kotlin("native.cocoapods")
    id("com.android.library")
    id("org.jetbrains.compose")
    id("app.cash.sqldelight").version(Versions.sqlDelight)
    id("dev.icerock.mobile.multiplatform-resources")
    id("com.google.gms.google-services")
}
shared gradle
p

Pablichjenkov

11/08/2023, 3:32 PM
I think you have to apply Android library plugin in it
v

Vlad

11/08/2023, 3:33 PM
Oh, right. In the template android application plugin is applied, and I still have .library
p

Pablichjenkov

11/08/2023, 3:33 PM
Or well, if it is your Android application module, the Android application plugin then
🙌 1
Is one or the other, don't apply both cause it will error out too
v

Vlad

11/08/2023, 3:35 PM
That will be weird. Because I have androidApp, iosApp and shared modules. If I apply android application in shared module it won't build my android, coz we can't have 2 android application modules
What a hell
And seems like new Kotlin wizzard creates template with only 2 modules. composeApp + iosApp
p

Pablichjenkov

11/08/2023, 3:42 PM
Exactly, Android application plugin cannot depend on another module that is an Android application too, it can only depend on Android library plugin, which is the case for shared or any other module you want to expose as a library
In fact shared is a library, a UI library
In there shared is actually android app as well. Dunno why they did that
p

Pablichjenkov

11/08/2023, 3:44 PM
Humm, sounds more like a bug to me
I really don't use these templates so much for these kind of stuff. I prefer manual setup. You struggle to make your first template but once done, just copy paste it every where and is less error prone
v

Vlad

11/08/2023, 3:45 PM
I don't know gradle that well so I could ignore templates
p

Pablichjenkov

11/08/2023, 3:48 PM
You can bring that up, about the application plugin applied to shared in their issue tracker or wherever is supposed to be reported
v

Vlad

11/08/2023, 4:13 PM
Okay. So what I learned: I can't use
androidTarget()
in
shared
because my shared has
id("com.android.library")
plugin. And seems like only android.application must be used for
androidTarget()
. Since I have androidApp module, I replaced in it the
kotlin("android")
plugin to
kotlin("multiplatform")
and added.
Copy code
kotlin {
    androidTarget()

    sourceSets {
        val androidMain by getting {
            dependencies {
                implementation(project(":shared"))
            }
        }
    }
}
This setup can be seen in the compose-multiplatform-ios-android-template which I used to start the project. Seems like JB has 2 different templates at the moment and I have no clue where they are going. But seems like I can't migrate to the gradle hierarchies just now. At least it won't be easy coz I am not smart enough to do so. It builds for Android atm, will check iOS
p

Pablichjenkov

11/08/2023, 5:09 PM
Did you apply
applyDefaultHierarchyTemplate()
In your Gradle , and remove the Android plugins , see what happens. Check this build.gradle file. It works for me: https://github.com/pablichjenkov/component-toolkit/blob/master/component-toolkit/build.gradle.kts
v

Vlad

11/08/2023, 5:18 PM
Copy code
/shared/build.gradle.kts:28:5: Unresolved reference: applyDefaultHierarchyTemplate
Although I can apply it for androidApp module
🤔 1
p

Pablichjenkov

11/08/2023, 5:25 PM
Potentially yeup, I have to refresh the gradle scripts right. There is probably a lot of stuff not needed anymore. I LL take a look later today
v

Vlad

11/08/2023, 5:28 PM
Copy code
The Default Kotlin Hierarchy Template was not applied to 'project ':shared'':
Explicit .dependsOn() edges were configured for the following source sets:
[iosArm64Main, iosMain, iosSimulatorArm64Main, iosX64Main]

Consider removing dependsOn-calls or disabling the default template by adding
    'kotlin.mpp.applyDefaultHierarchyTemplate=false'
to your gradle.properties
And iOS won't build with that.
p

Pablichjenkov

11/08/2023, 5:29 PM
Well for iOS you have to replace createBy with gettingBy
v

Vlad

11/08/2023, 5:30 PM
But that won't work before?
Copy code
applyDefaultHierarchyTemplate()
p

Pablichjenkov

11/08/2023, 5:31 PM
Exactly won't work before, is like a breaking change I guess
v

Vlad

11/08/2023, 5:33 PM
Seems like @Landry Norris has similar issue little bit below lmaop
😁 1
p

Pablichjenkov

11/08/2023, 5:34 PM
I saw it 😀 , but yeah I need to remove the applyDefaultHirerchyTemplate. Seems not to be needed anymore
v

Vlad

11/08/2023, 5:41 PM
Copy code
commonMain.dependencies {
I can't even import the .dependencies extension. Something is wrong with my gradle
p

Pablichjenkov

11/08/2023, 5:46 PM
What gradle version you are using by the way
I got 8.3
v

Vlad

11/08/2023, 5:49 PM
Copy code
distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip
this?
p

Pablichjenkov

11/08/2023, 5:51 PM
Seems good
v

Vlad

11/08/2023, 5:51 PM
I wonder if having buildSrc module breaks everything
I honestly not seeing any other options. Unless somehow some of my other plugins break the gradle
if it is even possible
p

Pablichjenkov

11/08/2023, 5:52 PM
Depending on what the code inside does. Unless it is not applying the plugins programatically
v

Vlad

11/08/2023, 5:53 PM
Copy code
plugins {
    `kotlin-dsl`
}

repositories {
    mavenCentral()
}

kotlin {
    jvmToolchain(17)
}
It has this
I am not sure if that "kotlin-dsl" is the problem
p

Pablichjenkov

11/08/2023, 5:54 PM
Are you applying the plugins to each project by code? I think it overrides the scripts
I have used that before in pure Android projects without an issue. Never tried multiplatform but shouldn't be. Try commenting out anything you see weird and check what happens
v

Vlad

11/08/2023, 5:57 PM
I can't comment anything because I have my kotlin class Deps in there which I use everywhere to get the dependencies 😄
Well, the dependency's constants
Aka
Will remove it tomorrow and try
I am toasted. Thank you very much for hanging around
Mission is impossible
l

Landry Norris

11/08/2023, 6:03 PM
I ran into this in one module, and just left it with the deprecated
android
, which works for me. It just warns about deprecation.
p

Pablichjenkov

11/08/2023, 6:08 PM
👍🏻😀
j

Jeff Lockhart

11/08/2023, 6:15 PM
I can't use
androidTarget()
in
shared
because my shared has
id("com.android.library")
plugin. And seems like only android.application must be used for
androidTarget()
This isn't true.
androidTarget()
can be applied to either a Android application or library.
I wonder if having buildSrc module breaks everything
This is very likely the case. It seems as if you have multiple versions of the Kotlin Gradle plugin being applied, an older version that doesn't have
androidTarget()
or
applyDefaultHierarchyTemplate()
.
v

Vlad

11/08/2023, 6:16 PM
Will remove buildSrc tomorrow and report
j

Jeff Lockhart

11/08/2023, 6:25 PM
Gradle plugin versions is definitely one of the more painful aspects of Gradle. The build script needs to apply a specific version only once to the classpath. I use
buildSrc
in my library with version catalogs, which don't work well together out of the box currently, but this workaround helps. You can check out how I'm configuring the Kotlin Gradle plugin version in my library with
buildSrc
. It's being added to the classpath from the version catalog here. Then when it's applied, it doesn't use an explicit version.
1
I've seen a couple of other threads that had similar issues not seeing the
androidTarget()
API, likely because an older KGP was being applied. In some cases it was the fault of another plugin they were using, so you might try removing other plugins until you identify the source. Also, see if there are updated plugin versions.
👍 1
1
v

Vlad

11/09/2023, 2:35 PM
Upd: Maybe I am wrong. Checking.
Na, I literally copy-pasted all my plugins into working template and everything works. But not in the my project.
👍 1
p

Pablichjenkov

11/09/2023, 3:57 PM
Humm 🤔 , well if it works it works 🤷🏻‍♂️ 😀
v

Vlad

11/09/2023, 4:00 PM
It starts working if I remove from my project SQLDelight plugin. But template project works with the same plugin
👀 1
wut
Everything started worked when I: 1. Replaced
id("app.cash.sqldelight").version(Versions.sqlDelight)
with
id("app.cash.sqldelight")
in my shared build.gradle (removed the version). 2. Added
id("app.cash.sqldelight").version(sqldelightVersion)
into plugins {} in settings.gradle for the project 3. Added
id("app.cash.sqldelight").apply(false)
into project's build.gradle. That is it. 2 days. And I still have no clue why exactly.
j

Jeff Lockhart

11/09/2023, 4:52 PM
Generally plugins should be applied at the top-level project build.gradle with the explicit version in order to add to the classpath once. If the plugin doesn't need to be applied to the top level, then
apply false
can be added. Whenever a plugin is applied in a module build.gradle configurations, no version should be specified, as it will use the version introduced on the classpath already. I've found it best to follow this rule with all plugins, whether you think you're applying it only in a single module or not because it's possible other plugins have side effects of introducing another version where you don't expect. So by declaring it yourself at the top level, you maintain control of the version.
👍 1
v

Vlad

11/09/2023, 4:54 PM
I do follow it, as you could see that on top, I have all others plugin following that idea. I don't remember why exactly I didn't do that with the only SQLDelight plugin, I planned to "fix it later". Shot into the foot
😄 2
Cleaning up my gradle files and noted that simply adding only step 3
Copy code
Added id("app.cash.sqldelight").apply(false) into project's build.gradle.
would be already sufficient 🤦‍♂️ . I remember explicitly not adding it because I thought since I am not applying the SQLDelight to whole project but only to shared, I don't need it lmao.
😃 1
👍 1
👍🏼 1
34 Views