Task wiring
* Generalized tasks wiring * Moved the old implementation to LegacyAndroidAndroidProjectHandler.kt * Added an implementation with the new AGP API (cherry picked from commit 1b4592d) (cherry picked from commit 50a75d4)
This commit is contained in:
committed by
Alexey Tsvetkov
parent
eb71dee9cc
commit
b0c2c4eba9
@@ -21,7 +21,7 @@ repositories {
|
|||||||
maven { url 'http://repository.jetbrains.com/utils/' }
|
maven { url 'http://repository.jetbrains.com/utils/' }
|
||||||
|
|
||||||
// todo: remove this once the AGP artifacts get published
|
// todo: remove this once the AGP artifacts get published
|
||||||
maven { url project.property("googlePreviewRepositoryPath") } // path to the local unpacked preview repo
|
maven { url (project.findProperty("googlePreviewRepositoryPath") ?: System.getProperty("googlePreviewRepositoryPath")) }
|
||||||
}
|
}
|
||||||
|
|
||||||
configurations {
|
configurations {
|
||||||
@@ -57,6 +57,7 @@ tasks.withType(project.compileKotlin.class) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
compileKotlin.dependsOn compileGroovy
|
compileKotlin.dependsOn compileGroovy
|
||||||
|
compileAgp25Kotlin.dependsOn compileGroovy
|
||||||
compileGroovy.dependsOn.remove("compileJava")
|
compileGroovy.dependsOn.remove("compileJava")
|
||||||
|
|
||||||
def groovyClassesDir = file("${buildDir}/mainGroovyClasses")
|
def groovyClassesDir = file("${buildDir}/mainGroovyClasses")
|
||||||
@@ -68,6 +69,7 @@ sourceSets.main.java.srcDirs += sourceSets.main.kotlin.srcDirs
|
|||||||
sourceSets {
|
sourceSets {
|
||||||
agp25 {
|
agp25 {
|
||||||
compileClasspath += configurations.compile + configurations.agp25CompileOnly + sourceSets.main.output
|
compileClasspath += configurations.compile + configurations.agp25CompileOnly + sourceSets.main.output
|
||||||
|
compileClasspath += files(groovyClassesDir)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+41
@@ -8,6 +8,8 @@ import com.android.build.gradle.api.UnitTestVariant
|
|||||||
import com.android.builder.model.SourceProvider
|
import com.android.builder.model.SourceProvider
|
||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
import org.gradle.api.tasks.compile.AbstractCompile
|
import org.gradle.api.tasks.compile.AbstractCompile
|
||||||
|
import org.jetbrains.kotlin.gradle.internal.Kapt3KotlinGradleSubplugin
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.android.AndroidGradleWrapper
|
||||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
@@ -39,6 +41,45 @@ class Android25ProjectHandler(kotlinConfigurationTools: KotlinConfigurationTools
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun wireKotlinTasks(project: Project,
|
||||||
|
androidPlugin: BasePlugin,
|
||||||
|
androidExt: BaseExtension,
|
||||||
|
variantData: BaseVariant,
|
||||||
|
javaTask: AbstractCompile,
|
||||||
|
kotlinTask: KotlinCompile,
|
||||||
|
kotlinAfterJavaTask: KotlinCompile?) {
|
||||||
|
|
||||||
|
val preJavaKotlinOutput =
|
||||||
|
(if (kotlinAfterJavaTask == null)
|
||||||
|
// Add Kapt3 output as well, since there's no SyncOutputTask with the new API
|
||||||
|
project.files(kotlinTask.destinationDir, Kapt3KotlinGradleSubplugin.getKaptClasssesDir(project, getVariantName(variantData)))
|
||||||
|
else
|
||||||
|
// Don't register the output, but add the task to the pipeline
|
||||||
|
project.files()
|
||||||
|
).builtBy(kotlinTask)
|
||||||
|
|
||||||
|
val preJavaClasspathKey = variantData.registerPreJavacGeneratedBytecode(preJavaKotlinOutput)
|
||||||
|
val kotlinClasspath = variantData.getCompileClasspath(preJavaClasspathKey)
|
||||||
|
|
||||||
|
kotlinTask.conventionMapping.map("classpath") {
|
||||||
|
kotlinClasspath + project.files(AndroidGradleWrapper.getRuntimeJars(androidPlugin, androidExt))
|
||||||
|
}
|
||||||
|
|
||||||
|
kotlinTask.setJavaOutput(javaTask.destinationDir)
|
||||||
|
kotlinAfterJavaTask?.setJavaOutput(javaTask.destinationDir)
|
||||||
|
|
||||||
|
// Use kapt1 annotations file for up-to-date check since annotation processing is done with javac
|
||||||
|
kotlinTask.annotationsFile?.let { javaTask.inputs.file(it) }
|
||||||
|
|
||||||
|
val kotlinAfterJavaOutput = project.files(kotlinAfterJavaTask).builtBy(kotlinAfterJavaTask)
|
||||||
|
variantData.registerPostJavacGeneratedBytecode(kotlinAfterJavaOutput)
|
||||||
|
|
||||||
|
if (kotlinAfterJavaTask != null) {
|
||||||
|
// Then don't register kotlinTask output, but only use it for Java compilation
|
||||||
|
javaTask.appendClasspath(kotlinTask.destinationDir)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun getSourceProviders(variantData: BaseVariant): Iterable<SourceProvider> =
|
override fun getSourceProviders(variantData: BaseVariant): Iterable<SourceProvider> =
|
||||||
variantData.sourceSets
|
variantData.sourceSets
|
||||||
|
|
||||||
|
|||||||
+19
-37
@@ -3,7 +3,6 @@ package org.jetbrains.kotlin.gradle.plugin
|
|||||||
import com.android.build.gradle.BaseExtension
|
import com.android.build.gradle.BaseExtension
|
||||||
import com.android.build.gradle.BasePlugin
|
import com.android.build.gradle.BasePlugin
|
||||||
import com.android.build.gradle.api.AndroidSourceSet
|
import com.android.build.gradle.api.AndroidSourceSet
|
||||||
import com.android.build.gradle.internal.variant.BaseVariantData
|
|
||||||
import com.android.builder.model.SourceProvider
|
import com.android.builder.model.SourceProvider
|
||||||
import groovy.lang.Closure
|
import groovy.lang.Closure
|
||||||
import org.apache.tools.ant.util.ReflectUtil.newInstance
|
import org.apache.tools.ant.util.ReflectUtil.newInstance
|
||||||
@@ -21,13 +20,13 @@ import org.gradle.api.tasks.SourceSet
|
|||||||
import org.gradle.api.tasks.compile.AbstractCompile
|
import org.gradle.api.tasks.compile.AbstractCompile
|
||||||
import org.gradle.api.tasks.compile.JavaCompile
|
import org.gradle.api.tasks.compile.JavaCompile
|
||||||
import org.jetbrains.kotlin.com.intellij.openapi.util.io.FileUtil
|
import org.jetbrains.kotlin.com.intellij.openapi.util.io.FileUtil
|
||||||
|
import org.jetbrains.kotlin.com.intellij.openapi.util.text.StringUtil.compareVersionNumbers
|
||||||
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptionsImpl
|
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptionsImpl
|
||||||
import org.jetbrains.kotlin.gradle.internal.AnnotationProcessingManager
|
import org.jetbrains.kotlin.gradle.internal.AnnotationProcessingManager
|
||||||
import org.jetbrains.kotlin.gradle.internal.Kapt3GradleSubplugin
|
import org.jetbrains.kotlin.gradle.internal.Kapt3GradleSubplugin
|
||||||
import org.jetbrains.kotlin.gradle.internal.Kapt3KotlinGradleSubplugin
|
import org.jetbrains.kotlin.gradle.internal.Kapt3KotlinGradleSubplugin
|
||||||
import org.jetbrains.kotlin.gradle.internal.Kapt3KotlinGradleSubplugin.Companion.getKaptClasssesDir
|
import org.jetbrains.kotlin.gradle.internal.Kapt3KotlinGradleSubplugin.Companion.getKaptClasssesDir
|
||||||
import org.jetbrains.kotlin.gradle.internal.initKapt
|
import org.jetbrains.kotlin.gradle.internal.initKapt
|
||||||
import org.jetbrains.kotlin.gradle.plugin.android.AndroidGradleWrapper
|
|
||||||
import org.jetbrains.kotlin.gradle.tasks.*
|
import org.jetbrains.kotlin.gradle.tasks.*
|
||||||
import org.jetbrains.kotlin.gradle.utils.ParsedGradleVersion
|
import org.jetbrains.kotlin.gradle.utils.ParsedGradleVersion
|
||||||
import org.jetbrains.kotlin.incremental.configureMultiProjectIncrementalCompilation
|
import org.jetbrains.kotlin.incremental.configureMultiProjectIncrementalCompilation
|
||||||
@@ -375,22 +374,13 @@ class KotlinConfigurationTools internal constructor(val kotlinSourceSetProvider:
|
|||||||
abstract class AbstractAndroidProjectHandler<V>(private val kotlinConfigurationTools: KotlinConfigurationTools) {
|
abstract class AbstractAndroidProjectHandler<V>(private val kotlinConfigurationTools: KotlinConfigurationTools) {
|
||||||
|
|
||||||
protected val artifactDifferenceRegistryProvider get() =
|
protected val artifactDifferenceRegistryProvider get() =
|
||||||
kotlinConfigurationTools.kotlinGradleBuildServices.artifactDifferenceRegistryProvider
|
kotlinConfigurationTools.kotlinGradleBuildServices.artifactDifferenceRegistryProvider
|
||||||
|
|
||||||
private val logger = Logging.getLogger(this.javaClass)
|
protected val KotlinCompile.annotationsFile: File? get() = kaptOptions.annotationsFile
|
||||||
|
protected fun KotlinCompile.setJavaOutput(file: File) { javaOutputDir = file }
|
||||||
|
protected fun AbstractCompile.appendClasspath(file: File) = appendClasspathDynamically(file)
|
||||||
|
|
||||||
private fun Project.tryGetSingleArtifact(variantData: BaseVariantData<*>): File? {
|
protected val logger = Logging.getLogger(this.javaClass)
|
||||||
val log = logger
|
|
||||||
log.kotlinDebug { "Trying to determine single artifact for project $path" }
|
|
||||||
|
|
||||||
val outputs = variantData.outputs
|
|
||||||
if (outputs.size != 1) {
|
|
||||||
log.kotlinDebug { "Output count != 1 for variant: ${outputs.map { it.outputFile.relativeTo(rootDir).path }.joinToString()}" }
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
return variantData.outputs.first().outputFile
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract fun forEachVariant(project: Project, action: (V) -> Unit): Unit
|
protected abstract fun forEachVariant(project: Project, action: (V) -> Unit): Unit
|
||||||
|
|
||||||
@@ -402,6 +392,14 @@ abstract class AbstractAndroidProjectHandler<V>(private val kotlinConfigurationT
|
|||||||
protected abstract fun getJavaTask(variantData: V): AbstractCompile?
|
protected abstract fun getJavaTask(variantData: V): AbstractCompile?
|
||||||
protected abstract fun addJavaSourceDirectoryToVariantModel(variantData: V, javaSourceDirectory: File): Unit
|
protected abstract fun addJavaSourceDirectoryToVariantModel(variantData: V, javaSourceDirectory: File): Unit
|
||||||
|
|
||||||
|
protected abstract fun wireKotlinTasks(project: Project,
|
||||||
|
androidPlugin: BasePlugin,
|
||||||
|
androidExt: BaseExtension,
|
||||||
|
variantData: V,
|
||||||
|
javaTask: AbstractCompile,
|
||||||
|
kotlinTask: KotlinCompile,
|
||||||
|
kotlinAfterJavaTask: KotlinCompile?): Unit
|
||||||
|
|
||||||
protected abstract fun configureMultiProjectIc(project: Project,
|
protected abstract fun configureMultiProjectIc(project: Project,
|
||||||
variantData: V,
|
variantData: V,
|
||||||
javaTask: AbstractCompile,
|
javaTask: AbstractCompile,
|
||||||
@@ -455,10 +453,6 @@ abstract class AbstractAndroidProjectHandler<V>(private val kotlinConfigurationT
|
|||||||
val variantDataName = getVariantName(variantData)
|
val variantDataName = getVariantName(variantData)
|
||||||
logger.kotlinDebug("Process variant [$variantDataName]")
|
logger.kotlinDebug("Process variant [$variantDataName]")
|
||||||
|
|
||||||
val testedVariantData = getTestedVariantData(variantData)
|
|
||||||
val isAndroidTestVariant = variantDataName.endsWith("androidTest", ignoreCase = true) &&
|
|
||||||
testedVariantData != null
|
|
||||||
|
|
||||||
val javaTask = getJavaTask(variantData)
|
val javaTask = getJavaTask(variantData)
|
||||||
|
|
||||||
if (javaTask == null) {
|
if (javaTask == null) {
|
||||||
@@ -474,7 +468,6 @@ abstract class AbstractAndroidProjectHandler<V>(private val kotlinConfigurationT
|
|||||||
// store kotlin classes in separate directory. They will serve as class-path to java compiler
|
// store kotlin classes in separate directory. They will serve as class-path to java compiler
|
||||||
kotlinTask.destinationDir = File(project.buildDir, "tmp/kotlin-classes/$variantDataName")
|
kotlinTask.destinationDir = File(project.buildDir, "tmp/kotlin-classes/$variantDataName")
|
||||||
kotlinTask.description = "Compiles the $variantDataName kotlin."
|
kotlinTask.description = "Compiles the $variantDataName kotlin."
|
||||||
kotlinTask.setDependsOn(javaTask.dependsOn)
|
|
||||||
|
|
||||||
val isKapt3Enabled = Kapt3GradleSubplugin.isEnabled(project)
|
val isKapt3Enabled = Kapt3GradleSubplugin.isEnabled(project)
|
||||||
|
|
||||||
@@ -502,10 +495,6 @@ abstract class AbstractAndroidProjectHandler<V>(private val kotlinConfigurationT
|
|||||||
val appliedPlugins = subpluginEnvironment.addSubpluginOptions(
|
val appliedPlugins = subpluginEnvironment.addSubpluginOptions(
|
||||||
project, kotlinTask, javaTask, variantData, null)
|
project, kotlinTask, javaTask, variantData, null)
|
||||||
|
|
||||||
kotlinTask.mapClasspath {
|
|
||||||
javaTask.classpath + project.files(AndroidGradleWrapper.getRuntimeJars(androidPlugin, androidExt))
|
|
||||||
}
|
|
||||||
|
|
||||||
var kotlinAfterJavaTask: KotlinCompile? = null
|
var kotlinAfterJavaTask: KotlinCompile? = null
|
||||||
|
|
||||||
if (javaTask is JavaCompile && aptFiles.isNotEmpty() && !isKapt3Enabled) {
|
if (javaTask is JavaCompile && aptFiles.isNotEmpty() && !isKapt3Enabled) {
|
||||||
@@ -524,18 +513,11 @@ abstract class AbstractAndroidProjectHandler<V>(private val kotlinConfigurationT
|
|||||||
configureSources(task, variantData)
|
configureSources(task, variantData)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isAndroidTestVariant) {
|
|
||||||
// Android Gradle plugin bypasses the Gradle finalizedBy for its tasks in some cases, and
|
|
||||||
// the Kotlin classes may not be copied for the tested variant. Make sure they are.
|
|
||||||
kotlinTask.dependsOn(syncOutputTaskName(getVariantName(testedVariantData!!)))
|
|
||||||
}
|
|
||||||
|
|
||||||
appliedPlugins.flatMap { it.getSubpluginKotlinTasks(project, kotlinTask) }
|
appliedPlugins.flatMap { it.getSubpluginKotlinTasks(project, kotlinTask) }
|
||||||
.forEach { configureSources(it, variantData) }
|
.forEach { configureSources(it, variantData) }
|
||||||
|
|
||||||
//todo Wire tasks and classpaths with the new API
|
wireKotlinTasks(project, androidPlugin, androidExt, variantData, javaTask,
|
||||||
configureJavaTask(kotlinTask, javaTask, logger)
|
kotlinTask, kotlinAfterJavaTask)
|
||||||
createSyncOutputTask(project, kotlinTask, javaTask, kotlinAfterJavaTask, variantDataName)
|
|
||||||
|
|
||||||
configureMultiProjectIc(project, variantData, javaTask, kotlinTask, kotlinAfterJavaTask)
|
configureMultiProjectIc(project, variantData, javaTask, kotlinTask, kotlinAfterJavaTask)
|
||||||
}
|
}
|
||||||
@@ -555,7 +537,7 @@ abstract class AbstractAndroidProjectHandler<V>(private val kotlinConfigurationT
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun configureJavaTask(kotlinTask: KotlinCompile, javaTask: AbstractCompile, logger: Logger) {
|
internal fun configureJavaTask(kotlinTask: KotlinCompile, javaTask: AbstractCompile, logger: Logger) {
|
||||||
// Gradle Java IC in older Gradle versions (before 2.14) cannot check .class directories updates.
|
// Gradle Java IC in older Gradle versions (before 2.14) cannot check .class directories updates.
|
||||||
// To make it work, reset the up-to-date status of compileJava with this flag.
|
// To make it work, reset the up-to-date status of compileJava with this flag.
|
||||||
kotlinTask.anyClassesCompiled = false
|
kotlinTask.anyClassesCompiled = false
|
||||||
@@ -587,9 +569,9 @@ private fun configureJavaTask(kotlinTask: KotlinCompile, javaTask: AbstractCompi
|
|||||||
javaTask.appendClasspathDynamically(kotlinTask.destinationDir!!)
|
javaTask.appendClasspathDynamically(kotlinTask.destinationDir!!)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun syncOutputTaskName(variantName: String) = "copy${variantName.capitalize()}KotlinClasses"
|
internal fun syncOutputTaskName(variantName: String) = "copy${variantName.capitalize()}KotlinClasses"
|
||||||
|
|
||||||
private fun createSyncOutputTask(
|
internal fun createSyncOutputTask(
|
||||||
project: Project,
|
project: Project,
|
||||||
kotlinTask: KotlinCompile,
|
kotlinTask: KotlinCompile,
|
||||||
javaTask: AbstractCompile,
|
javaTask: AbstractCompile,
|
||||||
|
|||||||
+25
-1
@@ -1,5 +1,6 @@
|
|||||||
package org.jetbrains.kotlin.gradle.plugin
|
package org.jetbrains.kotlin.gradle.plugin
|
||||||
|
|
||||||
|
import com.android.build.gradle.BaseExtension
|
||||||
import com.android.build.gradle.BasePlugin
|
import com.android.build.gradle.BasePlugin
|
||||||
import com.android.build.gradle.internal.variant.BaseVariantData
|
import com.android.build.gradle.internal.variant.BaseVariantData
|
||||||
import com.android.build.gradle.internal.variant.BaseVariantOutputData
|
import com.android.build.gradle.internal.variant.BaseVariantOutputData
|
||||||
@@ -31,6 +32,30 @@ internal class LegacyAndroidAndroidProjectHandler(kotlinConfigurationTools: Kotl
|
|||||||
variantManager.variantDataList.forEach(action)
|
variantManager.variantDataList.forEach(action)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun wireKotlinTasks(project: Project,
|
||||||
|
androidPlugin: BasePlugin,
|
||||||
|
androidExt: BaseExtension,
|
||||||
|
variantData: BaseVariantData<out BaseVariantOutputData>,
|
||||||
|
javaTask: AbstractCompile,
|
||||||
|
kotlinTask: KotlinCompile,
|
||||||
|
kotlinAfterJavaTask: KotlinCompile?) {
|
||||||
|
|
||||||
|
kotlinTask.setDependsOn(javaTask.dependsOn)
|
||||||
|
|
||||||
|
kotlinTask.mapClasspath {
|
||||||
|
javaTask.classpath + project.files(AndroidGradleWrapper.getRuntimeJars(androidPlugin, androidExt))
|
||||||
|
}
|
||||||
|
|
||||||
|
getTestedVariantData(variantData)?.let { testedVariantData ->
|
||||||
|
// Android Gradle plugin bypasses the Gradle finalizedBy for its tasks in some cases, and
|
||||||
|
// the Kotlin classes may not be copied for the tested variant. Make sure they are.
|
||||||
|
kotlinTask.dependsOn(syncOutputTaskName(getVariantName(testedVariantData)))
|
||||||
|
}
|
||||||
|
|
||||||
|
configureJavaTask(kotlinTask, javaTask, logger)
|
||||||
|
createSyncOutputTask(project, kotlinTask, javaTask, kotlinAfterJavaTask, getVariantName(variantData))
|
||||||
|
}
|
||||||
|
|
||||||
override fun getVariantName(variant: BaseVariantData<out BaseVariantOutputData>): String = variant.name
|
override fun getVariantName(variant: BaseVariantData<out BaseVariantOutputData>): String = variant.name
|
||||||
|
|
||||||
override fun checkVariant(variant: BaseVariantData<out BaseVariantOutputData>): Unit {
|
override fun checkVariant(variant: BaseVariantData<out BaseVariantOutputData>): Unit {
|
||||||
@@ -44,7 +69,6 @@ internal class LegacyAndroidAndroidProjectHandler(kotlinConfigurationTools: Kotl
|
|||||||
override fun getJavaTask(variantData: BaseVariantData<out BaseVariantOutputData>): AbstractCompile? =
|
override fun getJavaTask(variantData: BaseVariantData<out BaseVariantOutputData>): AbstractCompile? =
|
||||||
AndroidGradleWrapper.getJavaTask(variantData)
|
AndroidGradleWrapper.getJavaTask(variantData)
|
||||||
|
|
||||||
|
|
||||||
override fun addJavaSourceDirectoryToVariantModel(variantData: BaseVariantData<out BaseVariantOutputData>,
|
override fun addJavaSourceDirectoryToVariantModel(variantData: BaseVariantData<out BaseVariantOutputData>,
|
||||||
javaSourceDirectory: File) =
|
javaSourceDirectory: File) =
|
||||||
variantData.addJavaSourceFoldersToModel(javaSourceDirectory)
|
variantData.addJavaSourceFoldersToModel(javaSourceDirectory)
|
||||||
|
|||||||
Reference in New Issue
Block a user