diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerRunner.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerRunner.kt index 2b6210a76ec..b82eb5cd7b4 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerRunner.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerRunner.kt @@ -27,6 +27,7 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinWithJavaTarget import org.jetbrains.kotlin.gradle.plugin.mpp.isMain import org.jetbrains.kotlin.gradle.plugin.mpp.ownModuleName import org.jetbrains.kotlin.gradle.tasks.KotlinCompileTaskData +import org.jetbrains.kotlin.gradle.tasks.locateTask import org.jetbrains.kotlin.gradle.utils.archivePathCompatible import org.jetbrains.kotlin.gradle.utils.newTmpFile import org.jetbrains.kotlin.gradle.utils.relativeToRoot @@ -201,7 +202,7 @@ internal open class GradleCompilerRunner(protected val task: Task) { if (compilation.isMain()) { if (isMultiplatformProject) { - (project.tasks.findByName(target.artifactsTaskName) as? AbstractArchiveTask)?.let { jarTask -> + project.locateTask(target.artifactsTaskName)?.configure { jarTask -> jarToModule[jarTask.archivePathCompatible.canonicalFile] = module } } else { 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 106a5dbe159..8cd118169a2 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 @@ -21,6 +21,7 @@ import org.gradle.api.plugins.InvalidPluginException import org.gradle.api.plugins.JavaPlugin import org.gradle.api.plugins.JavaPluginConvention import org.gradle.api.plugins.MavenPluginConvention +import org.gradle.api.provider.Provider import org.gradle.api.publish.PublishingExtension import org.gradle.api.publish.maven.MavenPublication import org.gradle.api.tasks.CompileClasspathNormalizer @@ -222,7 +223,10 @@ internal class Kotlin2JvmSourceSetProcessor( .flatMap { it.getSubpluginKotlinTasks(project, kotlinTaskInstance) } .forEach { plugin -> kotlinCompilation.allKotlinSourceSets.forEach { sourceSet -> plugin.source(sourceSet.kotlin) } } - javaTask?.let { configureJavaTask(kotlinTaskInstance, it) } + javaSourceSet?.let { java -> + val javaTask = project.tasks.withType().named(java.compileJavaTaskName) + configureJavaTask(kotlinTask, javaTask) + } if (project.pluginManager.hasPlugin("java-library") && sourceSetName == SourceSet.MAIN_SOURCE_SET_NAME) { registerKotlinOutputForJavaLibrary(kotlinTaskInstance.destinationDir, kotlinTaskInstance) @@ -405,10 +409,10 @@ internal class KotlinCommonSourceSetProcessor( tasksProvider, taskDescription = "Compiles the kotlin sources in $compilation to Metadata.", kotlinCompilation = compilation ) { override fun doTargetSpecificProcessing() { - project.tasks.findByName(kotlinCompilation.compileAllTaskName)!!.dependsOn(kotlinTask) + project.tasks.named(kotlinCompilation.compileAllTaskName).dependsOn(kotlinTask) // can be missing (e.g. in case of tests) if (kotlinCompilation.isMain()) { - project.tasks.findByName(kotlinCompilation.target.artifactsTaskName)?.dependsOn(kotlinTask) + project.locateTask(kotlinCompilation.target.artifactsTaskName)?.dependsOn(kotlinTask) } project.runOnceAfterEvaluated("KotlinCommonSourceSetProcessor.doTargetSpecificProcessing", kotlinTask) { @@ -514,10 +518,10 @@ internal abstract class AbstractKotlinPlugin( } private fun configureClassInspectionForIC(project: Project) { - val classesTask = project.tasks.findByName(JavaPlugin.CLASSES_TASK_NAME) - val jarTask = project.tasks.findByName(JavaPlugin.JAR_TASK_NAME) + val classesTask = project.locateTask(JavaPlugin.CLASSES_TASK_NAME) + val jarTask = project.locateTask(JavaPlugin.JAR_TASK_NAME) - if (classesTask == null || jarTask !is Jar) { + if (classesTask == null || jarTask == null) { project.logger.info( "Could not configure class inspection task " + "(classes task = ${classesTask?.javaClass?.canonicalName}, " + @@ -528,8 +532,8 @@ internal abstract class AbstractKotlinPlugin( val inspectTask = project.registerTask("inspectClassesForKotlinIC") { it.sourceSetName = SourceSet.MAIN_SOURCE_SET_NAME - it.archivePath.set(project.provider { jarTask.archivePathCompatible.canonicalPath }) - it.archiveName.set(project.provider { jarTask.archiveFileName.get() }) + it.archivePath.set(project.provider { jarTask.get().archivePathCompatible.canonicalPath }) + it.archiveName.set(project.provider { jarTask.get().archiveFileName.get() }) it.dependsOn(classesTask) } jarTask.dependsOn(inspectTask) @@ -1085,27 +1089,33 @@ abstract class AbstractAndroidProjectHandler(private val kotlinConfigurationTool } } -internal fun configureJavaTask(kotlinTask: KotlinCompile, javaTask: AbstractCompile) { - kotlinTask.javaOutputDir = javaTask.destinationDir +internal fun configureJavaTask( + kotlinTaskProvider: TaskProvider, + javaTaskProvider: TaskProvider +) { + javaTaskProvider.configure { javaTask -> + val kotlinTask = kotlinTaskProvider.get() + kotlinTask.javaOutputDir = javaTask.destinationDir - // Make Gradle check if the javaTask is up-to-date based on the Kotlin classes - javaTask.inputs.run { - dir(kotlinTask.destinationDir) - .withNormalizer(CompileClasspathNormalizer::class.java) - .withPropertyName("${kotlinTask.name}OutputClasses") + // Make Gradle check if the javaTask is up-to-date based on the Kotlin classes + javaTask.inputs.run { + dir(kotlinTask.destinationDir) + .withNormalizer(CompileClasspathNormalizer::class.java) + .withPropertyName("${kotlinTask.name}OutputClasses") + } + // Also, use kapt1 annotations file for up-to-date check since annotation processing is done with javac + javaTask.dependsOn(kotlinTask) + /* + * It's important to modify javaTask.classpath only in doFirst, + * because Android plugin uses ConventionMapping to modify it too (see JavaCompileConfigAction.execute), + * and setting classpath explicitly prevents usage of Android mappings. + * Also classpath set by Android can be modified after execution of some tasks (see VarianConfiguration.getCompileClasspath) + * ex. it adds some support libraries jars after execution of prepareComAndroidSupportSupportV42311Library task, + * so it's only safe to modify javaTask.classpath right before its usage + */ + // todo: remove? + javaTask.appendClasspathDynamically(kotlinTask.destinationDir) } - // Also, use kapt1 annotations file for up-to-date check since annotation processing is done with javac - javaTask.dependsOn(kotlinTask) - /* - * It's important to modify javaTask.classpath only in doFirst, - * because Android plugin uses ConventionMapping to modify it too (see JavaCompileConfigAction.execute), - * and setting classpath explicitly prevents usage of Android mappings. - * Also classpath set by Android can be modified after execution of some tasks (see VarianConfiguration.getCompileClasspath) - * ex. it adds some support libraries jars after execution of prepareComAndroidSupportSupportV42311Library task, - * so it's only safe to modify javaTask.classpath right before its usage - */ - // todo: remove? - javaTask.appendClasspathDynamically(kotlinTask.destinationDir) } private fun ifKaptEnabled(project: Project, block: () -> Unit) { diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinTargetConfigurator.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinTargetConfigurator.kt index cf40f267fb3..0c05a92a29c 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinTargetConfigurator.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinTargetConfigurator.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.gradle.plugin +import org.gradle.api.DefaultTask import org.gradle.api.NamedDomainObjectContainer import org.gradle.api.Project import org.gradle.api.Task @@ -21,6 +22,7 @@ import org.gradle.api.plugins.BasePlugin import org.gradle.api.plugins.ExtensionAware import org.gradle.api.plugins.JavaBasePlugin import org.gradle.api.tasks.Delete +import org.gradle.api.tasks.TaskProvider import org.gradle.api.tasks.bundling.Jar import org.gradle.api.tasks.bundling.Zip import org.gradle.language.base.plugins.LifecycleBasePlugin @@ -31,6 +33,8 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.* import org.jetbrains.kotlin.gradle.targets.js.KotlinJsCompilerAttribute import org.jetbrains.kotlin.gradle.targets.js.KotlinJsTarget import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrTarget +import org.jetbrains.kotlin.gradle.tasks.registerTask +import org.jetbrains.kotlin.gradle.tasks.withType import org.jetbrains.kotlin.gradle.utils.COMPILE import org.jetbrains.kotlin.gradle.utils.RUNTIME import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName @@ -65,8 +69,9 @@ abstract class AbstractKotlinTargetConfigurator ) : KotlinTargetConfigurator { private fun Project.registerOutputsForStaleOutputCleanup(kotlinCompilation: KotlinCompilation<*>) { - val cleanTask = tasks.getByName(LifecycleBasePlugin.CLEAN_TASK_NAME) as Delete - cleanTask.delete(kotlinCompilation.output.allOutputs) + tasks.withType().named(LifecycleBasePlugin.CLEAN_TASK_NAME).configure { cleanTask -> + cleanTask.delete(kotlinCompilation.output.allOutputs) + } } protected open fun setupCompilationDependencyFiles(compilation: KotlinCompilation) { @@ -125,10 +130,11 @@ abstract class AbstractKotlinTargetConfigurator ) { val project = compilation.target.project - val resourcesTask = project.tasks.maybeCreate(compilation.processResourcesTaskName, ProcessResources::class.java) - resourcesTask.description = "Processes $resourceSet." - DslObject(resourcesTask).conventionMapping.map("destinationDir") { project.file(compilation.output.resourcesDir) } - resourcesTask.from(resourceSet) + project.registerTask(compilation.processResourcesTaskName) { resourcesTask -> + resourcesTask.description = "Processes $resourceSet." + DslObject(resourcesTask).conventionMapping.map("destinationDir") { project.file(compilation.output.resourcesDir) } + resourcesTask.from(resourceSet) + } } protected fun createLifecycleTask(compilation: KotlinCompilation<*>) { @@ -136,12 +142,12 @@ abstract class AbstractKotlinTargetConfigurator compilation.output.classesDirs.from(project.files().builtBy(compilation.compileAllTaskName)) - project.tasks.create(compilation.compileAllTaskName).apply { - group = LifecycleBasePlugin.BUILD_GROUP - description = "Assembles outputs for compilation '${compilation.name}' of target '${compilation.target.name}'" - dependsOn(compilation.compileKotlinTaskName) + project.registerTask(compilation.compileAllTaskName) { + it.group = LifecycleBasePlugin.BUILD_GROUP + it.description = "Assembles outputs for compilation '${compilation.name}' of target '${compilation.target.name}'" + it.dependsOn(compilation.compileKotlinTaskName) if (compilation is KotlinCompilationWithResources) { - dependsOn(compilation.processResourcesTaskName) + it.dependsOn(compilation.processResourcesTaskName) } } } @@ -228,22 +234,23 @@ abstract class AbstractKotlinTargetConfigurator override fun configureBuild(target: KotlinTargetType) { val project = target.project - val buildNeeded = project.tasks.getByName(JavaBasePlugin.BUILD_NEEDED_TASK_NAME) - val buildDependent = project.tasks.getByName(JavaBasePlugin.BUILD_DEPENDENTS_TASK_NAME) + val buildNeeded = project.tasks.named(JavaBasePlugin.BUILD_NEEDED_TASK_NAME) + val buildDependent = project.tasks.named(JavaBasePlugin.BUILD_DEPENDENTS_TASK_NAME) if (createTestCompilation) { val testCompilation = target.compilations.getByName(KotlinCompilation.TEST_COMPILATION_NAME) if (testCompilation is KotlinCompilationToRunnableFiles) { - addDependsOnTaskInOtherProjects(buildNeeded, true, testCompilation.deprecatedRuntimeConfigurationName) - addDependsOnTaskInOtherProjects(buildDependent, false, testCompilation.deprecatedRuntimeConfigurationName) + addDependsOnTaskInOtherProjects(project, buildNeeded, true, testCompilation.deprecatedRuntimeConfigurationName) + addDependsOnTaskInOtherProjects(project, buildDependent, false, testCompilation.deprecatedRuntimeConfigurationName) } } } - private fun addDependsOnTaskInOtherProjects(task: Task, useDependedOn: Boolean, configurationName: String) { - val project = task.project + private fun addDependsOnTaskInOtherProjects(project: Project, taskProvider: TaskProvider<*>, useDependedOn: Boolean, configurationName: String) { val configuration = project.configurations.getByName(configurationName) - task.dependsOn(configuration.getTaskDependencyFromProjectDependency(useDependedOn, task.name)) + taskProvider.configure { task -> + task.dependsOn(configuration.getTaskDependencyFromProjectDependency(useDependedOn, taskProvider.name)) + } } companion object { @@ -359,12 +366,12 @@ abstract class KotlinOnlyTargetConfigurator { //TODO Change Jar on Zip - return target.project.tasks.create(target.artifactsTaskName, Jar::class.java).apply { - description = "Assembles an archive containing the main classes." - group = BasePlugin.BUILD_GROUP - from(target.compilations.getByName(KotlinCompilation.MAIN_COMPILATION_NAME).output.allOutputs) + return target.project.registerTask(target.artifactsTaskName) { + it.description = "Assembles an archive containing the main classes." + it.group = BasePlugin.BUILD_GROUP + it.from(target.compilations.getByName(KotlinCompilation.MAIN_COMPILATION_NAME).output.allOutputs) } } @@ -375,7 +382,11 @@ abstract class KotlinOnlyTargetConfigurator + task.configure { taskInstance -> + taskInstance.archiveAppendix.set(classifier.toLowerCase()) + } + } // Workaround: adding the artifact during configuration seems to interfere with the Java plugin, which results into missing // task dependency 'assemble -> jar' if the Java plugin is applied after this steps diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinMetadataTarget.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinMetadataTarget.kt index 860e6e2d853..8ed308de305 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinMetadataTarget.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinMetadataTarget.kt @@ -30,7 +30,7 @@ open class KotlinMetadataTarget @Inject constructor(project: Project) : val javaApiUsage = project.usageByName("java-api-jars") usageContexts += run { - val allMetadataJar = project.tasks.getByName(KotlinMetadataTargetConfigurator.ALL_METADATA_JAR_NAME) + val allMetadataJar = project.tasks.named(KotlinMetadataTargetConfigurator.ALL_METADATA_JAR_NAME) val allMetadataArtifact = project.artifacts.add(Dependency.ARCHIVES_CONFIGURATION, allMetadataJar) { it.classifier = if (project.isCompatibilityMetadataVariantEnabled) "all" else "" } diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinMultiplatformPlugin.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinMultiplatformPlugin.kt index 064fea23d5b..3e503b7f7b1 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinMultiplatformPlugin.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinMultiplatformPlugin.kt @@ -17,6 +17,8 @@ import org.gradle.api.publish.PublicationContainer import org.gradle.api.publish.PublishingExtension import org.gradle.api.publish.maven.MavenPublication import org.gradle.api.publish.maven.internal.publication.MavenPublicationInternal +import org.gradle.api.publish.maven.tasks.AbstractPublishToMaven +import org.gradle.api.tasks.TaskProvider import org.gradle.api.tasks.compile.AbstractCompile import org.gradle.jvm.tasks.Jar import org.gradle.util.ConfigureUtil @@ -35,9 +37,9 @@ import org.jetbrains.kotlin.gradle.plugin.statistics.KotlinBuildStatsService import org.jetbrains.kotlin.gradle.scripting.internal.ScriptingGradleSubplugin import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrTargetPreset import org.jetbrains.kotlin.gradle.targets.metadata.isKotlinGranularMetadataEnabled -import org.jetbrains.kotlin.gradle.utils.SingleWarningPerBuild -import org.jetbrains.kotlin.gradle.utils.checkGradleCompatibility -import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName +import org.jetbrains.kotlin.gradle.tasks.registerTask +import org.jetbrains.kotlin.gradle.tasks.withType +import org.jetbrains.kotlin.gradle.utils.* import org.jetbrains.kotlin.konan.target.HostManager import org.jetbrains.kotlin.konan.target.KonanTarget.* import org.jetbrains.kotlin.konan.target.presetName @@ -338,7 +340,7 @@ internal fun applyUserDefinedAttributes(target: AbstractKotlinTarget) { } } -internal fun sourcesJarTask(compilation: KotlinCompilation<*>, componentName: String?, artifactNameAppendix: String): Jar = +internal fun sourcesJarTask(compilation: KotlinCompilation<*>, componentName: String?, artifactNameAppendix: String): TaskProvider = sourcesJarTask(compilation.target.project, lazy { compilation.allKotlinSourceSets }, componentName, artifactNameAppendix) internal fun sourcesJarTask( @@ -346,20 +348,25 @@ internal fun sourcesJarTask( sourceSets: Lazy>, componentName: String?, artifactNameAppendix: String -): Jar { +): TaskProvider { val taskName = lowerCamelCaseName(componentName, "sourcesJar") - (project.tasks.findByName(taskName) as? Jar)?.let { return it } + project.tasks.withType().run { + if (taskName in names) + return named(taskName) + } - val result = project.tasks.create(taskName, Jar::class.java) { sourcesJar -> + val result = project.registerTask(taskName) { sourcesJar -> sourcesJar.archiveAppendix.set(artifactNameAppendix) sourcesJar.archiveClassifier.set("sources") } project.whenEvaluated { - sourceSets.value.forEach { sourceSet -> - result.from(sourceSet.kotlin) { copySpec -> - copySpec.into(sourceSet.name) + result.configure { + sourceSets.value.forEach { sourceSet -> + it.from(sourceSet.kotlin) { copySpec -> + copySpec.into(sourceSet.name) + } } } } 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 b03b1a74363..876402327ec 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 @@ -113,7 +113,7 @@ abstract class AbstractKotlinCompilation( // To configure a task that may have not yet been created at this point, use 'withType-matching-all`: .withType(AbstractKotlinCompile::class.java) .matching { it.name == compileKotlinTaskName } - .all { compileKotlinTask -> + .configureEach { compileKotlinTask -> compileKotlinTask.configureAction() } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/KotlinJsIrTargetConfigurator.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/KotlinJsIrTargetConfigurator.kt index d07c83a5876..478ffb485ac 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/KotlinJsIrTargetConfigurator.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/KotlinJsIrTargetConfigurator.kt @@ -6,6 +6,7 @@ package org.jetbrains.kotlin.gradle.targets.js.ir import org.gradle.api.attributes.Usage +import org.gradle.api.tasks.TaskProvider import org.gradle.api.tasks.bundling.Zip import org.jetbrains.kotlin.gradle.dsl.KotlinJsOptions import org.jetbrains.kotlin.gradle.plugin.* @@ -54,9 +55,9 @@ open class KotlinJsIrTargetConfigurator(kotlinPluginVersion: String) : return KotlinJsIrSourceSetProcessor(tasksProvider, compilation, kotlinPluginVersion) } - override fun createArchiveTasks(target: KotlinJsIrTarget): Zip { + override fun createArchiveTasks(target: KotlinJsIrTarget): TaskProvider { return super.createArchiveTasks(target).apply { - archiveExtension.set(KLIB_TYPE) + configure { it.archiveExtension.set(KLIB_TYPE) } } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinJvmTarget.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinJvmTarget.kt index 04b7983dae3..79cfe2dec29 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinJvmTarget.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinJvmTarget.kt @@ -19,7 +19,7 @@ import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension import org.jetbrains.kotlin.gradle.plugin.* import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJvmCompilation import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinOnlyTarget -import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinWithJavaCompilation +import org.jetbrains.kotlin.gradle.tasks.withType import org.jetbrains.kotlin.gradle.utils.addExtendsFromRelation import java.util.concurrent.Callable import javax.inject.Inject @@ -61,11 +61,11 @@ open class KotlinJvmTarget @Inject constructor( javaPluginConvention.sourceSets.all { javaSourceSet -> val compilation = compilations.getByName(javaSourceSet.name) - val compileJavaTask = project.tasks.getByName(javaSourceSet.compileJavaTaskName) as AbstractCompile + val compileJavaTask = project.tasks.withType().named(javaSourceSet.compileJavaTaskName) setupJavaSourceSetSourcesAndResources(javaSourceSet, compilation) - val javaClasses = project.files(Callable { compileJavaTask.destinationDir }).builtBy(compileJavaTask) + val javaClasses = project.files(compileJavaTask.map { it.destinationDir }) compilation.output.classesDirs.from(javaClasses) @@ -110,16 +110,19 @@ open class KotlinJvmTarget @Inject constructor( private fun disableJavaPluginTasks(javaPluginConvention: JavaPluginConvention) { // A 'normal' build should not do redundant job like running the tests twice or building two JARs, // so disable some tasks and just make them depend on the others: - val targetJar = project.tasks.getByName(artifactsTaskName) as Jar - val javaJar = project.tasks.getByName(javaPluginConvention.sourceSets.getByName("main").jarTaskName) as Jar - (javaJar.source as? ConfigurableFileCollection)?.setFrom(targetJar.source) - javaJar.conventionMapping("archiveName") { targetJar.archiveFileName.get() } - javaJar.dependsOn(targetJar) - javaJar.enabled = false + val targetJar = project.tasks.withType(Jar::class.java).named(artifactsTaskName) - val javaTestTask = project.tasks.getByName(JavaPlugin.TEST_TASK_NAME) as Test - javaTestTask.dependsOn(project.tasks.getByName(testTaskName) as Test) - javaTestTask.enabled = false + project.tasks.withType(Jar::class.java).named(javaPluginConvention.sourceSets.getByName("main").jarTaskName) { javaJar -> + (javaJar.source as? ConfigurableFileCollection)?.setFrom(targetJar.map { it.source }) + javaJar.conventionMapping("archiveName") { targetJar.get().archiveFileName.get() } + javaJar.dependsOn(targetJar) + javaJar.enabled = false + } + + project.tasks.withType(Test::class.java).named(JavaPlugin.TEST_TASK_NAME) { javaTestTask -> + javaTestTask.dependsOn(project.tasks.named(testTaskName)) + javaTestTask.enabled = false + } } private fun setupDependenciesCrossInclusionForJava( diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinJvmTargetConfigurator.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinJvmTargetConfigurator.kt index 827fed8030d..ca5a0bdd768 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinJvmTargetConfigurator.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinJvmTargetConfigurator.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.gradle.targets.jvm +import org.gradle.api.Task import org.gradle.api.plugins.JavaBasePlugin import org.jetbrains.kotlin.gradle.plugin.* import org.jetbrains.kotlin.gradle.plugin.Kotlin2JvmSourceSetProcessor @@ -12,6 +13,8 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSetProcessor import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJvmCompilation import org.jetbrains.kotlin.gradle.targets.jvm.tasks.KotlinJvmTest import org.jetbrains.kotlin.gradle.tasks.KotlinTasksProvider +import org.jetbrains.kotlin.gradle.tasks.dependsOn +import org.jetbrains.kotlin.gradle.tasks.locateTask import org.jetbrains.kotlin.gradle.tasks.registerTask import org.jetbrains.kotlin.gradle.testing.internal.kotlinTestRegistry import org.jetbrains.kotlin.gradle.testing.testTaskName @@ -49,8 +52,8 @@ class KotlinJvmTargetConfigurator(kotlinPluginVersion: String) : ): KotlinJvmTestRun = KotlinJvmTestRun(name, target).apply { val testTaskOrProvider = target.project.registerTask(testTaskName) { testTask -> testTask.targetName = target.disambiguationClassifier - testTask.project.tasks.findByName(JavaBasePlugin.CHECK_TASK_NAME)?.dependsOn(testTask) } + target.project.locateTask(JavaBasePlugin.CHECK_TASK_NAME)?.dependsOn(testTaskOrProvider) executionTask = testTaskOrProvider diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/metadata/KotlinMetadataTargetConfigurator.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/metadata/KotlinMetadataTargetConfigurator.kt index 9076ba1b253..8a862f043eb 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/metadata/KotlinMetadataTargetConfigurator.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/metadata/KotlinMetadataTargetConfigurator.kt @@ -11,14 +11,12 @@ import org.gradle.api.attributes.Usage.USAGE_ATTRIBUTE import org.gradle.api.file.FileCollection import org.gradle.api.internal.component.SoftwareComponentInternal import org.gradle.api.plugins.BasePlugin -import org.gradle.api.tasks.AbstractCopyTask import org.gradle.api.tasks.TaskProvider import org.gradle.api.tasks.bundling.Jar import org.gradle.api.tasks.bundling.Zip import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions import org.jetbrains.kotlin.gradle.dsl.kotlinExtension import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension -import org.jetbrains.kotlin.gradle.dsl.multiplatformExtensionOrNull import org.jetbrains.kotlin.gradle.plugin.* import org.jetbrains.kotlin.gradle.plugin.mpp.* import org.jetbrains.kotlin.gradle.plugin.sources.* @@ -81,10 +79,10 @@ class KotlinMetadataTargetConfigurator(kotlinPluginVersion: String) : createMergedAllSourceSetsConfigurations(target) - val allMetadataJar = target.project.tasks.getByName(ALL_METADATA_JAR_NAME) as Jar + val allMetadataJar = target.project.tasks.withType().named(ALL_METADATA_JAR_NAME) createMetadataCompilationsForCommonSourceSets(target, allMetadataJar) - configureProjectStructureMetadataGeneration(allMetadataJar) + configureProjectStructureMetadataGeneration(target.project, allMetadataJar) setupDependencyTransformationForCommonSourceSets(target) @@ -125,12 +123,12 @@ class KotlinMetadataTargetConfigurator(kotlinPluginVersion: String) : override val kotlinTask: TaskProvider = with(nativeTargetConfigurator) { project.createKlibCompilationTask(kotlinCompilation) - }.thisTaskProvider + } override fun run() = Unit } - override fun createArchiveTasks(target: KotlinMetadataTarget): Zip { + override fun createArchiveTasks(target: KotlinMetadataTarget): TaskProvider { val result = super.createArchiveTasks(target) if (target.project.isKotlinGranularMetadataEnabled) { @@ -172,7 +170,7 @@ class KotlinMetadataTargetConfigurator(kotlinPluginVersion: String) : private fun createMetadataCompilationsForCommonSourceSets( target: KotlinMetadataTarget, - allMetadataJar: Jar + allMetadataJar: TaskProvider ) = target.project.whenEvaluated { // Do this after all targets are configured by the user build script @@ -194,14 +192,15 @@ class KotlinMetadataTargetConfigurator(kotlinPluginVersion: String) : } } - private fun configureProjectStructureMetadataGeneration(allMetadataJar: Jar): AbstractCopyTask { - val project = allMetadataJar.project + private fun configureProjectStructureMetadataGeneration(project: Project, allMetadataJar: TaskProvider) { val generateMetadata = project.createGenerateProjectStructureMetadataTask() - return allMetadataJar.from( - project.files(Callable { generateMetadata.get().resultXmlFile }).builtBy(generateMetadata) - ) { spec -> - spec.into("META-INF").rename { MULTIPLATFORM_PROJECT_METADATA_FILE_NAME } + allMetadataJar.configure { + it.from( + project.files(Callable { generateMetadata.get().resultXmlFile }).builtBy(generateMetadata) + ) { spec -> + spec.into("META-INF").rename { MULTIPLATFORM_PROJECT_METADATA_FILE_NAME } + } } } @@ -249,7 +248,7 @@ class KotlinMetadataTargetConfigurator(kotlinPluginVersion: String) : private fun createMetadataCompilation( target: KotlinMetadataTarget, sourceSet: KotlinSourceSet, - allMetadataJar: Jar, + allMetadataJar: TaskProvider, isHostSpecific: Boolean ): AbstractKotlinCompilation<*> { val project = target.project @@ -276,7 +275,7 @@ class KotlinMetadataTargetConfigurator(kotlinPluginVersion: String) : if (!isHostSpecific) { val metadataContent = project.filesWithUnpackedArchives(this@apply.output.allOutputs, setOf("klib")) - allMetadataJar.from(metadataContent) { spec -> spec.into(this@apply.defaultSourceSet.name) } + allMetadataJar.configure { it.from(metadataContent) { spec -> spec.into(this@apply.defaultSourceSet.name) } } } else { if (platformCompilations.filterIsInstance().none { it.konanTarget.enabledOnCurrentHost }) { // Then we don't have any platform module to put this compiled source set to, so disable the compilation task: diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/metadata/KotlinMetadataTargetPreset.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/metadata/KotlinMetadataTargetPreset.kt index 4322fac9444..ba8f20f52bd 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/metadata/KotlinMetadataTargetPreset.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/metadata/KotlinMetadataTargetPreset.kt @@ -57,8 +57,9 @@ class KotlinMetadataTargetPreset( project.whenEvaluated { // Since there's no default source set, apply language settings from commonMain: - val compileKotlinMetadata = mainCompilation.compileKotlinTask - applyLanguageSettingsToKotlinOptions(commonMainSourceSet.languageSettings, compileKotlinMetadata.kotlinOptions) + mainCompilation.compileKotlinTaskProvider.configure { compileKotlinMetadata -> + applyLanguageSettingsToKotlinOptions(commonMainSourceSet.languageSettings, compileKotlinMetadata.kotlinOptions) + } } } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/DefaultCInteropSettings.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/DefaultCInteropSettings.kt index e67b6524c76..763d581df16 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/DefaultCInteropSettings.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/DefaultCInteropSettings.kt @@ -10,6 +10,7 @@ import groovy.lang.Closure import org.gradle.api.Action import org.gradle.api.Project import org.gradle.api.file.FileCollection +import org.gradle.api.provider.Property import org.gradle.util.ConfigureUtil import org.jetbrains.kotlin.gradle.plugin.CInteropSettings import org.jetbrains.kotlin.gradle.plugin.CInteropSettings.IncludeDirectories @@ -56,7 +57,9 @@ open class DefaultCInteropSettings @Inject constructor( target.disambiguationClassifier ) - var defFile: File = project.projectDir.resolve("src/nativeInterop/cinterop/$name.def") + val defFile: Property = project.objects.property(File::class.java) + .apply { set(project.projectDir.resolve("src/nativeInterop/cinterop/$name.def")) } + var packageName: String? = null val compilerOpts = mutableListOf() @@ -69,7 +72,7 @@ open class DefaultCInteropSettings @Inject constructor( // DSL methods. override fun defFile(file: Any) { - defFile = project.file(file) + defFile.set(project.file(file)) } override fun packageName(value: String) { diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/KotlinNativeCompilation.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/KotlinNativeCompilation.kt index 8eab75fed39..bf8787d9b58 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/KotlinNativeCompilation.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/KotlinNativeCompilation.kt @@ -25,7 +25,6 @@ import org.jetbrains.kotlin.gradle.plugin.sources.getVisibleSourceSetsFromAssoci import org.jetbrains.kotlin.gradle.targets.metadata.getMetadataCompilationForSourceSet import org.jetbrains.kotlin.gradle.tasks.KotlinNativeCompile import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName -import org.jetbrains.kotlin.konan.target.HostManager import org.jetbrains.kotlin.konan.target.KonanTarget import java.util.concurrent.Callable diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/KotlinNativeTargetConfigurator.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/KotlinNativeTargetConfigurator.kt index f7c300a00a6..b9fe45e9b65 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/KotlinNativeTargetConfigurator.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/KotlinNativeTargetConfigurator.kt @@ -6,15 +6,15 @@ @file:Suppress("PackageDirectoryMismatch") // Old package for compatibility package org.jetbrains.kotlin.gradle.plugin +import org.gradle.api.DefaultTask import org.gradle.api.Project -import org.gradle.api.Task import org.gradle.api.artifacts.ConfigurationContainer import org.gradle.api.artifacts.Dependency import org.gradle.api.attributes.Usage.USAGE_ATTRIBUTE import org.gradle.api.internal.artifacts.ArtifactAttributes -import org.gradle.api.internal.artifacts.publish.DefaultPublishArtifact import org.gradle.api.internal.plugins.DefaultArtifactPublicationSet import org.gradle.api.plugins.BasePlugin +import org.gradle.api.provider.Provider import org.gradle.api.tasks.Copy import org.gradle.api.tasks.Exec import org.gradle.language.base.plugins.LifecycleBasePlugin @@ -33,7 +33,6 @@ import org.jetbrains.kotlin.gradle.testing.testTaskName import org.jetbrains.kotlin.konan.target.HostManager import org.jetbrains.kotlin.konan.target.KonanTarget import java.io.File -import java.util.* open class KotlinNativeTargetConfigurator( private val kotlinPluginVersion: String @@ -58,9 +57,9 @@ open class KotlinNativeTargetConfigurator( // region Artifact creation. private fun Project.createKlibArtifact( compilation: KotlinNativeCompilation, - artifactFile: File, + artifactFile: Provider, classifier: String?, - producingTask: Task, + producingTask: TaskProvider<*>, copy: Boolean = false ) { if (!compilation.konanTarget.enabledOnCurrentHost) { @@ -69,33 +68,30 @@ open class KotlinNativeTargetConfigurator( val apiElements = configurations.getByName(compilation.target.apiElementsConfigurationName) - val realProducingTask: Task + val realProducingTask: TaskProvider<*> // TODO: Someone remove this HACK PLEASE! val realArtifactFile = if (copy) { - realProducingTask = project.tasks.create("copy${producingTask.name.capitalize()}", Copy::class.java) { + realProducingTask = project.registerTask("copy${producingTask.name.capitalize()}") { val targetSubDirectory = compilation.target.disambiguationClassifier?.let { "$it/" }.orEmpty() it.destinationDir = project.buildDir.resolve("libs/$targetSubDirectory${compilation.name}") it.from(artifactFile) it.dependsOn(producingTask) } - realProducingTask.destinationDir.resolve(artifactFile.name) + realProducingTask.map { (it as Copy).destinationDir.resolve(artifactFile.get().name) } } else { realProducingTask = producingTask artifactFile } - val klibArtifact = DefaultPublishArtifact( - compilation.name, - "klib", - "klib", - classifier, - Date(), - realArtifactFile, - realProducingTask - ) - project.extensions.getByType(DefaultArtifactPublicationSet::class.java).addCandidate(klibArtifact) - - with(apiElements.outgoing) { + with(apiElements) { + val klibArtifact = project.artifacts.add(apiElements.name, realArtifactFile) { artifact -> + artifact.name = compilation.name + artifact.extension = "klib" + artifact.type = "klib" + artifact.classifier = classifier + artifact.builtBy(realProducingTask) + } + project.extensions.getByType(DefaultArtifactPublicationSet::class.java).addCandidate(klibArtifact) artifacts.add(klibArtifact) attributes.attribute(ArtifactAttributes.ARTIFACT_FORMAT, NativeArtifactFormat.KLIB) } @@ -103,115 +99,117 @@ open class KotlinNativeTargetConfigurator( private fun Project.createRegularKlibArtifact( compilation: KotlinNativeCompilation, - compileTask: KotlinNativeCompile - ) = createKlibArtifact(compilation, compileTask.outputFile.get(), null, compileTask) + compileTask: TaskProvider + ) = createKlibArtifact(compilation, compileTask.map { it.outputFile.get() }, null, compileTask) private fun Project.createCInteropKlibArtifact( interop: DefaultCInteropSettings, - interopTask: CInteropProcess - ) = createKlibArtifact(interop.compilation, interopTask.outputFile, "cinterop-${interop.name}", interopTask, copy = true) + interopTask: TaskProvider + ) = createKlibArtifact(interop.compilation, interopTask.map { it.outputFile }, "cinterop-${interop.name}", interopTask, copy = true) // endregion. // region Task creation. private fun Project.createLinkTask(binary: NativeBinary) { - tasks.create( - binary.linkTaskName, - KotlinNativeLink::class.java - ).apply { + val result = registerTask( + binary.linkTaskName + ) { val target = binary.target - this.binary = binary - group = BasePlugin.BUILD_GROUP - description = "Links ${binary.outputKind.description} '${binary.name}' for a target '${target.name}'." - enabled = binary.konanTarget.enabledOnCurrentHost + it.binary = binary + it.group = BasePlugin.BUILD_GROUP + it.description = "Links ${binary.outputKind.description} '${binary.name}' for a target '${target.name}'." + it.enabled = binary.konanTarget.enabledOnCurrentHost + it.destinationDir = binary.outputDirectory + } addCompilerPlugins() - if (binary !is TestExecutable) { - tasks.maybeCreate(target.artifactsTaskName).dependsOn(this) - tasks.maybeCreate(LifecycleBasePlugin.ASSEMBLE_TASK_NAME).dependsOn(this) - } + if (binary !is TestExecutable) { + tasks.named(binary.compilation.target.artifactsTaskName).configure { it.dependsOn(result) } + tasks.maybeCreate(LifecycleBasePlugin.ASSEMBLE_TASK_NAME).dependsOn(result) } } private fun Project.createRunTask(binary: Executable) { val taskName = binary.runTaskName ?: return - tasks.create(taskName, Exec::class.java).apply { - group = RUN_GROUP - description = "Executes Kotlin/Native executable ${binary.name} for target ${binary.target.name}" + registerTask(taskName) { exec -> + exec.group = RUN_GROUP + exec.description = "Executes Kotlin/Native executable ${binary.name} for target ${binary.target.name}" - enabled = binary.konanTarget.isCurrentHost + exec.enabled = binary.konanTarget.isCurrentHost - executable = binary.outputFile.absolutePath - workingDir = project.projectDir + exec.executable = binary.outputFile.absolutePath + exec.workingDir = project.projectDir - onlyIf { binary.outputFile.exists() } - dependsOn(binary.linkTaskName) + exec.onlyIf { binary.outputFile.exists() } + exec.dependsOn(binary.linkTaskName) } } - internal fun Project.createKlibCompilationTask(compilation: AbstractKotlinNativeCompilation): KotlinNativeCompile { - val compileTask = project.tasks.create( - compilation.compileKotlinTaskName, - KotlinNativeCompile::class.java - ).also { task -> - task.compilation = compilation - task.group = BasePlugin.BUILD_GROUP - task.description = "Compiles a klibrary from the '${compilation.name}' " + + internal fun Project.createKlibCompilationTask(compilation: AbstractKotlinNativeCompilation): TaskProvider { + val compileTaskProvider = registerTask( + compilation.compileKotlinTaskName + ) { + it.compilation = compilation + it.group = BasePlugin.BUILD_GROUP + it.description = "Compiles a klibrary from the '${compilation.name}' " + "compilation for target '${compilation.platformType.name}'." - task.enabled = compilation.konanTarget.enabledOnCurrentHost + it.enabled = compilation.konanTarget.enabledOnCurrentHost - task.destinationDir = klibOutputDirectory(compilation) - task.addCompilerPlugins() - compilation.output.addClassesDir { - project.files(task.outputFile).builtBy(task) - } + it.destinationDir = klibOutputDirectory(compilation) } - project.tasks.getByName(compilation.compileAllTaskName).dependsOn(compileTask) + + compilation.output.addClassesDir { + project.files(compileTaskProvider.map { it.outputFile }) + } + + + project.tasks.getByName(compilation.compileAllTaskName).dependsOn(compileTaskProvider) if (compilation.isMain()) { compilation as? KotlinNativeCompilation ?: error("Main shared-Native compilation is not yet supported!") project.tasks.getByName(compilation.target.artifactsTaskName).apply { - dependsOn(compileTask) + dependsOn(compileTaskProvider) } project.tasks.getByName(LifecycleBasePlugin.ASSEMBLE_TASK_NAME).apply { - dependsOn(compileTask) + dependsOn(compileTaskProvider) } - createRegularKlibArtifact(compilation, compileTask) + createRegularKlibArtifact(compilation, compileTaskProvider) } - return compileTask + + return compileTaskProvider } private fun Project.createCInteropTasks(compilation: KotlinNativeCompilation) { compilation.cinterops.all { interop -> - val interopTask = tasks.create(interop.interopProcessingTaskName, CInteropProcess::class.java).apply { - settings = interop - destinationDir = provider { klibOutputDirectory(compilation) } - group = INTEROP_GROUP - description = "Generates Kotlin/Native interop library '${interop.name}' " + + val interopTask = registerTask(interop.interopProcessingTaskName) { + it.settings = interop + it.destinationDir = provider { klibOutputDirectory(compilation) } + it.group = INTEROP_GROUP + it.description = "Generates Kotlin/Native interop library '${interop.name}' " + "for compilation '${compilation.name}'" + - "of target '${konanTarget.name}'." - enabled = compilation.konanTarget.enabledOnCurrentHost + "of target '${it.konanTarget.name}'." + it.enabled = compilation.konanTarget.enabledOnCurrentHost + } - val interopOutput = project.files(outputFileProvider).builtBy(this) - with(compilation) { - // Register the interop library as a dependency of the compilation to make IDE happy. - project.dependencies.add(compileDependencyConfigurationName, interopOutput) - if (isMain()) { - // Register the interop library as an outgoing klib to allow depending on projects with cinterops. - project.dependencies.add(target.apiElementsConfigurationName, interopOutput) - // Add the interop library in publication. - createCInteropKlibArtifact(interop, this@apply) - // We cannot add the interop library in an compilation output because in this case - // IDE doesn't see this library in module dependencies. So we have to manually add - // main interop libraries in dependencies of the default test compilation. - target.compilations.findByName(TEST_COMPILATION_NAME)?.let { testCompilation -> - project.dependencies.add(testCompilation.compileDependencyConfigurationName, interopOutput) - testCompilation.cinterops.all { - it.dependencyFiles += interopOutput - } + val interopOutput = project.files(interopTask.map { it.outputFileProvider }) + with(compilation) { + // Register the interop library as a dependency of the compilation to make IDE happy. + project.dependencies.add(compileDependencyConfigurationName, interopOutput) + if (isMain()) { + // Register the interop library as an outgoing klib to allow depending on projects with cinterops. + project.dependencies.add(target.apiElementsConfigurationName, interopOutput) + // Add the interop library in publication. + createCInteropKlibArtifact(interop, interopTask) + // We cannot add the interop library in an compilation output because in this case + // IDE doesn't see this library in module dependencies. So we have to manually add + // main interop libraries in dependencies of the default test compilation. + target.compilations.findByName(TEST_COMPILATION_NAME)?.let { testCompilation -> + project.dependencies.add(testCompilation.compileDependencyConfigurationName, interopOutput) + testCompilation.cinterops.all { + it.dependencyFiles += interopOutput } } } @@ -232,7 +230,7 @@ open class KotlinNativeTargetConfigurator( } override fun configureArchivesAndComponent(target: T): Unit = with(target.project) { - tasks.create(target.artifactsTaskName) + registerTask(target.artifactsTaskName) { } target.compilations.all { createKlibCompilationTask(it) } @@ -280,12 +278,14 @@ open class KotlinNativeTargetConfigurator( // Create an aggregate link task for each compilation. target.compilations.all { - project.tasks.create(it.binariesTaskName) + project.registerTask(it.binariesTaskName) } project.whenEvaluated { - target.binaries.forEach { - project.tasks.getByName(it.compilation.binariesTaskName).dependsOn(it.linkTaskName) + target.binaries.forEach { binary -> + project.tasks.named(binary.compilation.binariesTaskName).configure { binariesTask -> + binariesTask.dependsOn(binary.linkTaskName) + } } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/NativeBinaries.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/NativeBinaries.kt index 7844e1d2074..e3cd7074268 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/NativeBinaries.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/NativeBinaries.kt @@ -13,6 +13,7 @@ import org.gradle.api.Project import org.gradle.api.artifacts.Dependency import org.gradle.api.provider.Provider import org.gradle.api.tasks.AbstractExecTask +import org.gradle.api.tasks.TaskProvider import org.jetbrains.kotlin.gradle.tasks.KotlinNativeLink import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName import org.jetbrains.kotlin.konan.target.KonanTarget @@ -79,7 +80,10 @@ sealed class NativeBinary( get() = lowerCamelCaseName("link", name, target.targetName) val linkTask: KotlinNativeLink - get() = project.tasks.getByName(linkTaskName) as KotlinNativeLink + get() = linkTaskProvider.get() + + val linkTaskProvider: TaskProvider + get() = project.tasks.withType(KotlinNativeLink::class.java).named(linkTaskName) // Output access. // TODO: Provide output configurations and integrate them with Gradle Native. diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/cocoapods/KotlinCocoapodsPlugin.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/cocoapods/KotlinCocoapodsPlugin.kt index 67a1708ea4b..8a43fcf026f 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/cocoapods/KotlinCocoapodsPlugin.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/cocoapods/KotlinCocoapodsPlugin.kt @@ -9,7 +9,9 @@ package org.jetbrains.kotlin.gradle.plugin.cocoapods import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.api.Task +import org.gradle.api.provider.Provider import org.gradle.api.tasks.Sync +import org.gradle.api.tasks.TaskProvider import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation @@ -20,10 +22,7 @@ import org.jetbrains.kotlin.gradle.targets.native.tasks.PodBuildSettingsProperti import org.jetbrains.kotlin.gradle.targets.native.tasks.PodBuildTask import org.jetbrains.kotlin.gradle.targets.native.tasks.PodInstallTask import org.jetbrains.kotlin.gradle.targets.native.tasks.PodSetupBuildTask -import org.jetbrains.kotlin.gradle.tasks.DefFileTask -import org.jetbrains.kotlin.gradle.tasks.DummyFrameworkTask -import org.jetbrains.kotlin.gradle.tasks.FatFrameworkTask -import org.jetbrains.kotlin.gradle.tasks.PodspecTask +import org.jetbrains.kotlin.gradle.tasks.* import org.jetbrains.kotlin.gradle.utils.asValidTaskName import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName import org.jetbrains.kotlin.konan.target.HostManager @@ -84,9 +83,8 @@ open class KotlinCocoapodsPlugin : Plugin { } } - private fun Project.createSyncFrameworkTask(originalDirectory: File, buildingTask: Task): Sync? { - - return tasks.create(SYNC_TASK_NAME, Sync::class.java) { + private fun Project.createSyncFrameworkTask(originalDirectory: Provider, buildingTask: TaskProvider<*>) = + registerTask(SYNC_TASK_NAME) { it.group = TASK_GROUP it.description = "Copies a framework for given platform and build type into the CocoaPods build directory" @@ -94,7 +92,6 @@ open class KotlinCocoapodsPlugin : Plugin { it.from(originalDirectory) it.destinationDir = cocoapodsBuildDirs.framework } - } private fun createSyncForFatFramework( project: Project, @@ -114,7 +111,7 @@ open class KotlinCocoapodsPlugin : Plugin { } } - val fatFrameworkTask = project.tasks.create("fatFramework", FatFrameworkTask::class.java) { task -> + val fatFrameworkTask = project.registerTask("fatFramework") { task -> task.group = TASK_GROUP task.description = "Creates a fat framework for ARM32 and ARM64 architectures" task.destinationDir = project.cocoapodsBuildDirs.fatFramework(requestedBuildType) @@ -126,7 +123,7 @@ open class KotlinCocoapodsPlugin : Plugin { } } - project.createSyncFrameworkTask(fatFrameworkTask.destinationDir, fatFrameworkTask) + project.createSyncFrameworkTask(fatFrameworkTask.map { it.destinationDir }, fatFrameworkTask) } private fun createSyncForRegularFramework( @@ -140,8 +137,8 @@ open class KotlinCocoapodsPlugin : Plugin { check(targets.isNotEmpty()) { "The project doesn't contain a target for the requested platform: `${requestedPlatform.visibleName}`" } check(targets.size == 1) { "The project has more than one target for the requested platform: `${requestedPlatform.visibleName}`" } - val frameworkLinkTask = targets.single().binaries.getFramework(requestedBuildType).linkTask - project.createSyncFrameworkTask(frameworkLinkTask.destinationDir, frameworkLinkTask) + val frameworkLinkTask = targets.single().binaries.getFramework(requestedBuildType).linkTaskProvider + project.createSyncFrameworkTask(frameworkLinkTask.map { it.destinationDir }, frameworkLinkTask) } private fun createSyncTask( @@ -183,10 +180,8 @@ open class KotlinCocoapodsPlugin : Plugin { } moduleNames.add(pod.moduleName) - val defTask = project.tasks.create( - lowerCamelCaseName("generateDef", pod.moduleName).asValidTaskName(), - DefFileTask::class.java - ) { + val defTask = project.registerTask( + lowerCamelCaseName("generateDef", pod.moduleName).asValidTaskName()) { it.pod = pod it.description = "Generates a def file for CocoaPods dependencies with module ${pod.moduleName}" // This task is an implementation detail so we don't add it in any group @@ -200,7 +195,7 @@ open class KotlinCocoapodsPlugin : Plugin { interopTask.dependsOn(defTask) - interop.defFile = defTask.outputFile + interop.defFile.set(defTask.map { it.outputFile }) interop.packageName = "cocoapods.${pod.moduleName}" diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/performance/KotlinPerformancePlugin.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/performance/KotlinPerformancePlugin.kt index 49aa89d6063..a3be560667b 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/performance/KotlinPerformancePlugin.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/performance/KotlinPerformancePlugin.kt @@ -15,6 +15,7 @@ import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension import org.jetbrains.kotlin.gradle.plugin.addExtension import org.jetbrains.kotlin.gradle.plugin.mpp.disambiguateName import org.jetbrains.kotlin.gradle.targets.native.tasks.NativePerformanceReport +import org.jetbrains.kotlin.gradle.tasks.registerTask import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName import java.io.File import java.util.concurrent.ConcurrentHashMap @@ -68,17 +69,14 @@ open class KotlinPerformancePlugin : Plugin { val timeListener = TaskTimerListener(project) project.gradle.addListener(timeListener) performanceExtension.trackedBinaries.forEach { binary -> - project.tasks.create( - binary.target.disambiguateName(lowerCamelCaseName("perfReport", binary.name)), - NativePerformanceReport::class.java - ) { + val perfReport = project.registerTask(binary.target.disambiguateName(lowerCamelCaseName("perfReport", binary.name))) { it.binary = binary it.settings = performanceExtension it.timeListener = timeListener it.group = TASK_GROUP it.description = "Report performance measurement results for binary '${binary.name}' of target '${binary.target.name}'." - binary.linkTask.finalizedBy(it) } + binary.linkTaskProvider.configure { linkTask -> linkTask.finalizedBy(perfReport) } } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/KotlinNativeTasks.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/KotlinNativeTasks.kt index d14fe70a591..301c0d5d622 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/KotlinNativeTasks.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/KotlinNativeTasks.kt @@ -966,7 +966,7 @@ open class CInteropProcess : DefaultTask() { project.provider { destinationDir.get().resolve(outputFileName) } val defFile: File - @InputFile get() = settings.defFile + @InputFile get() = settings.defFile.get() val packageName: String? @Optional @Input get() = settings.packageName diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/TasksProvider.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/TasksProvider.kt index f84afcb39ec..0b42781daab 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/TasksProvider.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/TasksProvider.kt @@ -19,6 +19,7 @@ package org.jetbrains.kotlin.gradle.tasks import org.gradle.api.Project import org.gradle.api.Task import org.gradle.api.UnknownTaskException +import org.gradle.api.tasks.TaskCollection import org.gradle.api.tasks.TaskProvider import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider import org.jetbrains.kotlin.gradle.plugin.mapKotlinTaskProperties @@ -39,7 +40,7 @@ internal fun registerTask(project: Project, name: String, type: Class internal inline fun Project.registerTask( name: String, args: List = emptyList(), - noinline body: (T) -> (Unit) + noinline body: ((T) -> (Unit))? = null ): TaskProvider = this@registerTask.registerTask(name, T::class.java, args, body) @@ -47,11 +48,18 @@ internal fun Project.registerTask( name: String, type: Class, constructorArgs: List = emptyList(), - body: (T) -> (Unit) + body: ((T) -> (Unit))? = null ): TaskProvider { - return project.tasks.register(name, type, *constructorArgs.toTypedArray()).apply { configure(body) } + val resultProvider = project.tasks.register(name, type, *constructorArgs.toTypedArray()) + if (body != null) { + resultProvider.configure(body) + } + return resultProvider } +internal fun TaskProvider<*>.dependsOn(other: TaskProvider<*>) = configure { it.dependsOn(other) } + +internal inline fun TaskCollection.withType(): TaskCollection = withType(S::class.java) /** * Locates a task by [name] and [type], without triggering its creation or configuration.