Search code examples
androidgradleandroid-gradle-pluginannotation-processingkapt

Specify arguments for kapt separately for each buildType in an Android project


Basically, I want my annotation processor to insert certain debug logic when I assemble in debug mode, while in release I want generated code to perform as fast as possible without additional checks.

How do I specify arguments for kapt separately for each build type? Of course, I'd like it to work like this:

android {
  buildTypes {
    debug {
      kapt {
        arg("key", "value-for-debug")
      }
    }
    debug {
      kapt {
        arg("key", "value-for-release")
      }
    }
  }
}

But it doesn't work, because kapt {} is being invoked from android {} closure, not from specific buildType closure, so naturally the release one wins and is being used everywhere.

I suspect that I can't solve my problem with kapt {} invocation, as it is indeed global to a plugin. So is there another way around like specifying arguments for a specific task or something?


Solution

  • Well, turns out since Kotlin 1.7.0 it's actually possible to implement this. In that version, KAPT plugin exposed a public task interface - org.jetbrains.kotlin.gradle.tasks.Kapt, which has annotationProcessorOptionProviders property. The property has the type of MutableList<Any>, but in reality it is MutableList<List<CommandLineArgumentProvider>>.

    So, one could write something along the lines:

    // Somewhere in your build.gradle.kts
    
    tasks.withType<Kapt> {
        if (name.startsWith("kaptDebug")) {
            annotationProcessorOptionProviders += listOf(CommandLineArgumentProvider {
                listOf("key", "value-for-debug")
            }
        } else if (name.startsWith("kaptRelease")) {
            annotationProcessorOptionProviders += listOf(CommandLineArgumentProvider {
                listOf("key", "value-for-release")
            }
        }
    }