11

I'm working on migrating by Gradle build files to the Kotlin DSL and I encounter an issue.

On my parent build.gradle, I have the following piece of code



buildscript {
  repositories {
    google()
    mavenCentral()
  }
  dependencies {
    classpath 'com.android.tools.build:gradle:3.4.2'
    classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${Version.kotlin}"
  }
}

allprojects {
  repositories {
    google()
    mavenCentral()
  }
}

subprojects {
  afterEvaluate { project ->

    if (project.plugins.findPlugin('com.android.application') ?:
      project.plugins.findPlugin('com.android.library')) {

      android {
        compileSdkVersion = Android.SDK_COMPILE
        defaultConfig {
          minSdkVersion Android.SDK_MIN
          targetSdkVersion Android.SDK_TARGET
          versionCode = Android.VERSION_CODE
          versionName = Android.VERSION_NAME
        }
        ...
      } 
    }
  }
}

This allows me to configure in only one place all the modules that are android applications or libraries.

However this doesn't seem to work when I migrated to kotlin:


buildscript {
  repositories {
    google()
    mavenCentral()
  }
  dependencies {
    classpath(Dependency.androidGradle)
    classpath(Dependency.kotlinGradle)
  }
}

allprojects {
  repositories {
    google()
    mavenCentral()
  }
}

subprojects {
  afterEvaluate {

    if (project.plugins.findPlugin("com.android.application") != null || 
        project.plugins.findPlugin("com.android.library") != null) {

      android { <<<<------------ Unresolved reference: android
        compileSdkVersion(Android.SDK_COMPILE)
        defaultConfig {
          minSdkVersion(Android.SDK_MIN)
          targetSdkVersion(Android.SDK_TARGET)
          versionCode = Android.VERSION_CODE
          versionName = Android.VERSION_NAME
        }
        ...
      }
    }
  }
}

The error is Unresolved reference: android and it looks like the android{} block is not recognized by the script compiler.

My theory is that the if checking for the subproject type is not enough, and I might have to cast or get a reference to some object in which I can call the android{} block, but honestly I do not know enough.

Any clues?

2
  • 1
    Why are you wrapping it all in an afterEvaluate block? Except you are fiddling with compile tasks or what not, you dont need the afterEvaluate block. Just use project.plugins.withId("<plugin-id>") { ... } Commented Aug 25, 2019 at 8:04
  • Do you find solution how to access "android" inside subprojects block gradle kotlin-dsl? Commented Oct 6, 2019 at 8:21

1 Answer 1

18

Gradle Kotlin DSL determines the dependencies for each script from the gradle classpath plus the applied plugins. That's why its recommended to use the plugins { ... } block in the Kotlin DSL.

You need to add the android and kotlin plugins to your root without applying it.

plugins {
  id("<android-plugin>") version "<plugin-version>" apply false
  id("<kotlin-plugin>") version "<plugin-version>" apply false
}

Unfortunately, that will still not generate the static accessors for the root build script but it will give you access to the plugin classes within the script and you can reference them like:

subprojects {

  // BasePlugin is the common superclass of the AppPlugin and LibraryPlugin which are the plugin classes that "com.android.application" and "com.android.library" apply
  plugins.withType<BasePlugin> {

    // BaseExtension is the common superclass of the AppExtension and LibraryExtension which are the extension classes registered by the two plugins to the name "android"
    configure<BaseExtension> {

      // This block is typed correctly
      defaultConfig {
        // ...
      }
    }
  }
}
Sign up to request clarification or add additional context in comments.

5 Comments

Thanks for your answer. It all makes sense, will give it a try soon!
This was a hard one, but finally got it working. For the second code part, I had to use plugins.withType(BasePlugin::class.java) instead of plugins.withType(BasePlugin)
do u have any sample code to apply this? i'm trying to move module build.gradle.kts to root build.gradle.kts using subprojects
@AlexBurdusel plugins.withType<BasePlugin>
In my case I had to change BasePlugin for AndroidBasePlugin. All of the rest remains the same

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.