Use TCA-compliant Gradle APIs in the Kotlin Gradle plugin

This commit is contained in:
Sergey Igushkin
2020-06-06 00:13:10 +03:00
parent 84287d77ca
commit 58e9b3ae0e
19 changed files with 260 additions and 217 deletions
@@ -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<AbstractArchiveTask>(target.artifactsTaskName)?.configure { jarTask ->
jarToModule[jarTask.archivePathCompatible.canonicalFile] = module
}
} else {
@@ -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<AbstractCompile>().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<Task>(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<Task>(JavaPlugin.CLASSES_TASK_NAME)
val jarTask = project.locateTask<Jar>(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<InspectClassesForMultiModuleIC>("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<out KotlinCompile>,
javaTaskProvider: TaskProvider<out AbstractCompile>
) {
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) {
@@ -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<KotlinTargetType : KotlinTarget>
) : KotlinTargetConfigurator<KotlinTargetType> {
private fun Project.registerOutputsForStaleOutputCleanup(kotlinCompilation: KotlinCompilation<*>) {
val cleanTask = tasks.getByName(LifecycleBasePlugin.CLEAN_TASK_NAME) as Delete
cleanTask.delete(kotlinCompilation.output.allOutputs)
tasks.withType<Delete>().named(LifecycleBasePlugin.CLEAN_TASK_NAME).configure { cleanTask ->
cleanTask.delete(kotlinCompilation.output.allOutputs)
}
}
protected open fun setupCompilationDependencyFiles(compilation: KotlinCompilation<KotlinCommonOptions>) {
@@ -125,10 +130,11 @@ abstract class AbstractKotlinTargetConfigurator<KotlinTargetType : KotlinTarget>
) {
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<ProcessResources>(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<KotlinTargetType : KotlinTarget>
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<DefaultTask>(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<KotlinTargetType : KotlinTarget>
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<KotlinCompilationType : KotlinCompil
}
/** The implementations are expected to create a [Zip] task under the name [KotlinTarget.artifactsTaskName] of the [target]. */
protected open fun createArchiveTasks(target: KotlinTargetType): Zip {
protected open fun createArchiveTasks(target: KotlinTargetType): TaskProvider<out Zip> {
//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<Jar>(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<KotlinCompilationType : KotlinCompil
val task = createArchiveTasks(target)
target.disambiguationClassifier?.let { task.appendix = it.toLowerCase() }
target.disambiguationClassifier?.let { classifier ->
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
@@ -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 ""
}
@@ -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<Jar> =
sourcesJarTask(compilation.target.project, lazy { compilation.allKotlinSourceSets }, componentName, artifactNameAppendix)
internal fun sourcesJarTask(
@@ -346,20 +348,25 @@ internal fun sourcesJarTask(
sourceSets: Lazy<Set<KotlinSourceSet>>,
componentName: String?,
artifactNameAppendix: String
): Jar {
): TaskProvider<Jar> {
val taskName = lowerCamelCaseName(componentName, "sourcesJar")
(project.tasks.findByName(taskName) as? Jar)?.let { return it }
project.tasks.withType<Jar>().run {
if (taskName in names)
return named(taskName)
}
val result = project.tasks.create(taskName, Jar::class.java) { sourcesJar ->
val result = project.registerTask<Jar>(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)
}
}
}
}
@@ -113,7 +113,7 @@ abstract class AbstractKotlinCompilation<T : KotlinCommonOptions>(
// 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()
}
}
@@ -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<out Zip> {
return super.createArchiveTasks(target).apply {
archiveExtension.set(KLIB_TYPE)
configure { it.archiveExtension.set(KLIB_TYPE) }
}
}
@@ -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<AbstractCompile>().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(
@@ -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<KotlinJvmTest>(testTaskName) { testTask ->
testTask.targetName = target.disambiguationClassifier
testTask.project.tasks.findByName(JavaBasePlugin.CHECK_TASK_NAME)?.dependsOn(testTask)
}
target.project.locateTask<Task>(JavaBasePlugin.CHECK_TASK_NAME)?.dependsOn(testTaskOrProvider)
executionTask = testTaskOrProvider
@@ -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<Jar>().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<out KotlinNativeCompile> =
with(nativeTargetConfigurator) {
project.createKlibCompilationTask(kotlinCompilation)
}.thisTaskProvider
}
override fun run() = Unit
}
override fun createArchiveTasks(target: KotlinMetadataTarget): Zip {
override fun createArchiveTasks(target: KotlinMetadataTarget): TaskProvider<out Zip> {
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<out Jar>
) = 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<out Jar>) {
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<out Jar>,
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<KotlinNativeCompilation>().none { it.konanTarget.enabledOnCurrentHost }) {
// Then we don't have any platform module to put this compiled source set to, so disable the compilation task:
@@ -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)
}
}
}
}
@@ -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<File> = project.objects.property(File::class.java)
.apply { set(project.projectDir.resolve("src/nativeInterop/cinterop/$name.def")) }
var packageName: String? = null
val compilerOpts = mutableListOf<String>()
@@ -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) {
@@ -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
@@ -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<T : KotlinNativeTarget>(
private val kotlinPluginVersion: String
@@ -58,9 +57,9 @@ open class KotlinNativeTargetConfigurator<T : KotlinNativeTarget>(
// region Artifact creation.
private fun Project.createKlibArtifact(
compilation: KotlinNativeCompilation,
artifactFile: File,
artifactFile: Provider<File>,
classifier: String?,
producingTask: Task,
producingTask: TaskProvider<*>,
copy: Boolean = false
) {
if (!compilation.konanTarget.enabledOnCurrentHost) {
@@ -69,33 +68,30 @@ open class KotlinNativeTargetConfigurator<T : KotlinNativeTarget>(
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>("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<T : KotlinNativeTarget>(
private fun Project.createRegularKlibArtifact(
compilation: KotlinNativeCompilation,
compileTask: KotlinNativeCompile
) = createKlibArtifact(compilation, compileTask.outputFile.get(), null, compileTask)
compileTask: TaskProvider<out KotlinNativeCompile>
) = 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<out CInteropProcess>
) = 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<KotlinNativeLink>(
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<Exec>(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<KotlinNativeCompile> {
val compileTaskProvider = registerTask<KotlinNativeCompile>(
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<CInteropProcess>(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<T : KotlinNativeTarget>(
}
override fun configureArchivesAndComponent(target: T): Unit = with(target.project) {
tasks.create(target.artifactsTaskName)
registerTask<DefaultTask>(target.artifactsTaskName) { }
target.compilations.all {
createKlibCompilationTask(it)
}
@@ -280,12 +278,14 @@ open class KotlinNativeTargetConfigurator<T : KotlinNativeTarget>(
// Create an aggregate link task for each compilation.
target.compilations.all {
project.tasks.create(it.binariesTaskName)
project.registerTask<DefaultTask>(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)
}
}
}
@@ -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<out KotlinNativeLink>
get() = project.tasks.withType(KotlinNativeLink::class.java).named(linkTaskName)
// Output access.
// TODO: Provide output configurations and integrate them with Gradle Native.
@@ -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<Project> {
}
}
private fun Project.createSyncFrameworkTask(originalDirectory: File, buildingTask: Task): Sync? {
return tasks.create(SYNC_TASK_NAME, Sync::class.java) {
private fun Project.createSyncFrameworkTask(originalDirectory: Provider<File>, buildingTask: TaskProvider<*>) =
registerTask<Sync>(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<Project> {
it.from(originalDirectory)
it.destinationDir = cocoapodsBuildDirs.framework
}
}
private fun createSyncForFatFramework(
project: Project,
@@ -114,7 +111,7 @@ open class KotlinCocoapodsPlugin : Plugin<Project> {
}
}
val fatFrameworkTask = project.tasks.create("fatFramework", FatFrameworkTask::class.java) { task ->
val fatFrameworkTask = project.registerTask<FatFrameworkTask>("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> {
}
}
project.createSyncFrameworkTask(fatFrameworkTask.destinationDir, fatFrameworkTask)
project.createSyncFrameworkTask(fatFrameworkTask.map { it.destinationDir }, fatFrameworkTask)
}
private fun createSyncForRegularFramework(
@@ -140,8 +137,8 @@ open class KotlinCocoapodsPlugin : Plugin<Project> {
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<Project> {
}
moduleNames.add(pod.moduleName)
val defTask = project.tasks.create(
lowerCamelCaseName("generateDef", pod.moduleName).asValidTaskName(),
DefFileTask::class.java
) {
val defTask = project.registerTask<DefFileTask>(
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<Project> {
interopTask.dependsOn(defTask)
interop.defFile = defTask.outputFile
interop.defFile.set(defTask.map { it.outputFile })
interop.packageName = "cocoapods.${pod.moduleName}"
@@ -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<Project> {
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<NativePerformanceReport>(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) }
}
}
@@ -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
@@ -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 <T : Task> registerTask(project: Project, name: String, type: Class
internal inline fun <reified T : Task> Project.registerTask(
name: String,
args: List<Any> = emptyList(),
noinline body: (T) -> (Unit)
noinline body: ((T) -> (Unit))? = null
): TaskProvider<T> =
this@registerTask.registerTask(name, T::class.java, args, body)
@@ -47,11 +48,18 @@ internal fun <T : Task> Project.registerTask(
name: String,
type: Class<T>,
constructorArgs: List<Any> = emptyList(),
body: (T) -> (Unit)
body: ((T) -> (Unit))? = null
): TaskProvider<T> {
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 <reified S : Task> TaskCollection<in S>.withType(): TaskCollection<S> = withType(S::class.java)
/**
* Locates a task by [name] and [type], without triggering its creation or configuration.