I am trying to migrate my gradle to the gradle hie...
# multiplatform
v
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
I would say restart the IDE, do a cleanup, remove the .gradle .idea directories. Ensure the plugins are up to date
v
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
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
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
That's the root project but for the specific subproject where the error happens
v
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
I think you have to apply Android library plugin in it
v
Oh, right. In the template android application plugin is applied, and I still have .library
p
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
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
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
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
I don't know gradle that well so I could ignore templates
p
You can bring that up, about the application plugin applied to shared in their issue tracker or wherever is supposed to be reported
v
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
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
Copy code
/shared/build.gradle.kts:28:5: Unresolved reference: applyDefaultHierarchyTemplate
Although I can apply it for androidApp module
🤔 1
p
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
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
Well for iOS you have to replace createBy with gettingBy
v
But that won't work before?
Copy code
applyDefaultHierarchyTemplate()
p
Exactly won't work before, is like a breaking change I guess
v
Seems like @Landry Norris has similar issue little bit below lmaop
😁 1
p
I saw it 😀 , but yeah I need to remove the applyDefaultHirerchyTemplate. Seems not to be needed anymore
v
Copy code
commonMain.dependencies {
I can't even import the .dependencies extension. Something is wrong with my gradle
p
What gradle version you are using by the way
I got 8.3
v
Copy code
distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip
this?
p
Seems good
v
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
Depending on what the code inside does. Unless it is not applying the plugins programatically
v
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
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
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
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
👍🏻😀
j
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
Will remove buildSrc tomorrow and report
j
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
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
Humm 🤔 , well if it works it works 🤷🏻‍♂️ 😀
v
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
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
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
648 Views