Fixes for Android single-target projects

1. Kapt resolves runtime classpath during configuration, and because of
that we are unable to setup configurations that already took part in
dependency resolution. To fix that, run Kapt configuration as a separate
step out of the main loop over the variants

2. Old Android projects (< 3.0.0) don't have `api` and `implementation`
configurations. To stay compatible with those, ignore these
configurations being absent during configurations hierarchy setup.
This commit is contained in:
Sergey Igushkin
2018-07-13 23:19:55 +03:00
parent 7b6764c9ae
commit 19fd706d98
4 changed files with 39 additions and 18 deletions
@@ -102,6 +102,8 @@ class Android25ProjectHandler(kotlinConfigurationTools: KotlinConfigurationTools
override fun setUpDependencyResolution(variant: BaseVariant, compilation: KotlinJvmAndroidCompilation) { override fun setUpDependencyResolution(variant: BaseVariant, compilation: KotlinJvmAndroidCompilation) {
val project = compilation.target.project val project = compilation.target.project
KotlinTargetConfigurator.defineConfigurationsForCompilation(compilation, compilation.target, project.configurations)
compilation.compileDependencyFiles = variant.compileConfiguration.apply { compilation.compileDependencyFiles = variant.compileConfiguration.apply {
usesPlatformOf(compilation.target) usesPlatformOf(compilation.target)
project.addExtendsFromRelation(name, compilation.compileDependencyConfigurationName) project.addExtendsFromRelation(name, compilation.compileDependencyConfigurationName)
@@ -626,6 +626,12 @@ abstract class AbstractAndroidProjectHandler<V>(private val kotlinConfigurationT
ext.addExtension(KOTLIN_OPTIONS_DSL_NAME, kotlinOptions) ext.addExtension(KOTLIN_OPTIONS_DSL_NAME, kotlinOptions)
project.afterEvaluate { project -> project.afterEvaluate { project ->
forEachVariant(project) { variant ->
val variantName = getVariantName(variant)
val compilation = kotlinAndroidTarget.compilations.create(variantName)
setUpDependencyResolution(variant, compilation)
}
val androidPluginIds = listOf("android", "com.android.application", "android-library", "com.android.library", val androidPluginIds = listOf("android", "com.android.application", "android-library", "com.android.library",
"com.android.test", "com.android.feature", "com.android.dynamic-feature", "com.android.instantapp") "com.android.test", "com.android.feature", "com.android.dynamic-feature", "com.android.instantapp")
val plugin = androidPluginIds.asSequence() val plugin = androidPluginIds.asSequence()
@@ -635,16 +641,20 @@ abstract class AbstractAndroidProjectHandler<V>(private val kotlinConfigurationT
"plugins to be applied to the project:\n\t" + "plugins to be applied to the project:\n\t" +
androidPluginIds.joinToString("\n\t") { "* $it" }) androidPluginIds.joinToString("\n\t") { "* $it" })
val subpluginEnvironment = loadSubplugins(project, kotlinConfigurationTools.kotlinPluginVersion)
checkAndroidAnnotationProcessorDependencyUsage(project) checkAndroidAnnotationProcessorDependencyUsage(project)
forEachVariant(project) { forEachVariant(project) {
processVariant( processVariant(
it, kotlinAndroidTarget, project, ext, plugin, kotlinOptions, kotlinConfigurationTools.kotlinTasksProvider, it, kotlinAndroidTarget, project, ext, plugin, kotlinOptions, kotlinConfigurationTools.kotlinTasksProvider
subpluginEnvironment
) )
} }
val subpluginEnvironment = loadSubplugins(project, kotlinConfigurationTools.kotlinPluginVersion)
forEachVariant(project) { variant ->
val compilation = kotlinAndroidTarget.compilations.getByName(getVariantName(variant))
applySubplugins(project, compilation, variant, subpluginEnvironment)
}
} }
} }
@@ -655,20 +665,12 @@ abstract class AbstractAndroidProjectHandler<V>(private val kotlinConfigurationT
androidExt: BaseExtension, androidExt: BaseExtension,
androidPlugin: BasePlugin, androidPlugin: BasePlugin,
rootKotlinOptions: KotlinJvmOptionsImpl, rootKotlinOptions: KotlinJvmOptionsImpl,
tasksProvider: KotlinTasksProvider, tasksProvider: KotlinTasksProvider
subpluginEnvironment: SubpluginEnvironment
) { ) {
checkVariantIsValid(variantData) checkVariantIsValid(variantData)
val variantDataName = getVariantName(variantData) val variantDataName = getVariantName(variantData)
logger.kotlinDebug("Process variant [$variantDataName]") logger.kotlinDebug("Process variant [$variantDataName]")
val compilation = target.compilations.create(variantDataName).apply {
KotlinTargetConfigurator.defineConfigurationsForCompilation(this, target, project.configurations)
}
setUpDependencyResolution(variantData, compilation)
val javaTask = getJavaTask(variantData) val javaTask = getJavaTask(variantData)
if (javaTask == null) { if (javaTask == null) {
@@ -676,6 +678,7 @@ abstract class AbstractAndroidProjectHandler<V>(private val kotlinConfigurationT
return return
} }
val compilation = target.compilations.getByName(variantDataName)
val kotlinTaskName = compilation.compileKotlinTaskName val kotlinTaskName = compilation.compileKotlinTaskName
// todo: Investigate possibility of creating and configuring kotlinTask before evaluation // todo: Investigate possibility of creating and configuring kotlinTask before evaluation
val kotlinTask = tasksProvider.createKotlinJVMTask(project, kotlinTaskName, variantDataName) val kotlinTask = tasksProvider.createKotlinJVMTask(project, kotlinTaskName, variantDataName)
@@ -696,6 +699,16 @@ abstract class AbstractAndroidProjectHandler<V>(private val kotlinConfigurationT
} }
wireKotlinTasks(project, compilation, androidPlugin, androidExt, variantData, javaTask, kotlinTask) wireKotlinTasks(project, compilation, androidPlugin, androidExt, variantData, javaTask, kotlinTask)
}
private fun applySubplugins(
project: Project,
compilation: KotlinCompilation,
variantData: V,
subpluginEnvironment: SubpluginEnvironment
) {
val kotlinTask = project.tasks.getByName(compilation.compileKotlinTaskName) as KotlinCompile
val javaTask = getJavaTask(variantData)
val appliedPlugins = subpluginEnvironment.addSubpluginOptions( val appliedPlugins = subpluginEnvironment.addSubpluginOptions(
project, kotlinTask, javaTask, wrapVariantDataForKapt(variantData), this, null) project, kotlinTask, javaTask, wrapVariantDataForKapt(variantData), this, null)
@@ -73,9 +73,13 @@ abstract class AbstractKotlinCompilation(
whenEvaluated { whenEvaluated {
(target.project.tasks.getByName(compileKotlinTaskName) as AbstractKotlinCompile<*>).source(sourceSet.kotlin) (target.project.tasks.getByName(compileKotlinTaskName) as AbstractKotlinCompile<*>).source(sourceSet.kotlin)
} }
addExtendsFromRelation(apiConfigurationName, sourceSet.apiConfigurationName)
addExtendsFromRelation(implementationConfigurationName, sourceSet.implementationConfigurationName) // Use `forced = false` since `api`, `implementation`, and `compileOnly` may be missing in some cases like
addExtendsFromRelation(compileOnlyConfigurationName, sourceSet.compileOnlyConfigurationName) // old Java & Android projects:
addExtendsFromRelation(apiConfigurationName, sourceSet.apiConfigurationName, forced = false)
addExtendsFromRelation(implementationConfigurationName, sourceSet.implementationConfigurationName, forced = false)
addExtendsFromRelation(compileOnlyConfigurationName, sourceSet.compileOnlyConfigurationName, forced = false)
if (this is KotlinCompilationToRunnableFiles) { if (this is KotlinCompilationToRunnableFiles) {
addExtendsFromRelation(runtimeOnlyConfigurationName, sourceSet.runtimeOnlyConfigurationName) addExtendsFromRelation(runtimeOnlyConfigurationName, sourceSet.runtimeOnlyConfigurationName)
} }
@@ -7,8 +7,10 @@ package org.jetbrains.kotlin.gradle.utils
import org.gradle.api.Project import org.gradle.api.Project
fun Project.addExtendsFromRelation(extendingConfigurationName: String, extendsFromConfigurationName: String) { fun Project.addExtendsFromRelation(extendingConfigurationName: String, extendsFromConfigurationName: String, forced: Boolean = false) {
if (extendingConfigurationName != extendsFromConfigurationName) { if (extendingConfigurationName != extendsFromConfigurationName) {
project.dependencies.add(extendingConfigurationName, project.configurations.getByName(extendsFromConfigurationName)) if (forced || configurations.findByName(extendingConfigurationName) != null) {
project.dependencies.add(extendingConfigurationName, project.configurations.getByName(extendsFromConfigurationName))
}
} }
} }