From 19fd706d980d9524bfad72f6e86cee234cdf53d2 Mon Sep 17 00:00:00 2001 From: Sergey Igushkin Date: Fri, 13 Jul 2018 23:19:55 +0300 Subject: [PATCH] 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. --- .../plugin/android/Android25ProjectHandler.kt | 2 + .../kotlin/gradle/plugin/KotlinPlugin.kt | 39 ++++++++++++------- .../gradle/plugin/mpp/kotlinCompilations.kt | 10 +++-- .../gradle/utils/gradleConfigurationUtils.kt | 6 ++- 4 files changed, 39 insertions(+), 18 deletions(-) diff --git a/libraries/tools/kotlin-gradle-plugin/src/agp25/kotlin/org/jetbrains/kotlin/gradle/plugin/android/Android25ProjectHandler.kt b/libraries/tools/kotlin-gradle-plugin/src/agp25/kotlin/org/jetbrains/kotlin/gradle/plugin/android/Android25ProjectHandler.kt index 476995e2e0e..cc45ea0dcb1 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/agp25/kotlin/org/jetbrains/kotlin/gradle/plugin/android/Android25ProjectHandler.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/agp25/kotlin/org/jetbrains/kotlin/gradle/plugin/android/Android25ProjectHandler.kt @@ -102,6 +102,8 @@ class Android25ProjectHandler(kotlinConfigurationTools: KotlinConfigurationTools override fun setUpDependencyResolution(variant: BaseVariant, compilation: KotlinJvmAndroidCompilation) { val project = compilation.target.project + KotlinTargetConfigurator.defineConfigurationsForCompilation(compilation, compilation.target, project.configurations) + compilation.compileDependencyFiles = variant.compileConfiguration.apply { usesPlatformOf(compilation.target) project.addExtendsFromRelation(name, compilation.compileDependencyConfigurationName) diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt index dc6588e90c3..e1407339888 100755 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt @@ -626,6 +626,12 @@ abstract class AbstractAndroidProjectHandler(private val kotlinConfigurationT ext.addExtension(KOTLIN_OPTIONS_DSL_NAME, kotlinOptions) 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", "com.android.test", "com.android.feature", "com.android.dynamic-feature", "com.android.instantapp") val plugin = androidPluginIds.asSequence() @@ -635,16 +641,20 @@ abstract class AbstractAndroidProjectHandler(private val kotlinConfigurationT "plugins to be applied to the project:\n\t" + androidPluginIds.joinToString("\n\t") { "* $it" }) - val subpluginEnvironment = loadSubplugins(project, kotlinConfigurationTools.kotlinPluginVersion) - checkAndroidAnnotationProcessorDependencyUsage(project) forEachVariant(project) { processVariant( - it, kotlinAndroidTarget, project, ext, plugin, kotlinOptions, kotlinConfigurationTools.kotlinTasksProvider, - subpluginEnvironment + it, kotlinAndroidTarget, project, ext, plugin, kotlinOptions, kotlinConfigurationTools.kotlinTasksProvider ) } + + 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(private val kotlinConfigurationT androidExt: BaseExtension, androidPlugin: BasePlugin, rootKotlinOptions: KotlinJvmOptionsImpl, - tasksProvider: KotlinTasksProvider, - subpluginEnvironment: SubpluginEnvironment + tasksProvider: KotlinTasksProvider ) { - checkVariantIsValid(variantData) val variantDataName = getVariantName(variantData) 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) if (javaTask == null) { @@ -676,6 +678,7 @@ abstract class AbstractAndroidProjectHandler(private val kotlinConfigurationT return } + val compilation = target.compilations.getByName(variantDataName) val kotlinTaskName = compilation.compileKotlinTaskName // todo: Investigate possibility of creating and configuring kotlinTask before evaluation val kotlinTask = tasksProvider.createKotlinJVMTask(project, kotlinTaskName, variantDataName) @@ -696,6 +699,16 @@ abstract class AbstractAndroidProjectHandler(private val kotlinConfigurationT } 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( project, kotlinTask, javaTask, wrapVariantDataForKapt(variantData), this, null) diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/kotlinCompilations.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/kotlinCompilations.kt index 5cc29a43532..4e27302b988 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/kotlinCompilations.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/kotlinCompilations.kt @@ -73,9 +73,13 @@ abstract class AbstractKotlinCompilation( whenEvaluated { (target.project.tasks.getByName(compileKotlinTaskName) as AbstractKotlinCompile<*>).source(sourceSet.kotlin) } - addExtendsFromRelation(apiConfigurationName, sourceSet.apiConfigurationName) - addExtendsFromRelation(implementationConfigurationName, sourceSet.implementationConfigurationName) - addExtendsFromRelation(compileOnlyConfigurationName, sourceSet.compileOnlyConfigurationName) + + // Use `forced = false` since `api`, `implementation`, and `compileOnly` may be missing in some cases like + // 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) { addExtendsFromRelation(runtimeOnlyConfigurationName, sourceSet.runtimeOnlyConfigurationName) } diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/utils/gradleConfigurationUtils.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/utils/gradleConfigurationUtils.kt index 40100e183b8..9b8c1c11702 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/utils/gradleConfigurationUtils.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/utils/gradleConfigurationUtils.kt @@ -7,8 +7,10 @@ package org.jetbrains.kotlin.gradle.utils 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) { - project.dependencies.add(extendingConfigurationName, project.configurations.getByName(extendsFromConfigurationName)) + if (forced || configurations.findByName(extendingConfigurationName) != null) { + project.dependencies.add(extendingConfigurationName, project.configurations.getByName(extendsFromConfigurationName)) + } } } \ No newline at end of file