From 51234d10b90bd78870149b5dd53f931b57069259 Mon Sep 17 00:00:00 2001 From: Sergey Igushkin Date: Fri, 1 Mar 2019 19:57:30 +0300 Subject: [PATCH] Actual change for splitting files preserving Git history Remove resulting redeclarations and finish the split in files below: - from KotlinTargetConfigurator.kt - to KotlinNativeTaretConfigurator.kt - from mpp\kotlinTargets.kt - to mpp\KotlinAndroidTarget.kt - to mpp\KotlinNativeTarget.kt - to mpp\KotlinWithJavaTarget.kt - from mpp\kotlinTargetPresets.kt - to mpp\KotlinAndroidTargetPreset.kt - to mpp\KotlinNativeTargetPreset.kt - to mpp\KotlinJsTargetPreset.kt - to mpp\KotlinJvmTargetPreset.kt - to mpp\KotlinJvmWithJavaTargetPreset.kt - to mpp\KotlinMetadataTargetPreset.kt - from mpp\kotlinCompilations.kt - to mpp\KotlinCommonCompilation.kt - to mpp\KotlinJvmCompilation.kt - to mpp\KotlinJvmAndroidCompilation.kt - to mpp\KotlinJsCompilation.kt - to mpp\KotlinNativeCompilation.kt - to mpp\KotlinWithJavaCompilation.kt - from mpp\KotlinCompilationFactory.kt - to mpp\KotlinJsCompilationFactory.kt - to mpp\KotlinJvmCompilationFactory.kt - to mpp\KotlinJvmAndroidCompilationFactory.kt - to mpp\KotlinNativeCompilationFactory.kt - to mpp\KotlinWithJavaCompilationFactory.kt - from mpp\kotlinCompilationOutputs.kt - to mpp\KotlinWithJavaCompilationOutput.kt --- .../plugin/KotlinNativeTaretConfigurator.kt | 369 +------------- .../gradle/plugin/KotlinTargetConfigurator.kt | 395 --------------- .../gradle/plugin/mpp/KotlinAndroidTarget.kt | 240 +-------- .../plugin/mpp/KotlinAndroidTargetPreset.kt | 302 +----------- .../plugin/mpp/KotlinCommonCompilation.kt | 452 +---------------- .../plugin/mpp/KotlinCompilationFactory.kt | 69 --- .../gradle/plugin/mpp/KotlinJsCompilation.kt | 457 +----------------- .../plugin/mpp/KotlinJsCompilationFactory.kt | 73 --- .../gradle/plugin/mpp/KotlinJsTargetPreset.kt | 293 +---------- .../plugin/mpp/KotlinJvmAndroidCompilation.kt | 454 +---------------- .../mpp/KotlinJvmAndroidCompilationFactory.kt | 72 --- .../gradle/plugin/mpp/KotlinJvmCompilation.kt | 456 +---------------- .../plugin/mpp/KotlinJvmCompilationFactory.kt | 76 --- .../plugin/mpp/KotlinJvmTargetPreset.kt | 293 +---------- .../mpp/KotlinJvmWithJavaTargetPreset.kt | 277 ----------- .../plugin/mpp/KotlinMetadataTargetPreset.kt | 267 ---------- .../plugin/mpp/KotlinNativeCompilation.kt | 318 +----------- .../mpp/KotlinNativeCompilationFactory.kt | 64 --- .../gradle/plugin/mpp/KotlinNativeTarget.kt | 378 +-------------- .../plugin/mpp/KotlinNativeTargetPreset.kt | 206 -------- .../plugin/mpp/KotlinWithJavaCompilation.kt | 415 +--------------- .../mpp/KotlinWithJavaCompilationFactory.kt | 66 --- .../mpp/KotlinWithJavaCompilationOutput.kt | 19 - .../gradle/plugin/mpp/KotlinWithJavaTarget.kt | 403 +-------------- .../plugin/mpp/kotlinCompilationOutputs.kt | 27 +- .../gradle/plugin/mpp/kotlinCompilations.kt | 249 ---------- .../gradle/plugin/mpp/kotlinTargetPresets.kt | 284 +---------- .../kotlin/gradle/plugin/mpp/kotlinTargets.kt | 274 +---------- 28 files changed, 50 insertions(+), 7198 deletions(-) diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinNativeTaretConfigurator.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinNativeTaretConfigurator.kt index eb37b6e9abb..7f0836b4c00 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinNativeTaretConfigurator.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinNativeTaretConfigurator.kt @@ -7,27 +7,17 @@ package org.jetbrains.kotlin.gradle.plugin import org.gradle.api.Project import org.gradle.api.Task -import org.gradle.api.artifacts.* -import org.gradle.api.artifacts.type.ArtifactTypeDefinition -import org.gradle.api.attributes.Usage +import org.gradle.api.artifacts.ConfigurationContainer +import org.gradle.api.artifacts.Dependency import org.gradle.api.attributes.Usage.USAGE_ATTRIBUTE -import org.gradle.api.file.FileCollection 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.internal.plugins.DslObject import org.gradle.api.plugins.BasePlugin -import org.gradle.api.plugins.JavaBasePlugin import org.gradle.api.tasks.Copy -import org.gradle.api.tasks.Delete import org.gradle.api.tasks.Exec -import org.gradle.api.tasks.bundling.Jar -import org.gradle.api.tasks.testing.Test import org.gradle.language.base.plugins.LifecycleBasePlugin -import org.gradle.language.jvm.tasks.ProcessResources -import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments import org.jetbrains.kotlin.gradle.dsl.KotlinNativeBinaryContainer -import org.jetbrains.kotlin.gradle.dsl.kotlinExtension import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation.Companion.MAIN_COMPILATION_NAME import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation.Companion.TEST_COMPILATION_NAME import org.jetbrains.kotlin.gradle.plugin.mpp.* @@ -35,351 +25,8 @@ import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinNativeCompile import org.jetbrains.kotlin.gradle.tasks.CInteropProcess import org.jetbrains.kotlin.gradle.tasks.KotlinNativeCompile import org.jetbrains.kotlin.gradle.tasks.KotlinNativeLink -import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName import java.io.File import java.util.* -import java.util.concurrent.Callable - -abstract class AbstractKotlinTargetConfigurator( - protected val createDefaultSourceSets: Boolean, - protected val createTestCompilation: Boolean -) { - open fun configureTarget( - target: KotlinTargetType - ) { - configureCompilationDefaults(target) - configureCompilations(target) - defineConfigurationsForTarget(target) - configureArchivesAndComponent(target) - configureTest(target) - configureBuild(target) - } - - - abstract protected fun configureArchivesAndComponent(target: KotlinTargetType) - abstract protected fun configureTest(target: KotlinTargetType) - - private fun Project.registerOutputsForStaleOutputCleanup(kotlinCompilation: KotlinCompilation<*>) { - val cleanTask = tasks.getByName(LifecycleBasePlugin.CLEAN_TASK_NAME) as Delete - cleanTask.delete(kotlinCompilation.output.allOutputs) - } - - protected fun configureCompilations(platformTarget: KotlinTargetType) { - val project = platformTarget.project - val main = platformTarget.compilations.create(KotlinCompilation.MAIN_COMPILATION_NAME) - - platformTarget.compilations.all { - project.registerOutputsForStaleOutputCleanup(it) - it.compileDependencyFiles = project.configurations.maybeCreate(it.compileDependencyConfigurationName) - if (it is KotlinCompilationToRunnableFiles) { - it.runtimeDependencyFiles = project.configurations.maybeCreate(it.runtimeDependencyConfigurationName) - } - } - - if (createTestCompilation) { - platformTarget.compilations.create(KotlinCompilation.TEST_COMPILATION_NAME).apply { - compileDependencyFiles = project.files( - main.output.allOutputs, - project.configurations.maybeCreate(compileDependencyConfigurationName) - ) - - if (this is KotlinCompilationToRunnableFiles) { - runtimeDependencyFiles = project.files( - output.allOutputs, - main.output.allOutputs, - project.configurations.maybeCreate(runtimeDependencyConfigurationName) - ) - } - } - } - } - - protected fun configureCompilationDefaults(target: KotlinTargetType) { - val project = target.project - - target.compilations.all { compilation -> - defineConfigurationsForCompilation(compilation) - - if (createDefaultSourceSets) { - project.kotlinExtension.sourceSets.maybeCreate(compilation.defaultSourceSetName).also { sourceSet -> - compilation.source(sourceSet) // also adds dependencies, requires the configurations for target and source set to exist at this point - } - } - - if (compilation is KotlinCompilationWithResources) { - configureResourceProcessing(compilation, project.files(Callable { compilation.allKotlinSourceSets.map { it.resources } })) - } - - createLifecycleTask(compilation) - } - } - - protected fun configureResourceProcessing( - compilation: KotlinCompilationWithResources<*>, - resourceSet: FileCollection - ) { - 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) - } - - protected fun createLifecycleTask(compilation: KotlinCompilation<*>) { - val project = compilation.target.project - - 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) - if (compilation is KotlinCompilationWithResources) { - dependsOn(compilation.processResourcesTaskName) - } - } - } - - protected open fun defineConfigurationsForTarget(target: KotlinTargetType) { - val project = target.project - - val configurations = project.configurations - - val defaultConfiguration = configurations.maybeCreate(target.defaultConfigurationName).apply { - setupAsLocalTargetSpecificConfigurationIfSupported(target) - } - - val mainCompilation = target.compilations.maybeCreate(KotlinCompilation.MAIN_COMPILATION_NAME) - - val compileConfiguration = configurations.maybeCreate(mainCompilation.deprecatedCompileConfigurationName) - val implementationConfiguration = configurations.maybeCreate(mainCompilation.implementationConfigurationName) - - val runtimeOnlyConfiguration = configurations.maybeCreate(mainCompilation.runtimeOnlyConfigurationName) - - val apiElementsConfiguration = configurations.maybeCreate(target.apiElementsConfigurationName).apply { - description = "API elements for main." - isVisible = false - isCanBeResolved = false - isCanBeConsumed = true - attributes.attribute(USAGE_ATTRIBUTE, KotlinUsages.producerApiUsage(target)) - extendsFrom(configurations.maybeCreate(mainCompilation.apiConfigurationName)) - if (mainCompilation is KotlinCompilationToRunnableFiles) { - val runtimeConfiguration = configurations.maybeCreate(mainCompilation.deprecatedRuntimeConfigurationName) - extendsFrom(runtimeConfiguration) - } - usesPlatformOf(target) - setupAsPublicConfigurationIfSupported(target) - } - - if (mainCompilation is KotlinCompilationToRunnableFiles<*>) { - val runtimeElementsConfiguration = configurations.maybeCreate(target.runtimeElementsConfigurationName).apply { - description = "Elements of runtime for main." - isVisible = false - isCanBeConsumed = true - isCanBeResolved = false - attributes.attribute(USAGE_ATTRIBUTE, KotlinUsages.producerRuntimeUsage(target)) - val runtimeConfiguration = configurations.maybeCreate(mainCompilation.deprecatedRuntimeConfigurationName) - extendsFrom(implementationConfiguration, runtimeOnlyConfiguration, runtimeConfiguration) - usesPlatformOf(target) - setupAsPublicConfigurationIfSupported(target) - } - defaultConfiguration.extendsFrom(runtimeElementsConfiguration) - } else { - defaultConfiguration.extendsFrom(apiElementsConfiguration) - } - - if (createTestCompilation) { - val testCompilation = target.compilations.getByName(KotlinCompilation.TEST_COMPILATION_NAME) - val compileTestsConfiguration = configurations.maybeCreate(testCompilation.deprecatedCompileConfigurationName) - val testImplementationConfiguration = configurations.maybeCreate(testCompilation.implementationConfigurationName) - val testRuntimeOnlyConfiguration = configurations.maybeCreate(testCompilation.runtimeOnlyConfigurationName) - - compileTestsConfiguration.extendsFrom(compileConfiguration) - testImplementationConfiguration.extendsFrom(implementationConfiguration) - testRuntimeOnlyConfiguration.extendsFrom(runtimeOnlyConfiguration) - - if (mainCompilation is KotlinCompilationToRunnableFiles && testCompilation is KotlinCompilationToRunnableFiles) { - val runtimeConfiguration = configurations.maybeCreate(mainCompilation.deprecatedRuntimeConfigurationName) - val testRuntimeConfiguration = configurations.maybeCreate(testCompilation.deprecatedRuntimeConfigurationName) - testRuntimeConfiguration.extendsFrom(runtimeConfiguration) - } - } - } - - protected 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) - - 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) - } - } - } - - private fun addDependsOnTaskInOtherProjects(task: Task, useDependedOn: Boolean, configurationName: String) { - val project = task.project - val configuration = project.configurations.getByName(configurationName) - task.dependsOn(configuration.getTaskDependencyFromProjectDependency(useDependedOn, task.name)) - } - - companion object { - const val testTaskNameSuffix = "test" - - fun defineConfigurationsForCompilation( - compilation: KotlinCompilation<*> - ) { - val target = compilation.target - val configurations = target.project.configurations - - val compileConfiguration = configurations.maybeCreate(compilation.deprecatedCompileConfigurationName).apply { - setupAsLocalTargetSpecificConfigurationIfSupported(target) - isVisible = false - isCanBeResolved = true // Needed for IDE import - description = "Dependencies for $compilation (deprecated, use '${compilation.implementationConfigurationName} ' instead)." - } - - val apiConfiguration = configurations.maybeCreate(compilation.apiConfigurationName).apply { - extendsFrom(compileConfiguration) - isVisible = false - isCanBeConsumed = false - isCanBeResolved = false - description = "API dependencies for $compilation." - } - - val implementationConfiguration = configurations.maybeCreate(compilation.implementationConfigurationName).apply { - extendsFrom(compileConfiguration, apiConfiguration) - isVisible = false - isCanBeConsumed = false - isCanBeResolved = false - description = "Implementation only dependencies for $compilation." - } - - val compileOnlyConfiguration = configurations.maybeCreate(compilation.compileOnlyConfigurationName).apply { - setupAsLocalTargetSpecificConfigurationIfSupported(target) - isVisible = false - isCanBeResolved = true // Needed for IDE import - description = "Compile only dependencies for $compilation." - } - - val compileClasspathConfiguration = configurations.maybeCreate(compilation.compileDependencyConfigurationName).apply { - extendsFrom(compileOnlyConfiguration, implementationConfiguration) - usesPlatformOf(target) - isVisible = false - isCanBeConsumed = false - attributes.attribute(USAGE_ATTRIBUTE, KotlinUsages.consumerApiUsage(compilation.target)) - description = "Compile classpath for $compilation." - } - - if (compilation is KotlinCompilationToRunnableFiles) { - val runtimeConfiguration = configurations.maybeCreate(compilation.deprecatedRuntimeConfigurationName).apply { - setupAsLocalTargetSpecificConfigurationIfSupported(target) - extendsFrom(compileConfiguration) - isVisible = false - isCanBeResolved = true // Needed for IDE import - description = - "Runtime dependencies for $compilation (deprecated, use '${compilation.runtimeOnlyConfigurationName} ' instead)." - } - - val runtimeOnlyConfiguration = configurations.maybeCreate(compilation.runtimeOnlyConfigurationName).apply { - isVisible = false - isCanBeConsumed = false - isCanBeResolved = false - description = "Runtime only dependencies for $compilation." - } - - val runtimeClasspathConfiguration = configurations.maybeCreate(compilation.runtimeDependencyConfigurationName).apply { - extendsFrom(runtimeOnlyConfiguration, runtimeConfiguration, implementationConfiguration) - usesPlatformOf(target) - isVisible = false - isCanBeConsumed = false - isCanBeResolved = true - attributes.attribute(USAGE_ATTRIBUTE, KotlinUsages.consumerRuntimeUsage(compilation.target)) - description = "Runtime classpath of $compilation." - } - } - } - } -} - -internal val KotlinCompilation<*>.deprecatedCompileConfigurationName: String - get() = disambiguateName("compile") - -internal val KotlinCompilationToRunnableFiles<*>.deprecatedRuntimeConfigurationName: String - get() = disambiguateName("runtime") - -open class KotlinTargetConfigurator>( - createDefaultSourceSets: Boolean, - createTestCompilation: Boolean -) : AbstractKotlinTargetConfigurator>( - createDefaultSourceSets, - createTestCompilation -) { - - override fun configureArchivesAndComponent(target: KotlinOnlyTarget) { - val project = target.project - - val mainCompilation = target.compilations.getByName(KotlinCompilation.MAIN_COMPILATION_NAME) - - val jar = project.tasks.create(target.artifactsTaskName, Jar::class.java) - jar.description = "Assembles a jar archive containing the main classes." - jar.group = BasePlugin.BUILD_GROUP - jar.from(mainCompilation.output.allOutputs) - - val apiElementsConfiguration = project.configurations.getByName(target.apiElementsConfigurationName) - - target.disambiguationClassifier?.let { jar.appendix = it.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 - project.afterEvaluate { - project.artifacts.add(Dependency.ARCHIVES_CONFIGURATION, jar) { jarArtifact -> - jarArtifact.builtBy(jar) - jarArtifact.type = ArtifactTypeDefinition.JAR_TYPE - - addJar(apiElementsConfiguration, jarArtifact) - - if (mainCompilation is KotlinCompilationToRunnableFiles<*>) { - val runtimeConfiguration = project.configurations.getByName(mainCompilation.deprecatedRuntimeConfigurationName) - val runtimeElementsConfiguration = project.configurations.getByName(target.runtimeElementsConfigurationName) - addJar(runtimeConfiguration, jarArtifact) - addJar(runtimeElementsConfiguration, jarArtifact) - // TODO Check Gradle's special split into variants for classes & resources -- do we need that too? - } - } - } - } - - override fun configureTest(target: KotlinOnlyTarget) { - val testCompilation = target.compilations.findByName(KotlinCompilation.TEST_COMPILATION_NAME) as? KotlinCompilationToRunnableFiles<*> - ?: return // Otherwise, there is no runtime classpath - - target.project.tasks.create(lowerCamelCaseName(target.targetName, testTaskNameSuffix), Test::class.java).apply { - project.afterEvaluate { - // use afterEvaluate to override the JavaPlugin defaults for Test tasks - conventionMapping.map("testClassesDirs") { testCompilation.output.classesDirs } - conventionMapping.map("classpath") { testCompilation.runtimeDependencyFiles } - description = "Runs the unit tests." - group = JavaBasePlugin.VERIFICATION_GROUP - target.project.tasks.findByName(JavaBasePlugin.CHECK_TASK_NAME)?.dependsOn(this@apply) - } - } - } - - private fun addJar(configuration: Configuration, jarArtifact: PublishArtifact) { - val publications = configuration.outgoing - - // Configure an implicit variant - publications.artifacts.add(jarArtifact) - publications.attributes.attribute(ArtifactAttributes.ARTIFACT_FORMAT, ArtifactTypeDefinition.JAR_TYPE) - } -} - open class KotlinNativeTargetConfigurator( private val kotlinPluginVersion: String @@ -774,15 +421,3 @@ open class KotlinNativeTargetConfigurator( } } } - -internal fun Project.usageByName(usageName: String): Usage = - project.objects.named(Usage::class.java, usageName) - -fun Configuration.usesPlatformOf(target: KotlinTarget): Configuration { - attributes.attribute(KotlinPlatformType.attribute, target.platformType) - // TODO: Provide an universal way to copy attributes from the target. - if (target is KotlinNativeTarget) { - attributes.attribute(KotlinNativeTarget.konanTargetAttribute, target.konanTarget.name) - } - return this -} \ No newline at end of file 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 eb37b6e9abb..1c0ba8e4efc 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 @@ -380,401 +380,6 @@ open class KotlinTargetConfigurator } } - -open class KotlinNativeTargetConfigurator( - private val kotlinPluginVersion: String -) : AbstractKotlinTargetConfigurator( - createDefaultSourceSets = true, - createTestCompilation = true -) { - private fun Project.klibOutputDirectory( - compilation: KotlinNativeCompilation - ): File { - val targetSubDirectory = compilation.target.disambiguationClassifier?.let { "$it/" }.orEmpty() - return buildDir.resolve("classes/kotlin/$targetSubDirectory${compilation.name}") - } - - private fun AbstractKotlinNativeCompile.addCompilerPlugins() { - SubpluginEnvironment - .loadSubplugins(project, kotlinPluginVersion) - .addSubpluginOptions(project, this, compilerPluginOptions) - compilerPluginClasspath = project.configurations.getByName(NATIVE_COMPILER_PLUGIN_CLASSPATH_CONFIGURATION_NAME) - } - - // region Artifact creation. - private fun Project.createKlibArtifact( - compilation: KotlinNativeCompilation, - artifactFile: File, - classifier: String?, - producingTask: Task, - copy: Boolean = false - ) { - if (!compilation.target.konanTarget.enabledOnCurrentHost) { - return - } - - val apiElements = configurations.getByName(compilation.target.apiElementsConfigurationName) - - val realProducingTask: Task - // TODO: Someone remove this HACK PLEASE! - val realArtifactFile = if (copy) { - realProducingTask = project.tasks.create("copy${producingTask.name.capitalize()}", Copy::class.java) { - 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) - } 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) { - artifacts.add(klibArtifact) - attributes.attribute(ArtifactAttributes.ARTIFACT_FORMAT, NativeArtifactFormat.KLIB) - } - } - - private fun Project.createRegularKlibArtifact( - compilation: KotlinNativeCompilation, - compileTask: KotlinNativeCompile - ) = createKlibArtifact(compilation, compileTask.outputFile.get(), null, compileTask) - - private fun Project.createCInteropKlibArtifact( - interop: DefaultCInteropSettings, - interopTask: CInteropProcess - ) = createKlibArtifact(interop.compilation, interopTask.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 target = binary.target - this.binary = binary - group = BasePlugin.BUILD_GROUP - description = "Links ${binary.outputKind.description} '${binary.name}' for a target '${target.name}'." - enabled = target.konanTarget.enabledOnCurrentHost - destinationDir = binary.outputDirectory - addCompilerPlugins() - - tasks.maybeCreate(target.artifactsTaskName).dependsOn(this) - tasks.maybeCreate(LifecycleBasePlugin.ASSEMBLE_TASK_NAME).dependsOn(this) - } - } - - private fun Project.createRunTask(binary: Executable) { - val taskName = binary.runTaskName ?: return - // TODO provide a special exec task for tests. - tasks.create(taskName, Exec::class.java).apply { - if (binary.isDefaultTestExecutable) { - group = LifecycleBasePlugin.VERIFICATION_GROUP - description = "Executes Kotlin/Native unit tests for target ${binary.target.name}." - tasks.maybeCreate(LifecycleBasePlugin.CHECK_TASK_NAME).dependsOn(this) - if (project.hasProperty("teamcity.version")) { - args("--ktest_logger=TEAMCITY") - } - } else { - group = RUN_GROUP - description = "Executes Kotlin/Native executable ${binary.name} for target ${binary.target.name}" - } - - enabled = binary.target.konanTarget.isCurrentHost - - executable = binary.outputFile.absolutePath - workingDir = project.projectDir - - onlyIf { binary.outputFile.exists() } - dependsOn(binary.linkTaskName) - } - } - - private fun Project.createKlibCompilationTask(compilation: KotlinNativeCompilation) { - val compileTask = tasks.create( - compilation.compileKotlinTaskName, - KotlinNativeCompile::class.java - ).apply { - this.compilation = compilation - group = BasePlugin.BUILD_GROUP - description = "Compiles a klibrary from the '${compilation.name}' " + - "compilation for target '${compilation.platformType.name}'." - enabled = compilation.target.konanTarget.enabledOnCurrentHost - - destinationDir = klibOutputDirectory(compilation) - addCompilerPlugins() - compilation.output.addClassesDir { - project.files(this.outputFile).builtBy(this) - } - } - - project.tasks.getByName(compilation.compileAllTaskName).dependsOn(compileTask) - - if (compilation.compilationName == KotlinCompilation.MAIN_COMPILATION_NAME) { - project.tasks.getByName(compilation.target.artifactsTaskName).apply { - dependsOn(compileTask) - } - project.tasks.getByName(LifecycleBasePlugin.ASSEMBLE_TASK_NAME).apply { - dependsOn(compileTask) - } - createRegularKlibArtifact(compilation, compileTask) - } - } - - 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}' " + - "for compilation '${compilation.name}'" + - "of target '${konanTarget.name}'." - enabled = compilation.target.konanTarget.enabledOnCurrentHost - - val interopOutput = project.files(outputFileProvider).builtBy(this) - with(compilation) { - project.dependencies.add(compileDependencyConfigurationName, interopOutput) - if (isMainCompilation) { - target.compilations.findByName(TEST_COMPILATION_NAME)?.let { - project.dependencies.add(it.compileDependencyConfigurationName, interopOutput) - } - } - project.dependencies.add(target.apiElementsConfigurationName, interopOutput) - } - } - createCInteropKlibArtifact(interop, interopTask) - } - } - // endregion. - - // region Configuration. - override fun configureTarget(target: KotlinNativeTarget) { - super.configureTarget(target) - configureBinaries(target) - configureFrameworkExport(target) - configureCInterops(target) - warnAboutIncorrectDependencies(target) - } - - override fun configureArchivesAndComponent(target: KotlinNativeTarget): Unit = with(target.project) { - tasks.create(target.artifactsTaskName) - target.compilations.all { - createKlibCompilationTask(it) - } - - with(configurations.getByName(target.apiElementsConfigurationName)) { - outgoing.attributes.attribute(ArtifactAttributes.ARTIFACT_FORMAT, NativeArtifactFormat.KLIB) - } - } - - override fun configureTest(target: KotlinNativeTarget) { - target.binaries.defaultTestExecutable { - compilation = target.compilations.maybeCreate(KotlinCompilation.TEST_COMPILATION_NAME) - // Allow accessing the test binary using the old getters (e.g. compilations.test.getBinary('EXECUTABLE', 'DEBUG')) - compilation.binaries[NativeOutputKind.EXECUTABLE to KotlinNativeBinaryContainer.DEFAULT_TEST_BUILD_TYPE] = this - } - } - - protected fun configureCInterops(target: KotlinNativeTarget): Unit = with(target.project) { - target.compilations.all { compilation -> - createCInteropTasks(compilation) - compilation.cinterops.all { - defineConfigurationsForCInterop(compilation, it, target, configurations) - } - } - - if (createTestCompilation) { - val mainCompilation = target.compilations.getByName(MAIN_COMPILATION_NAME) - target.compilations.findByName(TEST_COMPILATION_NAME)?.apply { - cinterops.all { - it.dependencyFiles += mainCompilation.output.allOutputs - } - } - } - } - - protected fun configureBinaries(target: KotlinNativeTarget) { - val project = target.project - // Create link and run tasks. - target.binaries.all { - project.createLinkTask(it) - } - - target.binaries.withType(Executable::class.java).all { - project.createRunTask(it) - } - - target.binaries.prefixGroups.all { prefixGroup -> - val linkGroupTask = project.tasks.maybeCreate(prefixGroup.linkTaskName) - prefixGroup.binaries.all { - linkGroupTask.dependsOn(it.linkTaskName) - } - } - - // Create an aggregate link task for each compilation. - target.compilations.all { - project.tasks.create(it.binariesTaskName) - } - - project.whenEvaluated { - target.binaries.forEach { - project.tasks.getByName(it.compilation.binariesTaskName).dependsOn(it.linkTaskName) - } - } - - // Create binaries for output kinds declared using the old DSL. - project.whenEvaluated { - target.compilations.all { compilation -> - val binaries = target.binaries - val konanTarget = compilation.target.konanTarget - val name = compilation.name - val buildTypes = compilation.buildTypes - val availableOutputKinds = compilation.outputKinds.filter { it.availableFor(konanTarget) } - - val configure: NativeBinary.() -> Unit = { - this.compilation = compilation - linkerOpts.addAll(compilation.linkerOpts) - if (this is Executable) { - entryPoint = compilation.entryPoint - } - compilation.binaries[outputKind to buildType] = this - } - - for (kind in availableOutputKinds) { - when (kind) { - NativeOutputKind.EXECUTABLE -> binaries.executable(name, buildTypes, configure) - NativeOutputKind.DYNAMIC -> binaries.sharedLib(name, buildTypes, configure) - NativeOutputKind.STATIC -> binaries.staticLib(name, buildTypes, configure) - NativeOutputKind.FRAMEWORK -> binaries.framework(name, buildTypes, configure) - } - } - } - // Allow setting linker options for the default test executable using the - // corresponding properties of the test compilation. - target.binaries.getDefaultTestExecutable().apply { - linkerOpts.addAll(target.compilations.getByName(TEST_COMPILATION_NAME).linkerOpts) - } - } - } - - fun configureFrameworkExport(target: KotlinNativeTarget) { - val project = target.project - - target.compilations.all { - // Allow resolving api configurations directly to be able to check that - // all exported dependency are also added in the corresponding api configurations. - // The check is performed during a link task execution. - project.configurations.maybeCreate(it.apiConfigurationName).apply { - isCanBeResolved = true - usesPlatformOf(target) - attributes.attribute(USAGE_ATTRIBUTE, KotlinUsages.consumerApiUsage(target)) - } - } - - target.binaries.withType(Framework::class.java).all { framework -> - val exportConfiguration = project.configurations.maybeCreate(framework.exportConfigurationName).apply { - isVisible = false - isTransitive = false - isCanBeConsumed = false - isCanBeResolved = true - usesPlatformOf(target) - attributes.attribute(USAGE_ATTRIBUTE, KotlinUsages.consumerApiUsage(target)) - description = "Dependenceis to be exported in framework ${framework.name} for target ${target.targetName}" - } - } - } - - override fun defineConfigurationsForTarget(target: KotlinNativeTarget) { - super.defineConfigurationsForTarget(target) - val configurations = target.project.configurations - - // The configuration and the main compilation are created by the base class. - val mainCompilation = target.compilations.getByName(MAIN_COMPILATION_NAME) - configurations.getByName(target.apiElementsConfigurationName).apply { - // K/N compiler doesn't divide libraries into implementation and api ones. So we need to add implementation - // dependencies into the outgoing configuration. - extendsFrom(configurations.getByName(mainCompilation.implementationConfigurationName)) - } - } - - private fun warnAboutIncorrectDependencies(target: KotlinNativeTarget) = target.project.whenEvaluated { - - val compileOnlyDependencies = target.compilations.mapNotNull { - val dependencies = configurations.getByName(it.compileOnlyConfigurationName).allDependencies - if (dependencies.isNotEmpty()) { - it to dependencies - } else null - } - - fun Dependency.stringCoordinates(): String = buildString { - group?.let { append(it).append(':') } - append(name) - version?.let { append(':').append(it) } - } - - if (compileOnlyDependencies.isNotEmpty()) { - with(target.project.logger) { - warn("A compileOnly dependency is used in the Kotlin/Native target '${target.name}':") - compileOnlyDependencies.forEach { - warn( - """ - Compilation: ${it.first.name} - - Dependencies: - ${it.second.joinToString(separator = "\n") { it.stringCoordinates() }} - - """.trimIndent() - ) - } - warn("Such dependencies are not applicable for Kotlin/Native, consider changing the dependency type to 'implementation' or 'api'.") - } - } - } - // endregion. - - object NativeArtifactFormat { - const val KLIB = "org.jetbrains.kotlin.klib" - } - - companion object { - const val INTEROP_GROUP = "interop" - const val RUN_GROUP = "run" - - protected fun defineConfigurationsForCInterop( - compilation: KotlinNativeCompilation, - cinterop: CInteropSettings, - target: KotlinTarget, - configurations: ConfigurationContainer - ) { - val compileOnlyConfiguration = configurations.getByName(compilation.compileOnlyConfigurationName) - val implementationConfiguration = configurations.getByName(compilation.implementationConfigurationName) - - cinterop.dependencyFiles = configurations.maybeCreate(cinterop.dependencyConfigurationName).apply { - extendsFrom(compileOnlyConfiguration, implementationConfiguration) - usesPlatformOf(target) - isVisible = false - isCanBeConsumed = false - attributes.attribute(USAGE_ATTRIBUTE, KotlinUsages.consumerApiUsage(target)) - description = "Dependencies for cinterop '${cinterop.name}' (compilation '${compilation.name}')." - } - } - } -} - internal fun Project.usageByName(usageName: String): Usage = project.objects.named(Usage::class.java, usageName) diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinAndroidTarget.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinAndroidTarget.kt index f4bbb5d60f9..1345b130446 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinAndroidTarget.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinAndroidTarget.kt @@ -4,158 +4,15 @@ */ package org.jetbrains.kotlin.gradle.plugin.mpp -import groovy.lang.Closure -import org.gradle.api.* -import org.gradle.api.artifacts.ConfigurablePublishArtifact -import org.gradle.api.artifacts.Dependency -import org.gradle.api.artifacts.PublishArtifact -import org.gradle.api.attributes.Attribute -import org.gradle.api.attributes.AttributeContainer +import org.gradle.api.InvalidUserDataException +import org.gradle.api.NamedDomainObjectContainer +import org.gradle.api.Project import org.gradle.api.attributes.Usage.JAVA_API import org.gradle.api.attributes.Usage.JAVA_RUNTIME_JARS -import org.gradle.api.plugins.JavaPlugin -import org.gradle.api.publish.maven.MavenPublication -import org.gradle.util.ConfigureUtil -import org.gradle.util.WrapUtil -import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions -import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension -import org.jetbrains.kotlin.gradle.dsl.KotlinNativeBinaryContainer -import org.jetbrains.kotlin.gradle.dsl.kotlinExtension import org.jetbrains.kotlin.gradle.plugin.* import org.jetbrains.kotlin.gradle.utils.dashSeparatedName import org.jetbrains.kotlin.gradle.utils.isGradleVersionAtLeast import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName -import org.jetbrains.kotlin.konan.target.KonanTarget - -abstract class AbstractKotlinTarget( - final override val project: Project -) : KotlinTarget { - private val attributeContainer = HierarchyAttributeContainer(parent = null) - - override fun getAttributes(): AttributeContainer = attributeContainer - - override val defaultConfigurationName: String - get() = disambiguateName("default") - - override val apiElementsConfigurationName: String - get() = disambiguateName("apiElements") - - override val runtimeElementsConfigurationName: String - get() = disambiguateName("runtimeElements") - - override val artifactsTaskName: String - get() = disambiguateName("jar") - - override fun toString(): String = "target $name ($platformType)" - - override val publishable: Boolean - get() = true - - override val components: Set by lazy { - val mainCompilation = compilations.getByName(KotlinCompilation.MAIN_COMPILATION_NAME) - val usageContexts = createUsageContexts(mainCompilation) - setOf( - if (isGradleVersionAtLeast(4, 7)) { - val componentName = mainCompilation.target.name - createKotlinVariant(componentName, mainCompilation, usageContexts).apply { - sourcesArtifacts = setOf( - sourcesJarArtifact( - mainCompilation, componentName, - dashSeparatedName(target.name.toLowerCase(), componentName.toLowerCase()) - ) - ) - } - } else { - KotlinVariant(mainCompilation, usageContexts) - } - ).also { project.components.addAll(it) } - } - - protected fun createKotlinVariant( - componentName: String, - compilation: KotlinCompilation<*>, - usageContexts: Set - ): KotlinVariant { - - val kotlinExtension = project.kotlinExtension as? KotlinMultiplatformExtension - ?: return KotlinVariantWithCoordinates(compilation, usageContexts) - - if (targetName == KotlinMultiplatformPlugin.METADATA_TARGET_NAME) - return KotlinVariantWithCoordinates(compilation, usageContexts) - - val separateMetadataTarget = kotlinExtension.targets.getByName(KotlinMultiplatformPlugin.METADATA_TARGET_NAME) - - val result = if (kotlinExtension.isGradleMetadataAvailable) { - KotlinVariantWithMetadataVariant(compilation, usageContexts, separateMetadataTarget) - } else { - // we should only add the Kotlin metadata dependency if we publish no Gradle metadata related to Kotlin MPP; - // with metadata, such a dependency would get invalid, since a platform module should only depend on modules for that - // same platform, not Kotlin metadata modules - KotlinVariantWithMetadataDependency(compilation, usageContexts, separateMetadataTarget) - } - - result.componentName = componentName - return result - } - - private fun createUsageContexts( - producingCompilation: KotlinCompilation<*> - ): Set { - // Here, `JAVA_API` and `JAVA_RUNTIME_JARS` are used intentionally as Gradle needs this for - // ordering of the usage contexts (prioritizing the dependencies) when merging them into the POM; - // These Java usages should not be replaced with the custom Kotlin usages. - return listOfNotNull( - JAVA_API to apiElementsConfigurationName, - (JAVA_RUNTIME_JARS to runtimeElementsConfigurationName).takeIf { producingCompilation is KotlinCompilationToRunnableFiles } - ).mapTo(mutableSetOf()) { (usageName, dependenciesConfigurationName) -> - DefaultKotlinUsageContext( - producingCompilation, - project.usageByName(usageName), - dependenciesConfigurationName - ) - } - } - - protected fun sourcesJarArtifact( - producingCompilation: KotlinCompilation<*>, - componentName: String, - artifactNameAppendix: String, - classifierPrefix: String? = null - ): PublishArtifact { - val sourcesJarTask = sourcesJarTask(producingCompilation, componentName, artifactNameAppendix) - val sourceArtifactConfigurationName = producingCompilation.disambiguateName("sourceArtifacts") - return producingCompilation.target.project.run { - (configurations.findByName(sourceArtifactConfigurationName) ?: run { - val configuration = configurations.create(sourceArtifactConfigurationName) { - it.isCanBeResolved = false - it.isCanBeConsumed = false - } - artifacts.add(sourceArtifactConfigurationName, sourcesJarTask) - configuration - }).artifacts.single().apply { - this as ConfigurablePublishArtifact - classifier = dashSeparatedName(classifierPrefix, "sources") - } - } - } - - @Suppress("UNCHECKED_CAST") - internal val publicationConfigureActions = - WrapUtil.toDomainObjectSet(Action::class.java) as DomainObjectSet> - - override fun mavenPublication(action: Action) { - publicationConfigureActions.add(action) - } - - override fun mavenPublication(action: Closure) = - mavenPublication(ConfigureUtil.configureUsing(action)) - - override var preset: KotlinTargetPreset? = null - internal set -} - -internal fun KotlinTarget.disambiguateName(simpleName: String) = - lowerCamelCaseName(targetName, simpleName) open class KotlinAndroidTarget( override val targetName: String, @@ -344,94 +201,3 @@ open class KotlinAndroidTarget( } } } - -open class KotlinWithJavaTarget( - project: Project, - override val platformType: KotlinPlatformType, - override val targetName: String -) : AbstractKotlinTarget(project) { - override var disambiguationClassifier: String? = null - internal set - - override val defaultConfigurationName: String - get() = Dependency.DEFAULT_CONFIGURATION - - override val apiElementsConfigurationName: String - get() = JavaPlugin.API_ELEMENTS_CONFIGURATION_NAME - - override val runtimeElementsConfigurationName: String - get() = JavaPlugin.RUNTIME_ELEMENTS_CONFIGURATION_NAME - - override val artifactsTaskName: String - get() = JavaPlugin.JAR_TASK_NAME - - override val compilations: NamedDomainObjectContainer> = - @Suppress("UNCHECKED_CAST") - project.container( - KotlinWithJavaCompilation::class.java as Class>, - KotlinWithJavaCompilationFactory(project, this) - ) -} - -open class KotlinOnlyTarget>( - project: Project, - override val platformType: KotlinPlatformType -) : AbstractKotlinTarget(project) { - - override lateinit var compilations: NamedDomainObjectContainer - internal set - - override lateinit var targetName: String - internal set - - override var disambiguationClassifier: String? = null - internal set -} - -class KotlinNativeTarget( - project: Project, - val konanTarget: KonanTarget -) : KotlinOnlyTarget(project, KotlinPlatformType.native) { - - init { - attributes.attribute(konanTargetAttribute, konanTarget.name) - } - - val binaries = if(isGradleVersionAtLeast(4, 2)) { - // Use newInstance to allow accessing binaries by their names in Groovy using the extension mechanism. - project.objects.newInstance(KotlinNativeBinaryContainer::class.java, this, WrapUtil.toDomainObjectSet(NativeBinary::class.java)) - } else { - KotlinNativeBinaryContainer(this, WrapUtil.toDomainObjectSet(NativeBinary::class.java)) - } - - fun binaries(configure: KotlinNativeBinaryContainer.() -> Unit) { - binaries.configure() - } - - fun binaries(configure: Closure<*>) { - ConfigureUtil.configure(configure, binaries) - } - - override val artifactsTaskName: String - get() = disambiguateName("binaries") - - override val publishable: Boolean - get() = konanTarget.enabledOnCurrentHost - - // User-visible constants - val DEBUG = NativeBuildType.DEBUG - val RELEASE = NativeBuildType.RELEASE - - val EXECUTABLE = NativeOutputKind.EXECUTABLE - val FRAMEWORK = NativeOutputKind.FRAMEWORK - val DYNAMIC = NativeOutputKind.DYNAMIC - val STATIC = NativeOutputKind.STATIC - - companion object { - val konanTargetAttribute = Attribute.of( - "org.jetbrains.kotlin.native.target", - String::class.java - ) - } -} - diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinAndroidTargetPreset.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinAndroidTargetPreset.kt index 921736ad861..acf0636d347 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinAndroidTargetPreset.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinAndroidTargetPreset.kt @@ -6,168 +6,8 @@ package org.jetbrains.kotlin.gradle.plugin.mpp import org.gradle.api.Project -import org.gradle.api.artifacts.Dependency -import org.gradle.api.internal.file.FileResolver -import org.gradle.api.plugins.JavaPlugin -import org.gradle.internal.reflect.Instantiator -import org.jetbrains.kotlin.compilerRunner.KotlinNativeProjectProperty -import org.jetbrains.kotlin.compilerRunner.hasProperty -import org.jetbrains.kotlin.compilerRunner.konanHome -import org.jetbrains.kotlin.gradle.dsl.KotlinCompile -import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptions -import org.jetbrains.kotlin.gradle.dsl.kotlinExtension -import org.jetbrains.kotlin.gradle.plugin.* -import org.jetbrains.kotlin.gradle.plugin.sources.applyLanguageSettingsToKotlinTask -import org.jetbrains.kotlin.gradle.tasks.KotlinTasksProvider -import org.jetbrains.kotlin.gradle.utils.NativeCompilerDownloader -import org.jetbrains.kotlin.konan.KonanVersion -import org.jetbrains.kotlin.konan.target.HostManager -import org.jetbrains.kotlin.konan.target.KonanTarget -import java.io.File -import java.util.* - -abstract class KotlinOnlyTargetPreset>( - protected val project: Project, - private val instantiator: Instantiator, - private val fileResolver: FileResolver, - protected val kotlinPluginVersion: String -) : KotlinTargetPreset> { - - protected open fun createKotlinTargetConfigurator(): KotlinTargetConfigurator = - KotlinTargetConfigurator(createDefaultSourceSets = true, createTestCompilation = true) - - override fun createTarget(name: String): KotlinOnlyTarget { - val result = KotlinOnlyTarget(project, platformType).apply { - targetName = name - disambiguationClassifier = name - preset = this@KotlinOnlyTargetPreset - - val compilationFactory = createCompilationFactory(this) - compilations = project.container(compilationFactory.itemClass, compilationFactory) - } - - createKotlinTargetConfigurator().configureTarget(result) - - result.compilations.all { compilation -> - buildCompilationProcessor(compilation).run() - if (compilation.name == KotlinCompilation.MAIN_COMPILATION_NAME) { - sourcesJarTask(compilation, result.targetName, result.targetName.toLowerCase()) - } - } - - return result - } - - protected abstract fun createCompilationFactory(forTarget: KotlinOnlyTarget): KotlinCompilationFactory - protected abstract val platformType: KotlinPlatformType - internal abstract fun buildCompilationProcessor(compilation: T): KotlinSourceSetProcessor<*> -} - -class KotlinMetadataTargetPreset( - project: Project, - instantiator: Instantiator, - fileResolver: FileResolver, - kotlinPluginVersion: String -) : KotlinOnlyTargetPreset( - project, - instantiator, - fileResolver, - kotlinPluginVersion -) { - override fun getName(): String = PRESET_NAME - - override fun createCompilationFactory( - forTarget: KotlinOnlyTarget - ): KotlinCompilationFactory = - KotlinCommonCompilationFactory(forTarget) - - override val platformType: KotlinPlatformType - get() = KotlinPlatformType.common - - override fun buildCompilationProcessor(compilation: KotlinCommonCompilation): KotlinSourceSetProcessor<*> { - val tasksProvider = KotlinTasksProvider(compilation.target.targetName) - return KotlinCommonSourceSetProcessor(project, compilation, tasksProvider, kotlinPluginVersion) - } - - companion object { - const val PRESET_NAME = "metadata" - } - - override fun createKotlinTargetConfigurator(): KotlinTargetConfigurator = - KotlinTargetConfigurator(createDefaultSourceSets = false, createTestCompilation = false) - - override fun createTarget(name: String): KotlinOnlyTarget = - super.createTarget(name).apply { - val mainCompilation = compilations.getByName(KotlinCompilation.MAIN_COMPILATION_NAME) - val commonMainSourceSet = project.kotlinExtension.sourceSets.getByName(KotlinSourceSet.COMMON_MAIN_SOURCE_SET_NAME) - - mainCompilation.source(commonMainSourceSet) - - project.afterEvaluate { - // Since there's no default source set, apply language settings from commonMain: - val compileKotlinMetadata = project.tasks.getByName(mainCompilation.compileKotlinTaskName) as KotlinCompile<*> - applyLanguageSettingsToKotlinTask(commonMainSourceSet.languageSettings, compileKotlinMetadata) - } - } -} - -class KotlinJvmTargetPreset( - project: Project, - instantiator: Instantiator, - fileResolver: FileResolver, - kotlinPluginVersion: String -) : KotlinOnlyTargetPreset( - project, - instantiator, - fileResolver, - kotlinPluginVersion -) { - override fun getName(): String = PRESET_NAME - - override fun createCompilationFactory(forTarget: KotlinOnlyTarget): KotlinCompilationFactory = - KotlinJvmCompilationFactory(forTarget) - - override val platformType: KotlinPlatformType - get() = KotlinPlatformType.jvm - - override fun buildCompilationProcessor(compilation: KotlinJvmCompilation): KotlinSourceSetProcessor<*> { - val tasksProvider = KotlinTasksProvider(compilation.target.targetName) - return Kotlin2JvmSourceSetProcessor(project, tasksProvider, compilation, kotlinPluginVersion) - } - - companion object { - const val PRESET_NAME = "jvm" - } -} - -class KotlinJsTargetPreset( - project: Project, - instantiator: Instantiator, - fileResolver: FileResolver, - kotlinPluginVersion: String -) : KotlinOnlyTargetPreset( - project, - instantiator, - fileResolver, - kotlinPluginVersion -) { - override fun getName(): String = PRESET_NAME - - override fun createCompilationFactory(forTarget: KotlinOnlyTarget) = - KotlinJsCompilationFactory(project, forTarget) - - override val platformType: KotlinPlatformType - get() = KotlinPlatformType.js - - override fun buildCompilationProcessor(compilation: KotlinJsCompilation): KotlinSourceSetProcessor<*> { - val tasksProvider = KotlinTasksProvider(compilation.target.targetName) - return Kotlin2JsSourceSetProcessor(project, tasksProvider, compilation, kotlinPluginVersion) - } - - companion object { - const val PRESET_NAME = "js" - } -} +import org.jetbrains.kotlin.gradle.plugin.KotlinAndroidPlugin +import org.jetbrains.kotlin.gradle.plugin.KotlinTargetPreset class KotlinAndroidTargetPreset( private val project: Project, @@ -190,141 +30,3 @@ class KotlinAndroidTargetPreset( const val PRESET_NAME = "android" } } - -class KotlinJvmWithJavaTargetPreset( - private val project: Project, - private val kotlinPluginVersion: String -) : KotlinTargetPreset> { - - override fun getName(): String = PRESET_NAME - - override fun createTarget(name: String): KotlinWithJavaTarget { - project.plugins.apply(JavaPlugin::class.java) - - val target = KotlinWithJavaTarget(project, KotlinPlatformType.jvm, name).apply { - disambiguationClassifier = name - preset = this@KotlinJvmWithJavaTargetPreset - } - - AbstractKotlinPlugin.configureTarget(target) { compilation -> - Kotlin2JvmSourceSetProcessor(project, KotlinTasksProvider(name), compilation, kotlinPluginVersion) - } - - target.compilations.getByName("test").run { - val main = target.compilations.getByName(KotlinCompilation.MAIN_COMPILATION_NAME) - - compileDependencyFiles = project.files( - main.output.allOutputs, - project.configurations.maybeCreate(compileDependencyConfigurationName) - ) - runtimeDependencyFiles = project.files( - output.allOutputs, - main.output.allOutputs, - project.configurations.maybeCreate(runtimeDependencyConfigurationName) - ) - } - - return target - } - - companion object { - const val PRESET_NAME = "jvmWithJava" - } -} - -class KotlinNativeTargetPreset( - private val name: String, - val project: Project, - val konanTarget: KonanTarget, - private val kotlinPluginVersion: String -) : KotlinTargetPreset { - - init { - // This is required to obtain Kotlin/Native home in CLion plugin: - setupNativeHomePrivateProperty() - } - - override fun getName(): String = name - - private fun setupNativeHomePrivateProperty() = with(project) { - if (!hasProperty(KOTLIN_NATIVE_HOME_PRIVATE_PROPERTY)) - extensions.extraProperties.set(KOTLIN_NATIVE_HOME_PRIVATE_PROPERTY, konanHome) - } - - private fun setupNativeCompiler() = with(project) { - if (!hasProperty(KotlinNativeProjectProperty.KONAN_HOME_OVERRIDE)) { - NativeCompilerDownloader(this).downloadIfNeeded() - logger.info("Kotlin/Native distribution: $konanHome") - } else { - logger.info("User-provided Kotlin/Native distribution: $konanHome") - } - } - - // We declare default K/N dependencies as files to avoid searching them in remote repos (see KT-28128). - private fun defaultLibs(target: KonanTarget? = null): List = with(project) { - - val relPath = if (target != null) "platform/${target.name}" else "common" - - file("$konanHome/klib/$relPath") - .listFiles { file -> file.isDirectory } - ?.sortedBy { dir -> dir.name.toLowerCase() } - ?.map { dir -> dependencies.create(files(dir)) } ?: emptyList() - } - - override fun createTarget(name: String): KotlinNativeTarget { - setupNativeCompiler() - - val result = KotlinNativeTarget(project, konanTarget).apply { - targetName = name - disambiguationClassifier = name - preset = this@KotlinNativeTargetPreset - - val compilationFactory = KotlinNativeCompilationFactory(project, this) - compilations = project.container(compilationFactory.itemClass, compilationFactory) - } - - KotlinNativeTargetConfigurator(kotlinPluginVersion).configureTarget(result) - - // Allow IDE to resolve the libraries provided by the compiler by adding them into dependencies. - result.compilations.all { compilation -> - val target = compilation.target.konanTarget - // First, put common libs: - defaultLibs().forEach { - project.dependencies.add(compilation.compileDependencyConfigurationName, it) - } - // Then, platform-specific libs: - defaultLibs(target).forEach { - project.dependencies.add(compilation.compileDependencyConfigurationName, it) - } - } - - if (!konanTarget.enabledOnCurrentHost) { - with(HostManager()) { - val supportedHosts = enabledTargetsByHost.filterValues { konanTarget in it }.keys - val supportedHostsString = - if (supportedHosts.size == 1) - "a ${supportedHosts.single()} host" else - "one of the host platforms: ${supportedHosts.joinToString(", ")}" - project.logger.warn( - "Target '$name' for platform ${konanTarget} is ignored during build on this ${HostManager.host} machine. " + - "You can build it with $supportedHostsString." - ) - } - } - - return result - } - - companion object { - private const val KOTLIN_NATIVE_HOME_PRIVATE_PROPERTY = "konanHome" - } -} - -internal val KonanTarget.isCurrentHost: Boolean - get() = this == HostManager.host - -internal val KonanTarget.enabledOnCurrentHost - get() = HostManager().isEnabled(this) - -internal val KotlinNativeCompilation.isMainCompilation: Boolean - get() = name == KotlinCompilation.MAIN_COMPILATION_NAME diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinCommonCompilation.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinCommonCompilation.kt index 1284fe446f3..654268288e1 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinCommonCompilation.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinCommonCompilation.kt @@ -5,287 +5,12 @@ package org.jetbrains.kotlin.gradle.plugin.mpp -import groovy.lang.Closure -import org.gradle.api.Action -import org.gradle.api.NamedDomainObjectContainer -import org.gradle.api.Project -import org.gradle.api.attributes.AttributeContainer -import org.gradle.api.file.FileCollection -import org.gradle.api.file.SourceDirectorySet -import org.gradle.api.tasks.SourceSet -import org.gradle.util.ConfigureUtil -import org.jetbrains.kotlin.gradle.dsl.* -import org.jetbrains.kotlin.gradle.dsl.KotlinCompile -import org.jetbrains.kotlin.gradle.plugin.* -import org.jetbrains.kotlin.gradle.plugin.sources.defaultSourceSetLanguageSettingsChecker -import org.jetbrains.kotlin.gradle.plugin.sources.getSourceSetHierarchy -import org.jetbrains.kotlin.gradle.tasks.* -import org.jetbrains.kotlin.gradle.utils.addExtendsFromRelation -import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName -import java.io.File -import java.util.* -import java.util.concurrent.Callable - -internal fun KotlinCompilation<*>.composeName(prefix: String? = null, suffix: String? = null): String { - val compilationNamePart = compilationName.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME } - val targetNamePart = target.disambiguationClassifier - - return lowerCamelCaseName(prefix, targetNamePart, compilationNamePart, suffix) -} - -internal val KotlinCompilation<*>.defaultSourceSetName: String - get() = lowerCamelCaseName(target.disambiguationClassifier, compilationName) - -abstract class AbstractKotlinCompilation( - target: KotlinTarget, - override val compilationName: String -) : KotlinCompilation, HasKotlinDependencies { - - override val kotlinOptions: T - get() = compileKotlinTask.kotlinOptions - - override fun kotlinOptions(configure: T.() -> Unit) = - configure(kotlinOptions) - - @Suppress("UNCHECKED_CAST") - override val compileKotlinTask: KotlinCompile - get() = (target.project.tasks.getByName(compileKotlinTaskName) as KotlinCompile) - - // Don't declare this property in the constructor to avoid NPE - // when an overriding property of a subclass is accessed instead. - override val target: KotlinTarget = target - - private val attributeContainer = HierarchyAttributeContainer(target.attributes) - - override fun getAttributes(): AttributeContainer = attributeContainer - - override val kotlinSourceSets: MutableSet = mutableSetOf() - - override val allKotlinSourceSets: Set - get() = kotlinSourceSets.flatMapTo(mutableSetOf()) { it.getSourceSetHierarchy() } - - override val defaultSourceSet: KotlinSourceSet - get() = target.project.kotlinExtension.sourceSets.getByName(defaultSourceSetName) - - override fun defaultSourceSet(configure: KotlinSourceSet.() -> Unit) = - configure(defaultSourceSet) - - override val output: KotlinCompilationOutput by lazy { - DefaultKotlinCompilationOutput( - target.project, - Callable { target.project.buildDir.resolve("processedResources/${target.targetName}/$name") }) - } - - open fun addSourcesToCompileTask(sourceSet: KotlinSourceSet, addAsCommonSources: Boolean) { - fun AbstractKotlinCompile<*>.configureAction() { - source(sourceSet.kotlin) - sourceFilesExtensions(sourceSet.customSourceFilesExtensions) - if (addAsCommonSources) { - commonSourceSet += sourceSet.kotlin - } - } - - // Note! Invocation of withType-all results in preliminary task instantiation. - // After fix of this issue the following code should be uncommented: -// if (useLazyTaskConfiguration) { -// (target.project.tasks.named(compileKotlinTaskName) as TaskProvider>).configure { -// it.configureAction() -// } -// } - - target.project.tasks - // 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 -> - compileKotlinTask.configureAction() - } - } - - override fun source(sourceSet: KotlinSourceSet) { - if (kotlinSourceSets.add(sourceSet)) { - //TODO possibly issue with forced instantiation - target.project.whenEvaluated { - sourceSet.getSourceSetHierarchy().forEach { sourceSet -> - val isCommonSource = - CompilationSourceSetUtil.sourceSetsInMultipleCompilations(project)?.contains(sourceSet) ?: false - - addSourcesToCompileTask(sourceSet, addAsCommonSources = isCommonSource) - - // Use `forced = false` since `api`, `implementation`, and `compileOnly` may be missing in some cases like - // old Java & Android projects: - addExtendsFromRelation(apiConfigurationName, sourceSet.apiConfigurationName, forced = false) - addExtendsFromRelation(implementationConfigurationName, sourceSet.implementationConfigurationName, forced = false) - addExtendsFromRelation(compileOnlyConfigurationName, sourceSet.compileOnlyConfigurationName, forced = false) - - if (this@AbstractKotlinCompilation is KotlinCompilationToRunnableFiles<*>) { - addExtendsFromRelation(runtimeOnlyConfigurationName, sourceSet.runtimeOnlyConfigurationName, forced = false) - } - - if (sourceSet.name != defaultSourceSetName) { - kotlinExtension.sourceSets.findByName(defaultSourceSetName)?.let { defaultSourceSet -> - // Temporary solution for checking consistency across source sets participating in a compilation that may - // not be interconnected with the dependsOn relation: check the settings as if the default source set of - // the compilation depends on the one added to the compilation: - defaultSourceSetLanguageSettingsChecker.runAllChecks( - defaultSourceSet, - sourceSet - ) - } - } - } - } - } - } - - override val compileDependencyConfigurationName: String - get() = lowerCamelCaseName( - target.disambiguationClassifier, - compilationName.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME }.orEmpty(), - "compileClasspath" - ) - - override val compileKotlinTaskName: String - get() = lowerCamelCaseName( - "compile", - compilationName.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME }, - "Kotlin", - target.targetName - ) - - override val compileAllTaskName: String - get() = lowerCamelCaseName(target.disambiguationClassifier, compilationName, "classes") - - override lateinit var compileDependencyFiles: FileCollection - - override val apiConfigurationName: String - get() = disambiguateName("api") - - override val implementationConfigurationName: String - get() = disambiguateName("implementation") - - override val compileOnlyConfigurationName: String - get() = disambiguateName("compileOnly") - - override val runtimeOnlyConfigurationName: String - get() = disambiguateName("runtimeOnly") - - override fun dependencies(configure: KotlinDependencyHandler.() -> Unit): Unit = - DefaultKotlinDependencyHandler(this, target.project).run(configure) - - override fun dependencies(configureClosure: Closure) = - dependencies f@{ ConfigureUtil.configure(configureClosure, this@f) } - - override fun toString(): String = "compilation '$compilationName' ($target)" -} - -abstract class AbstractKotlinCompilationToRunnableFiles( - target: KotlinTarget, - name: String -) : AbstractKotlinCompilation(target, name), KotlinCompilationToRunnableFiles { - override val runtimeDependencyConfigurationName: String - get() = lowerCamelCaseName( - target.disambiguationClassifier, - compilationName.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME }, - "runtimeClasspath" - ) - - override lateinit var runtimeDependencyFiles: FileCollection -} - -internal fun KotlinCompilation<*>.disambiguateName(simpleName: String): String { - return lowerCamelCaseName( - target.disambiguationClassifier, - compilationName.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME }, - simpleName - ) -} - -open class KotlinJvmCompilation( - target: KotlinTarget, - name: String -) : AbstractKotlinCompilationToRunnableFiles(target, name), KotlinCompilationWithResources { - override val processResourcesTaskName: String - get() = disambiguateName("processResources") - - override val compileKotlinTask: org.jetbrains.kotlin.gradle.tasks.KotlinCompile - get() = super.compileKotlinTask as org.jetbrains.kotlin.gradle.tasks.KotlinCompile -} - -class KotlinWithJavaCompilation( - target: KotlinWithJavaTarget, - name: String -) : AbstractKotlinCompilationToRunnableFiles(target, name), KotlinCompilationWithResources { - lateinit var javaSourceSet: SourceSet - - override val output: KotlinCompilationOutput by lazy { KotlinWithJavaCompilationOutput(this) } - - override val processResourcesTaskName: String - get() = javaSourceSet.processResourcesTaskName - - override var runtimeDependencyFiles: FileCollection - get() = javaSourceSet.runtimeClasspath - set(value) { - javaSourceSet.runtimeClasspath = value - } - - override val runtimeDependencyConfigurationName: String - get() = javaSourceSet.runtimeClasspathConfigurationName - - override val compileDependencyConfigurationName: String - get() = javaSourceSet.compileClasspathConfigurationName - - override val runtimeOnlyConfigurationName: String - get() = javaSourceSet.runtimeOnlyConfigurationName - - override val implementationConfigurationName: String - get() = javaSourceSet.implementationConfigurationName - - override val apiConfigurationName: String - get() = javaSourceSet.apiConfigurationName - - override val compileOnlyConfigurationName: String - get() = javaSourceSet.compileOnlyConfigurationName - - override val compileAllTaskName: String - get() = javaSourceSet.classesTaskName - - override var compileDependencyFiles: FileCollection - get() = javaSourceSet.compileClasspath - set(value) { - javaSourceSet.compileClasspath = value - } - - fun source(javaSourceSet: SourceSet) { - with(target.project) { - afterEvaluate { - (tasks.getByName(compileKotlinTaskName) as AbstractKotlinCompile<*>).source(javaSourceSet.java) - } - } - } -} - -class KotlinJvmAndroidCompilation( - target: KotlinAndroidTarget, - name: String -) : AbstractKotlinCompilationToRunnableFiles(target, name) { - override val compileKotlinTask: org.jetbrains.kotlin.gradle.tasks.KotlinCompile - get() = super.compileKotlinTask as org.jetbrains.kotlin.gradle.tasks.KotlinCompile - - override val relatedConfigurationNames: List - get() = super.relatedConfigurationNames + listOf("${name}ApiElements", "${name}RuntimeElements") -} - -class KotlinJsCompilation( - target: KotlinTarget, - name: String -) : AbstractKotlinCompilationToRunnableFiles(target, name), KotlinCompilationWithResources { - override val processResourcesTaskName: String - get() = disambiguateName("processResources") - - override val compileKotlinTask: Kotlin2JsCompile - get() = super.compileKotlinTask as Kotlin2JsCompile -} +import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformCommonOptions +import org.jetbrains.kotlin.gradle.dsl.kotlinExtension +import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation +import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet +import org.jetbrains.kotlin.gradle.plugin.KotlinTarget +import org.jetbrains.kotlin.gradle.tasks.KotlinCompileCommon class KotlinCommonCompilation( target: KotlinTarget, @@ -303,169 +28,4 @@ class KotlinCommonCompilation( override val defaultSourceSet: KotlinSourceSet get() = target.project.kotlinExtension.sourceSets.getByName(commonSourceSetName) -} - -class KotlinNativeCompilation( - override val target: KotlinNativeTarget, - name: String -) : AbstractKotlinCompilation(target, name), KotlinCompilationWithResources { - - override val kotlinOptions: KotlinCommonOptions - get() = compileKotlinTask.kotlinOptions - - override val compileKotlinTask: KotlinNativeCompile - get() = super.compileKotlinTask as KotlinNativeCompile - - private val project: Project - get() = target.project - - // A collection containing all source sets used by this compilation - // (taking into account dependencies between source sets). Used by both compilation - // and linking tasks. Unlike kotlinSourceSets, includes dependency source sets. - // TODO: Move into the compilation task when the linking task does klib linking instead of compilation. - internal val allSources: MutableSet = mutableSetOf() - - // TODO: Move into the compilation task when the linking task does klib linking instead of compilation. - internal val commonSources: MutableSet = mutableSetOf() - - var isTestCompilation = false - - var friendCompilationName: String? = null - - internal val friendCompilation: KotlinNativeCompilation? - get() = friendCompilationName?.let { - target.compilations.getByName(it) - } - - // Used only to support the old APIs. TODO: Remove when the old APIs are removed. - internal val binaries = mutableMapOf, NativeBinary>() - - // Native-specific DSL. - var extraOpts = mutableListOf() - - fun extraOpts(vararg values: Any) = extraOpts(values.toList()) - fun extraOpts(values: List) { - extraOpts.addAll(values.map { it.toString() }) - } - - var buildTypes = mutableListOf() - var outputKinds = mutableListOf() - - fun outputKind(kind: NativeOutputKind) = outputKinds.add(kind) - - fun outputKinds(vararg kinds: NativeOutputKind) { - outputKinds = kinds.toMutableList() - } - - fun outputKinds(vararg kinds: String) { - outputKinds = kinds.map { NativeOutputKind.valueOf(it.toUpperCase()) }.toMutableList() - } - - fun outputKinds(kinds: List) { - outputKinds = kinds.map { - when (it) { - is NativeOutputKind -> it - is String -> NativeOutputKind.valueOf(it.toUpperCase()) - else -> error("Cannot use $it as an output kind") - } - }.toMutableList() - } - - var entryPoint: String? = null - fun entryPoint(value: String) { - entryPoint = value - } - - // Interop DSL. - val cinterops = project.container(DefaultCInteropSettings::class.java) { cinteropName -> - DefaultCInteropSettings(project, cinteropName, this) - } - - var linkerOpts = mutableListOf() - - fun cinterops(action: NamedDomainObjectContainer.() -> Unit) = cinterops.action() - fun cinterops(action: Closure) = cinterops(ConfigureUtil.configureUsing(action)) - fun cinterops(action: Action>) = action.execute(cinterops) - - fun linkerOpts(vararg values: String) = linkerOpts(values.toList()) - fun linkerOpts(values: List) { - linkerOpts.addAll(values) - } - - // Task accessors. - fun findLinkTask(kind: NativeOutputKind, buildType: NativeBuildType): KotlinNativeLink? = binaries[kind to buildType]?.linkTask - - fun getLinkTask(kind: NativeOutputKind, buildType: NativeBuildType): KotlinNativeLink = - findLinkTask(kind, buildType) - ?: throw IllegalArgumentException("Cannot find a link task for the binary kind '$kind' and the build type '$buildType'") - - fun findLinkTask(kind: String, buildType: String) = - findLinkTask(NativeOutputKind.valueOf(kind.toUpperCase()), NativeBuildType.valueOf(buildType.toUpperCase())) - - fun getLinkTask(kind: String, buildType: String) = - getLinkTask(NativeOutputKind.valueOf(kind.toUpperCase()), NativeBuildType.valueOf(buildType.toUpperCase())) - - fun findBinary(kind: NativeOutputKind, buildType: NativeBuildType): File? = findLinkTask(kind, buildType)?.outputFile?.get() - - fun getBinary(kind: NativeOutputKind, buildType: NativeBuildType): File = getLinkTask(kind, buildType).outputFile.get() - - fun findBinary(kind: String, buildType: String) = - findBinary(NativeOutputKind.valueOf(kind.toUpperCase()), NativeBuildType.valueOf(buildType.toUpperCase())) - - fun getBinary(kind: String, buildType: String) = - getBinary(NativeOutputKind.valueOf(kind.toUpperCase()), NativeBuildType.valueOf(buildType.toUpperCase())) - - // Naming - override val processResourcesTaskName: String - get() = disambiguateName("processResources") - - fun linkTaskName(kind: NativeOutputKind, buildType: NativeBuildType): String = - lowerCamelCaseName( - "link", - KotlinNativeBinaryContainer.generateBinaryName(compilationName, buildType, kind.taskNameClassifier), - target.targetName - ) - - fun linkTaskName(kind: String, buildType: String) = - linkTaskName(NativeOutputKind.valueOf(kind.toUpperCase()), NativeBuildType.valueOf(buildType.toUpperCase())) - - override val compileDependencyConfigurationName: String - get() = lowerCamelCaseName( - target.disambiguationClassifier, - compilationName.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME }.orEmpty(), - "compileKlibraries" - ) - - override val compileAllTaskName: String - get() = lowerCamelCaseName(target.disambiguationClassifier, compilationName, "klibrary") - - val binariesTaskName: String - get() = lowerCamelCaseName(target.disambiguationClassifier, compilationName, "binaries") - - override fun addSourcesToCompileTask(sourceSet: KotlinSourceSet, addAsCommonSources: Boolean) { - allSources.add(sourceSet.kotlin) - if (addAsCommonSources) { - commonSources.add(sourceSet.kotlin) - } - } -} - -private object CompilationSourceSetUtil { - // Cache the results per project - private val projectSourceSetsInMultipleCompilationsCache = WeakHashMap>() - - fun sourceSetsInMultipleCompilations(project: Project) = - projectSourceSetsInMultipleCompilationsCache.computeIfAbsent(project) { _ -> - check(project.state.executed) { "Should only be computed after the project is evaluated" } - - val compilations = (project.kotlinExtension as? KotlinMultiplatformExtension)?.targets?.flatMap { it.compilations } - ?: return@computeIfAbsent null - - compilations - .flatMap { compilation -> compilation.allKotlinSourceSets.map { sourceSet -> compilation to sourceSet } } - .groupingBy { (_, sourceSet) -> sourceSet } - .eachCount() - .filterValues { it > 1 } - .keys - } } \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinCompilationFactory.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinCompilationFactory.kt index e63b6e6573d..c0d54714461 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinCompilationFactory.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinCompilationFactory.kt @@ -7,8 +7,6 @@ package org.jetbrains.kotlin.gradle.plugin.mpp import org.gradle.api.NamedDomainObjectFactory -import org.gradle.api.Project -import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation interface KotlinCompilationFactory> : NamedDomainObjectFactory { @@ -23,71 +21,4 @@ class KotlinCommonCompilationFactory( override fun create(name: String): KotlinCommonCompilation = KotlinCommonCompilation(target, name) -} - -class KotlinJvmCompilationFactory( - val target: KotlinOnlyTarget -) : KotlinCompilationFactory { - override val itemClass: Class - get() = KotlinJvmCompilation::class.java - - override fun create(name: String): KotlinJvmCompilation = - KotlinJvmCompilation(target, name) -} - -class KotlinWithJavaCompilationFactory( - val project: Project, - val target: KotlinWithJavaTarget -) : KotlinCompilationFactory> { - - override val itemClass: Class> - @Suppress("UNCHECKED_CAST") - get() = KotlinWithJavaCompilation::class.java as Class> - - override fun create(name: String): KotlinWithJavaCompilation { - val result = KotlinWithJavaCompilation(target, name) - return result - } -} - -class KotlinJvmAndroidCompilationFactory( - val project: Project, - val target: KotlinAndroidTarget -) : KotlinCompilationFactory { - - override val itemClass: Class - get() = KotlinJvmAndroidCompilation::class.java - - override fun create(name: String): KotlinJvmAndroidCompilation = - KotlinJvmAndroidCompilation(target, name) -} - -class KotlinJsCompilationFactory( - val project: Project, - val target: KotlinOnlyTarget -) : KotlinCompilationFactory { - override val itemClass: Class - get() = KotlinJsCompilation::class.java - - override fun create(name: String): KotlinJsCompilation = - KotlinJsCompilation(target, name) -} - -class KotlinNativeCompilationFactory( - val project: Project, - val target: KotlinNativeTarget -) : KotlinCompilationFactory { - - override val itemClass: Class - get() = KotlinNativeCompilation::class.java - - override fun create(name: String): KotlinNativeCompilation = - KotlinNativeCompilation(target, name).apply { - if (name == KotlinCompilation.TEST_COMPILATION_NAME) { - friendCompilationName = KotlinCompilation.MAIN_COMPILATION_NAME - isTestCompilation = true - } - buildTypes = mutableListOf(NativeBuildType.DEBUG, NativeBuildType.RELEASE) - } - } \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinJsCompilation.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinJsCompilation.kt index 1284fe446f3..85367d7bbf0 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinJsCompilation.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinJsCompilation.kt @@ -5,276 +5,10 @@ package org.jetbrains.kotlin.gradle.plugin.mpp -import groovy.lang.Closure -import org.gradle.api.Action -import org.gradle.api.NamedDomainObjectContainer -import org.gradle.api.Project -import org.gradle.api.attributes.AttributeContainer -import org.gradle.api.file.FileCollection -import org.gradle.api.file.SourceDirectorySet -import org.gradle.api.tasks.SourceSet -import org.gradle.util.ConfigureUtil -import org.jetbrains.kotlin.gradle.dsl.* -import org.jetbrains.kotlin.gradle.dsl.KotlinCompile -import org.jetbrains.kotlin.gradle.plugin.* -import org.jetbrains.kotlin.gradle.plugin.sources.defaultSourceSetLanguageSettingsChecker -import org.jetbrains.kotlin.gradle.plugin.sources.getSourceSetHierarchy -import org.jetbrains.kotlin.gradle.tasks.* -import org.jetbrains.kotlin.gradle.utils.addExtendsFromRelation -import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName -import java.io.File -import java.util.* -import java.util.concurrent.Callable - -internal fun KotlinCompilation<*>.composeName(prefix: String? = null, suffix: String? = null): String { - val compilationNamePart = compilationName.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME } - val targetNamePart = target.disambiguationClassifier - - return lowerCamelCaseName(prefix, targetNamePart, compilationNamePart, suffix) -} - -internal val KotlinCompilation<*>.defaultSourceSetName: String - get() = lowerCamelCaseName(target.disambiguationClassifier, compilationName) - -abstract class AbstractKotlinCompilation( - target: KotlinTarget, - override val compilationName: String -) : KotlinCompilation, HasKotlinDependencies { - - override val kotlinOptions: T - get() = compileKotlinTask.kotlinOptions - - override fun kotlinOptions(configure: T.() -> Unit) = - configure(kotlinOptions) - - @Suppress("UNCHECKED_CAST") - override val compileKotlinTask: KotlinCompile - get() = (target.project.tasks.getByName(compileKotlinTaskName) as KotlinCompile) - - // Don't declare this property in the constructor to avoid NPE - // when an overriding property of a subclass is accessed instead. - override val target: KotlinTarget = target - - private val attributeContainer = HierarchyAttributeContainer(target.attributes) - - override fun getAttributes(): AttributeContainer = attributeContainer - - override val kotlinSourceSets: MutableSet = mutableSetOf() - - override val allKotlinSourceSets: Set - get() = kotlinSourceSets.flatMapTo(mutableSetOf()) { it.getSourceSetHierarchy() } - - override val defaultSourceSet: KotlinSourceSet - get() = target.project.kotlinExtension.sourceSets.getByName(defaultSourceSetName) - - override fun defaultSourceSet(configure: KotlinSourceSet.() -> Unit) = - configure(defaultSourceSet) - - override val output: KotlinCompilationOutput by lazy { - DefaultKotlinCompilationOutput( - target.project, - Callable { target.project.buildDir.resolve("processedResources/${target.targetName}/$name") }) - } - - open fun addSourcesToCompileTask(sourceSet: KotlinSourceSet, addAsCommonSources: Boolean) { - fun AbstractKotlinCompile<*>.configureAction() { - source(sourceSet.kotlin) - sourceFilesExtensions(sourceSet.customSourceFilesExtensions) - if (addAsCommonSources) { - commonSourceSet += sourceSet.kotlin - } - } - - // Note! Invocation of withType-all results in preliminary task instantiation. - // After fix of this issue the following code should be uncommented: -// if (useLazyTaskConfiguration) { -// (target.project.tasks.named(compileKotlinTaskName) as TaskProvider>).configure { -// it.configureAction() -// } -// } - - target.project.tasks - // 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 -> - compileKotlinTask.configureAction() - } - } - - override fun source(sourceSet: KotlinSourceSet) { - if (kotlinSourceSets.add(sourceSet)) { - //TODO possibly issue with forced instantiation - target.project.whenEvaluated { - sourceSet.getSourceSetHierarchy().forEach { sourceSet -> - val isCommonSource = - CompilationSourceSetUtil.sourceSetsInMultipleCompilations(project)?.contains(sourceSet) ?: false - - addSourcesToCompileTask(sourceSet, addAsCommonSources = isCommonSource) - - // Use `forced = false` since `api`, `implementation`, and `compileOnly` may be missing in some cases like - // old Java & Android projects: - addExtendsFromRelation(apiConfigurationName, sourceSet.apiConfigurationName, forced = false) - addExtendsFromRelation(implementationConfigurationName, sourceSet.implementationConfigurationName, forced = false) - addExtendsFromRelation(compileOnlyConfigurationName, sourceSet.compileOnlyConfigurationName, forced = false) - - if (this@AbstractKotlinCompilation is KotlinCompilationToRunnableFiles<*>) { - addExtendsFromRelation(runtimeOnlyConfigurationName, sourceSet.runtimeOnlyConfigurationName, forced = false) - } - - if (sourceSet.name != defaultSourceSetName) { - kotlinExtension.sourceSets.findByName(defaultSourceSetName)?.let { defaultSourceSet -> - // Temporary solution for checking consistency across source sets participating in a compilation that may - // not be interconnected with the dependsOn relation: check the settings as if the default source set of - // the compilation depends on the one added to the compilation: - defaultSourceSetLanguageSettingsChecker.runAllChecks( - defaultSourceSet, - sourceSet - ) - } - } - } - } - } - } - - override val compileDependencyConfigurationName: String - get() = lowerCamelCaseName( - target.disambiguationClassifier, - compilationName.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME }.orEmpty(), - "compileClasspath" - ) - - override val compileKotlinTaskName: String - get() = lowerCamelCaseName( - "compile", - compilationName.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME }, - "Kotlin", - target.targetName - ) - - override val compileAllTaskName: String - get() = lowerCamelCaseName(target.disambiguationClassifier, compilationName, "classes") - - override lateinit var compileDependencyFiles: FileCollection - - override val apiConfigurationName: String - get() = disambiguateName("api") - - override val implementationConfigurationName: String - get() = disambiguateName("implementation") - - override val compileOnlyConfigurationName: String - get() = disambiguateName("compileOnly") - - override val runtimeOnlyConfigurationName: String - get() = disambiguateName("runtimeOnly") - - override fun dependencies(configure: KotlinDependencyHandler.() -> Unit): Unit = - DefaultKotlinDependencyHandler(this, target.project).run(configure) - - override fun dependencies(configureClosure: Closure) = - dependencies f@{ ConfigureUtil.configure(configureClosure, this@f) } - - override fun toString(): String = "compilation '$compilationName' ($target)" -} - -abstract class AbstractKotlinCompilationToRunnableFiles( - target: KotlinTarget, - name: String -) : AbstractKotlinCompilation(target, name), KotlinCompilationToRunnableFiles { - override val runtimeDependencyConfigurationName: String - get() = lowerCamelCaseName( - target.disambiguationClassifier, - compilationName.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME }, - "runtimeClasspath" - ) - - override lateinit var runtimeDependencyFiles: FileCollection -} - -internal fun KotlinCompilation<*>.disambiguateName(simpleName: String): String { - return lowerCamelCaseName( - target.disambiguationClassifier, - compilationName.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME }, - simpleName - ) -} - -open class KotlinJvmCompilation( - target: KotlinTarget, - name: String -) : AbstractKotlinCompilationToRunnableFiles(target, name), KotlinCompilationWithResources { - override val processResourcesTaskName: String - get() = disambiguateName("processResources") - - override val compileKotlinTask: org.jetbrains.kotlin.gradle.tasks.KotlinCompile - get() = super.compileKotlinTask as org.jetbrains.kotlin.gradle.tasks.KotlinCompile -} - -class KotlinWithJavaCompilation( - target: KotlinWithJavaTarget, - name: String -) : AbstractKotlinCompilationToRunnableFiles(target, name), KotlinCompilationWithResources { - lateinit var javaSourceSet: SourceSet - - override val output: KotlinCompilationOutput by lazy { KotlinWithJavaCompilationOutput(this) } - - override val processResourcesTaskName: String - get() = javaSourceSet.processResourcesTaskName - - override var runtimeDependencyFiles: FileCollection - get() = javaSourceSet.runtimeClasspath - set(value) { - javaSourceSet.runtimeClasspath = value - } - - override val runtimeDependencyConfigurationName: String - get() = javaSourceSet.runtimeClasspathConfigurationName - - override val compileDependencyConfigurationName: String - get() = javaSourceSet.compileClasspathConfigurationName - - override val runtimeOnlyConfigurationName: String - get() = javaSourceSet.runtimeOnlyConfigurationName - - override val implementationConfigurationName: String - get() = javaSourceSet.implementationConfigurationName - - override val apiConfigurationName: String - get() = javaSourceSet.apiConfigurationName - - override val compileOnlyConfigurationName: String - get() = javaSourceSet.compileOnlyConfigurationName - - override val compileAllTaskName: String - get() = javaSourceSet.classesTaskName - - override var compileDependencyFiles: FileCollection - get() = javaSourceSet.compileClasspath - set(value) { - javaSourceSet.compileClasspath = value - } - - fun source(javaSourceSet: SourceSet) { - with(target.project) { - afterEvaluate { - (tasks.getByName(compileKotlinTaskName) as AbstractKotlinCompile<*>).source(javaSourceSet.java) - } - } - } -} - -class KotlinJvmAndroidCompilation( - target: KotlinAndroidTarget, - name: String -) : AbstractKotlinCompilationToRunnableFiles(target, name) { - override val compileKotlinTask: org.jetbrains.kotlin.gradle.tasks.KotlinCompile - get() = super.compileKotlinTask as org.jetbrains.kotlin.gradle.tasks.KotlinCompile - - override val relatedConfigurationNames: List - get() = super.relatedConfigurationNames + listOf("${name}ApiElements", "${name}RuntimeElements") -} +import org.jetbrains.kotlin.gradle.dsl.KotlinJsOptions +import org.jetbrains.kotlin.gradle.plugin.KotlinCompilationWithResources +import org.jetbrains.kotlin.gradle.plugin.KotlinTarget +import org.jetbrains.kotlin.gradle.tasks.Kotlin2JsCompile class KotlinJsCompilation( target: KotlinTarget, @@ -285,187 +19,4 @@ class KotlinJsCompilation( override val compileKotlinTask: Kotlin2JsCompile get() = super.compileKotlinTask as Kotlin2JsCompile -} - -class KotlinCommonCompilation( - target: KotlinTarget, - name: String -) : AbstractKotlinCompilation(target, name) { - override val compileKotlinTask: KotlinCompileCommon - get() = super.compileKotlinTask as KotlinCompileCommon - - // TODO once we properly compile metadata for each source set, the default source sets will likely become just the source sets - // which are transformed to metadata - private val commonSourceSetName = when (compilationName) { - KotlinCompilation.MAIN_COMPILATION_NAME -> KotlinSourceSet.COMMON_MAIN_SOURCE_SET_NAME - else -> error("Custom metadata compilations are not supported yet") - } - - override val defaultSourceSet: KotlinSourceSet - get() = target.project.kotlinExtension.sourceSets.getByName(commonSourceSetName) -} - -class KotlinNativeCompilation( - override val target: KotlinNativeTarget, - name: String -) : AbstractKotlinCompilation(target, name), KotlinCompilationWithResources { - - override val kotlinOptions: KotlinCommonOptions - get() = compileKotlinTask.kotlinOptions - - override val compileKotlinTask: KotlinNativeCompile - get() = super.compileKotlinTask as KotlinNativeCompile - - private val project: Project - get() = target.project - - // A collection containing all source sets used by this compilation - // (taking into account dependencies between source sets). Used by both compilation - // and linking tasks. Unlike kotlinSourceSets, includes dependency source sets. - // TODO: Move into the compilation task when the linking task does klib linking instead of compilation. - internal val allSources: MutableSet = mutableSetOf() - - // TODO: Move into the compilation task when the linking task does klib linking instead of compilation. - internal val commonSources: MutableSet = mutableSetOf() - - var isTestCompilation = false - - var friendCompilationName: String? = null - - internal val friendCompilation: KotlinNativeCompilation? - get() = friendCompilationName?.let { - target.compilations.getByName(it) - } - - // Used only to support the old APIs. TODO: Remove when the old APIs are removed. - internal val binaries = mutableMapOf, NativeBinary>() - - // Native-specific DSL. - var extraOpts = mutableListOf() - - fun extraOpts(vararg values: Any) = extraOpts(values.toList()) - fun extraOpts(values: List) { - extraOpts.addAll(values.map { it.toString() }) - } - - var buildTypes = mutableListOf() - var outputKinds = mutableListOf() - - fun outputKind(kind: NativeOutputKind) = outputKinds.add(kind) - - fun outputKinds(vararg kinds: NativeOutputKind) { - outputKinds = kinds.toMutableList() - } - - fun outputKinds(vararg kinds: String) { - outputKinds = kinds.map { NativeOutputKind.valueOf(it.toUpperCase()) }.toMutableList() - } - - fun outputKinds(kinds: List) { - outputKinds = kinds.map { - when (it) { - is NativeOutputKind -> it - is String -> NativeOutputKind.valueOf(it.toUpperCase()) - else -> error("Cannot use $it as an output kind") - } - }.toMutableList() - } - - var entryPoint: String? = null - fun entryPoint(value: String) { - entryPoint = value - } - - // Interop DSL. - val cinterops = project.container(DefaultCInteropSettings::class.java) { cinteropName -> - DefaultCInteropSettings(project, cinteropName, this) - } - - var linkerOpts = mutableListOf() - - fun cinterops(action: NamedDomainObjectContainer.() -> Unit) = cinterops.action() - fun cinterops(action: Closure) = cinterops(ConfigureUtil.configureUsing(action)) - fun cinterops(action: Action>) = action.execute(cinterops) - - fun linkerOpts(vararg values: String) = linkerOpts(values.toList()) - fun linkerOpts(values: List) { - linkerOpts.addAll(values) - } - - // Task accessors. - fun findLinkTask(kind: NativeOutputKind, buildType: NativeBuildType): KotlinNativeLink? = binaries[kind to buildType]?.linkTask - - fun getLinkTask(kind: NativeOutputKind, buildType: NativeBuildType): KotlinNativeLink = - findLinkTask(kind, buildType) - ?: throw IllegalArgumentException("Cannot find a link task for the binary kind '$kind' and the build type '$buildType'") - - fun findLinkTask(kind: String, buildType: String) = - findLinkTask(NativeOutputKind.valueOf(kind.toUpperCase()), NativeBuildType.valueOf(buildType.toUpperCase())) - - fun getLinkTask(kind: String, buildType: String) = - getLinkTask(NativeOutputKind.valueOf(kind.toUpperCase()), NativeBuildType.valueOf(buildType.toUpperCase())) - - fun findBinary(kind: NativeOutputKind, buildType: NativeBuildType): File? = findLinkTask(kind, buildType)?.outputFile?.get() - - fun getBinary(kind: NativeOutputKind, buildType: NativeBuildType): File = getLinkTask(kind, buildType).outputFile.get() - - fun findBinary(kind: String, buildType: String) = - findBinary(NativeOutputKind.valueOf(kind.toUpperCase()), NativeBuildType.valueOf(buildType.toUpperCase())) - - fun getBinary(kind: String, buildType: String) = - getBinary(NativeOutputKind.valueOf(kind.toUpperCase()), NativeBuildType.valueOf(buildType.toUpperCase())) - - // Naming - override val processResourcesTaskName: String - get() = disambiguateName("processResources") - - fun linkTaskName(kind: NativeOutputKind, buildType: NativeBuildType): String = - lowerCamelCaseName( - "link", - KotlinNativeBinaryContainer.generateBinaryName(compilationName, buildType, kind.taskNameClassifier), - target.targetName - ) - - fun linkTaskName(kind: String, buildType: String) = - linkTaskName(NativeOutputKind.valueOf(kind.toUpperCase()), NativeBuildType.valueOf(buildType.toUpperCase())) - - override val compileDependencyConfigurationName: String - get() = lowerCamelCaseName( - target.disambiguationClassifier, - compilationName.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME }.orEmpty(), - "compileKlibraries" - ) - - override val compileAllTaskName: String - get() = lowerCamelCaseName(target.disambiguationClassifier, compilationName, "klibrary") - - val binariesTaskName: String - get() = lowerCamelCaseName(target.disambiguationClassifier, compilationName, "binaries") - - override fun addSourcesToCompileTask(sourceSet: KotlinSourceSet, addAsCommonSources: Boolean) { - allSources.add(sourceSet.kotlin) - if (addAsCommonSources) { - commonSources.add(sourceSet.kotlin) - } - } -} - -private object CompilationSourceSetUtil { - // Cache the results per project - private val projectSourceSetsInMultipleCompilationsCache = WeakHashMap>() - - fun sourceSetsInMultipleCompilations(project: Project) = - projectSourceSetsInMultipleCompilationsCache.computeIfAbsent(project) { _ -> - check(project.state.executed) { "Should only be computed after the project is evaluated" } - - val compilations = (project.kotlinExtension as? KotlinMultiplatformExtension)?.targets?.flatMap { it.compilations } - ?: return@computeIfAbsent null - - compilations - .flatMap { compilation -> compilation.allKotlinSourceSets.map { sourceSet -> compilation to sourceSet } } - .groupingBy { (_, sourceSet) -> sourceSet } - .eachCount() - .filterValues { it > 1 } - .keys - } } \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinJsCompilationFactory.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinJsCompilationFactory.kt index e63b6e6573d..fb99442e5d3 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinJsCompilationFactory.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinJsCompilationFactory.kt @@ -6,61 +6,7 @@ package org.jetbrains.kotlin.gradle.plugin.mpp -import org.gradle.api.NamedDomainObjectFactory import org.gradle.api.Project -import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions -import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation - -interface KotlinCompilationFactory> : NamedDomainObjectFactory { - val itemClass: Class -} - -class KotlinCommonCompilationFactory( - val target: KotlinOnlyTarget -) : KotlinCompilationFactory { - override val itemClass: Class - get() = KotlinCommonCompilation::class.java - - override fun create(name: String): KotlinCommonCompilation = - KotlinCommonCompilation(target, name) -} - -class KotlinJvmCompilationFactory( - val target: KotlinOnlyTarget -) : KotlinCompilationFactory { - override val itemClass: Class - get() = KotlinJvmCompilation::class.java - - override fun create(name: String): KotlinJvmCompilation = - KotlinJvmCompilation(target, name) -} - -class KotlinWithJavaCompilationFactory( - val project: Project, - val target: KotlinWithJavaTarget -) : KotlinCompilationFactory> { - - override val itemClass: Class> - @Suppress("UNCHECKED_CAST") - get() = KotlinWithJavaCompilation::class.java as Class> - - override fun create(name: String): KotlinWithJavaCompilation { - val result = KotlinWithJavaCompilation(target, name) - return result - } -} - -class KotlinJvmAndroidCompilationFactory( - val project: Project, - val target: KotlinAndroidTarget -) : KotlinCompilationFactory { - - override val itemClass: Class - get() = KotlinJvmAndroidCompilation::class.java - - override fun create(name: String): KotlinJvmAndroidCompilation = - KotlinJvmAndroidCompilation(target, name) -} class KotlinJsCompilationFactory( val project: Project, @@ -71,23 +17,4 @@ class KotlinJsCompilationFactory( override fun create(name: String): KotlinJsCompilation = KotlinJsCompilation(target, name) -} - -class KotlinNativeCompilationFactory( - val project: Project, - val target: KotlinNativeTarget -) : KotlinCompilationFactory { - - override val itemClass: Class - get() = KotlinNativeCompilation::class.java - - override fun create(name: String): KotlinNativeCompilation = - KotlinNativeCompilation(target, name).apply { - if (name == KotlinCompilation.TEST_COMPILATION_NAME) { - friendCompilationName = KotlinCompilation.MAIN_COMPILATION_NAME - isTestCompilation = true - } - buildTypes = mutableListOf(NativeBuildType.DEBUG, NativeBuildType.RELEASE) - } - } \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinJsTargetPreset.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinJsTargetPreset.kt index 921736ad861..848779c04f2 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinJsTargetPreset.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinJsTargetPreset.kt @@ -6,139 +6,12 @@ package org.jetbrains.kotlin.gradle.plugin.mpp import org.gradle.api.Project -import org.gradle.api.artifacts.Dependency import org.gradle.api.internal.file.FileResolver -import org.gradle.api.plugins.JavaPlugin import org.gradle.internal.reflect.Instantiator -import org.jetbrains.kotlin.compilerRunner.KotlinNativeProjectProperty -import org.jetbrains.kotlin.compilerRunner.hasProperty -import org.jetbrains.kotlin.compilerRunner.konanHome -import org.jetbrains.kotlin.gradle.dsl.KotlinCompile -import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptions -import org.jetbrains.kotlin.gradle.dsl.kotlinExtension -import org.jetbrains.kotlin.gradle.plugin.* -import org.jetbrains.kotlin.gradle.plugin.sources.applyLanguageSettingsToKotlinTask +import org.jetbrains.kotlin.gradle.plugin.Kotlin2JsSourceSetProcessor +import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType +import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSetProcessor import org.jetbrains.kotlin.gradle.tasks.KotlinTasksProvider -import org.jetbrains.kotlin.gradle.utils.NativeCompilerDownloader -import org.jetbrains.kotlin.konan.KonanVersion -import org.jetbrains.kotlin.konan.target.HostManager -import org.jetbrains.kotlin.konan.target.KonanTarget -import java.io.File -import java.util.* - -abstract class KotlinOnlyTargetPreset>( - protected val project: Project, - private val instantiator: Instantiator, - private val fileResolver: FileResolver, - protected val kotlinPluginVersion: String -) : KotlinTargetPreset> { - - protected open fun createKotlinTargetConfigurator(): KotlinTargetConfigurator = - KotlinTargetConfigurator(createDefaultSourceSets = true, createTestCompilation = true) - - override fun createTarget(name: String): KotlinOnlyTarget { - val result = KotlinOnlyTarget(project, platformType).apply { - targetName = name - disambiguationClassifier = name - preset = this@KotlinOnlyTargetPreset - - val compilationFactory = createCompilationFactory(this) - compilations = project.container(compilationFactory.itemClass, compilationFactory) - } - - createKotlinTargetConfigurator().configureTarget(result) - - result.compilations.all { compilation -> - buildCompilationProcessor(compilation).run() - if (compilation.name == KotlinCompilation.MAIN_COMPILATION_NAME) { - sourcesJarTask(compilation, result.targetName, result.targetName.toLowerCase()) - } - } - - return result - } - - protected abstract fun createCompilationFactory(forTarget: KotlinOnlyTarget): KotlinCompilationFactory - protected abstract val platformType: KotlinPlatformType - internal abstract fun buildCompilationProcessor(compilation: T): KotlinSourceSetProcessor<*> -} - -class KotlinMetadataTargetPreset( - project: Project, - instantiator: Instantiator, - fileResolver: FileResolver, - kotlinPluginVersion: String -) : KotlinOnlyTargetPreset( - project, - instantiator, - fileResolver, - kotlinPluginVersion -) { - override fun getName(): String = PRESET_NAME - - override fun createCompilationFactory( - forTarget: KotlinOnlyTarget - ): KotlinCompilationFactory = - KotlinCommonCompilationFactory(forTarget) - - override val platformType: KotlinPlatformType - get() = KotlinPlatformType.common - - override fun buildCompilationProcessor(compilation: KotlinCommonCompilation): KotlinSourceSetProcessor<*> { - val tasksProvider = KotlinTasksProvider(compilation.target.targetName) - return KotlinCommonSourceSetProcessor(project, compilation, tasksProvider, kotlinPluginVersion) - } - - companion object { - const val PRESET_NAME = "metadata" - } - - override fun createKotlinTargetConfigurator(): KotlinTargetConfigurator = - KotlinTargetConfigurator(createDefaultSourceSets = false, createTestCompilation = false) - - override fun createTarget(name: String): KotlinOnlyTarget = - super.createTarget(name).apply { - val mainCompilation = compilations.getByName(KotlinCompilation.MAIN_COMPILATION_NAME) - val commonMainSourceSet = project.kotlinExtension.sourceSets.getByName(KotlinSourceSet.COMMON_MAIN_SOURCE_SET_NAME) - - mainCompilation.source(commonMainSourceSet) - - project.afterEvaluate { - // Since there's no default source set, apply language settings from commonMain: - val compileKotlinMetadata = project.tasks.getByName(mainCompilation.compileKotlinTaskName) as KotlinCompile<*> - applyLanguageSettingsToKotlinTask(commonMainSourceSet.languageSettings, compileKotlinMetadata) - } - } -} - -class KotlinJvmTargetPreset( - project: Project, - instantiator: Instantiator, - fileResolver: FileResolver, - kotlinPluginVersion: String -) : KotlinOnlyTargetPreset( - project, - instantiator, - fileResolver, - kotlinPluginVersion -) { - override fun getName(): String = PRESET_NAME - - override fun createCompilationFactory(forTarget: KotlinOnlyTarget): KotlinCompilationFactory = - KotlinJvmCompilationFactory(forTarget) - - override val platformType: KotlinPlatformType - get() = KotlinPlatformType.jvm - - override fun buildCompilationProcessor(compilation: KotlinJvmCompilation): KotlinSourceSetProcessor<*> { - val tasksProvider = KotlinTasksProvider(compilation.target.targetName) - return Kotlin2JvmSourceSetProcessor(project, tasksProvider, compilation, kotlinPluginVersion) - } - - companion object { - const val PRESET_NAME = "jvm" - } -} class KotlinJsTargetPreset( project: Project, @@ -168,163 +41,3 @@ class KotlinJsTargetPreset( const val PRESET_NAME = "js" } } - -class KotlinAndroidTargetPreset( - private val project: Project, - private val kotlinPluginVersion: String -) : KotlinTargetPreset { - - override fun getName(): String = PRESET_NAME - - override fun createTarget(name: String): KotlinAndroidTarget { - val result = KotlinAndroidTarget(name, project).apply { - disambiguationClassifier = name - preset = this@KotlinAndroidTargetPreset - } - - KotlinAndroidPlugin.applyToTarget(kotlinPluginVersion, result) - return result - } - - companion object { - const val PRESET_NAME = "android" - } -} - -class KotlinJvmWithJavaTargetPreset( - private val project: Project, - private val kotlinPluginVersion: String -) : KotlinTargetPreset> { - - override fun getName(): String = PRESET_NAME - - override fun createTarget(name: String): KotlinWithJavaTarget { - project.plugins.apply(JavaPlugin::class.java) - - val target = KotlinWithJavaTarget(project, KotlinPlatformType.jvm, name).apply { - disambiguationClassifier = name - preset = this@KotlinJvmWithJavaTargetPreset - } - - AbstractKotlinPlugin.configureTarget(target) { compilation -> - Kotlin2JvmSourceSetProcessor(project, KotlinTasksProvider(name), compilation, kotlinPluginVersion) - } - - target.compilations.getByName("test").run { - val main = target.compilations.getByName(KotlinCompilation.MAIN_COMPILATION_NAME) - - compileDependencyFiles = project.files( - main.output.allOutputs, - project.configurations.maybeCreate(compileDependencyConfigurationName) - ) - runtimeDependencyFiles = project.files( - output.allOutputs, - main.output.allOutputs, - project.configurations.maybeCreate(runtimeDependencyConfigurationName) - ) - } - - return target - } - - companion object { - const val PRESET_NAME = "jvmWithJava" - } -} - -class KotlinNativeTargetPreset( - private val name: String, - val project: Project, - val konanTarget: KonanTarget, - private val kotlinPluginVersion: String -) : KotlinTargetPreset { - - init { - // This is required to obtain Kotlin/Native home in CLion plugin: - setupNativeHomePrivateProperty() - } - - override fun getName(): String = name - - private fun setupNativeHomePrivateProperty() = with(project) { - if (!hasProperty(KOTLIN_NATIVE_HOME_PRIVATE_PROPERTY)) - extensions.extraProperties.set(KOTLIN_NATIVE_HOME_PRIVATE_PROPERTY, konanHome) - } - - private fun setupNativeCompiler() = with(project) { - if (!hasProperty(KotlinNativeProjectProperty.KONAN_HOME_OVERRIDE)) { - NativeCompilerDownloader(this).downloadIfNeeded() - logger.info("Kotlin/Native distribution: $konanHome") - } else { - logger.info("User-provided Kotlin/Native distribution: $konanHome") - } - } - - // We declare default K/N dependencies as files to avoid searching them in remote repos (see KT-28128). - private fun defaultLibs(target: KonanTarget? = null): List = with(project) { - - val relPath = if (target != null) "platform/${target.name}" else "common" - - file("$konanHome/klib/$relPath") - .listFiles { file -> file.isDirectory } - ?.sortedBy { dir -> dir.name.toLowerCase() } - ?.map { dir -> dependencies.create(files(dir)) } ?: emptyList() - } - - override fun createTarget(name: String): KotlinNativeTarget { - setupNativeCompiler() - - val result = KotlinNativeTarget(project, konanTarget).apply { - targetName = name - disambiguationClassifier = name - preset = this@KotlinNativeTargetPreset - - val compilationFactory = KotlinNativeCompilationFactory(project, this) - compilations = project.container(compilationFactory.itemClass, compilationFactory) - } - - KotlinNativeTargetConfigurator(kotlinPluginVersion).configureTarget(result) - - // Allow IDE to resolve the libraries provided by the compiler by adding them into dependencies. - result.compilations.all { compilation -> - val target = compilation.target.konanTarget - // First, put common libs: - defaultLibs().forEach { - project.dependencies.add(compilation.compileDependencyConfigurationName, it) - } - // Then, platform-specific libs: - defaultLibs(target).forEach { - project.dependencies.add(compilation.compileDependencyConfigurationName, it) - } - } - - if (!konanTarget.enabledOnCurrentHost) { - with(HostManager()) { - val supportedHosts = enabledTargetsByHost.filterValues { konanTarget in it }.keys - val supportedHostsString = - if (supportedHosts.size == 1) - "a ${supportedHosts.single()} host" else - "one of the host platforms: ${supportedHosts.joinToString(", ")}" - project.logger.warn( - "Target '$name' for platform ${konanTarget} is ignored during build on this ${HostManager.host} machine. " + - "You can build it with $supportedHostsString." - ) - } - } - - return result - } - - companion object { - private const val KOTLIN_NATIVE_HOME_PRIVATE_PROPERTY = "konanHome" - } -} - -internal val KonanTarget.isCurrentHost: Boolean - get() = this == HostManager.host - -internal val KonanTarget.enabledOnCurrentHost - get() = HostManager().isEnabled(this) - -internal val KotlinNativeCompilation.isMainCompilation: Boolean - get() = name == KotlinCompilation.MAIN_COMPILATION_NAME diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinJvmAndroidCompilation.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinJvmAndroidCompilation.kt index 1284fe446f3..8046b7bfaa3 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinJvmAndroidCompilation.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinJvmAndroidCompilation.kt @@ -5,265 +5,7 @@ package org.jetbrains.kotlin.gradle.plugin.mpp -import groovy.lang.Closure -import org.gradle.api.Action -import org.gradle.api.NamedDomainObjectContainer -import org.gradle.api.Project -import org.gradle.api.attributes.AttributeContainer -import org.gradle.api.file.FileCollection -import org.gradle.api.file.SourceDirectorySet -import org.gradle.api.tasks.SourceSet -import org.gradle.util.ConfigureUtil -import org.jetbrains.kotlin.gradle.dsl.* -import org.jetbrains.kotlin.gradle.dsl.KotlinCompile -import org.jetbrains.kotlin.gradle.plugin.* -import org.jetbrains.kotlin.gradle.plugin.sources.defaultSourceSetLanguageSettingsChecker -import org.jetbrains.kotlin.gradle.plugin.sources.getSourceSetHierarchy -import org.jetbrains.kotlin.gradle.tasks.* -import org.jetbrains.kotlin.gradle.utils.addExtendsFromRelation -import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName -import java.io.File -import java.util.* -import java.util.concurrent.Callable - -internal fun KotlinCompilation<*>.composeName(prefix: String? = null, suffix: String? = null): String { - val compilationNamePart = compilationName.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME } - val targetNamePart = target.disambiguationClassifier - - return lowerCamelCaseName(prefix, targetNamePart, compilationNamePart, suffix) -} - -internal val KotlinCompilation<*>.defaultSourceSetName: String - get() = lowerCamelCaseName(target.disambiguationClassifier, compilationName) - -abstract class AbstractKotlinCompilation( - target: KotlinTarget, - override val compilationName: String -) : KotlinCompilation, HasKotlinDependencies { - - override val kotlinOptions: T - get() = compileKotlinTask.kotlinOptions - - override fun kotlinOptions(configure: T.() -> Unit) = - configure(kotlinOptions) - - @Suppress("UNCHECKED_CAST") - override val compileKotlinTask: KotlinCompile - get() = (target.project.tasks.getByName(compileKotlinTaskName) as KotlinCompile) - - // Don't declare this property in the constructor to avoid NPE - // when an overriding property of a subclass is accessed instead. - override val target: KotlinTarget = target - - private val attributeContainer = HierarchyAttributeContainer(target.attributes) - - override fun getAttributes(): AttributeContainer = attributeContainer - - override val kotlinSourceSets: MutableSet = mutableSetOf() - - override val allKotlinSourceSets: Set - get() = kotlinSourceSets.flatMapTo(mutableSetOf()) { it.getSourceSetHierarchy() } - - override val defaultSourceSet: KotlinSourceSet - get() = target.project.kotlinExtension.sourceSets.getByName(defaultSourceSetName) - - override fun defaultSourceSet(configure: KotlinSourceSet.() -> Unit) = - configure(defaultSourceSet) - - override val output: KotlinCompilationOutput by lazy { - DefaultKotlinCompilationOutput( - target.project, - Callable { target.project.buildDir.resolve("processedResources/${target.targetName}/$name") }) - } - - open fun addSourcesToCompileTask(sourceSet: KotlinSourceSet, addAsCommonSources: Boolean) { - fun AbstractKotlinCompile<*>.configureAction() { - source(sourceSet.kotlin) - sourceFilesExtensions(sourceSet.customSourceFilesExtensions) - if (addAsCommonSources) { - commonSourceSet += sourceSet.kotlin - } - } - - // Note! Invocation of withType-all results in preliminary task instantiation. - // After fix of this issue the following code should be uncommented: -// if (useLazyTaskConfiguration) { -// (target.project.tasks.named(compileKotlinTaskName) as TaskProvider>).configure { -// it.configureAction() -// } -// } - - target.project.tasks - // 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 -> - compileKotlinTask.configureAction() - } - } - - override fun source(sourceSet: KotlinSourceSet) { - if (kotlinSourceSets.add(sourceSet)) { - //TODO possibly issue with forced instantiation - target.project.whenEvaluated { - sourceSet.getSourceSetHierarchy().forEach { sourceSet -> - val isCommonSource = - CompilationSourceSetUtil.sourceSetsInMultipleCompilations(project)?.contains(sourceSet) ?: false - - addSourcesToCompileTask(sourceSet, addAsCommonSources = isCommonSource) - - // Use `forced = false` since `api`, `implementation`, and `compileOnly` may be missing in some cases like - // old Java & Android projects: - addExtendsFromRelation(apiConfigurationName, sourceSet.apiConfigurationName, forced = false) - addExtendsFromRelation(implementationConfigurationName, sourceSet.implementationConfigurationName, forced = false) - addExtendsFromRelation(compileOnlyConfigurationName, sourceSet.compileOnlyConfigurationName, forced = false) - - if (this@AbstractKotlinCompilation is KotlinCompilationToRunnableFiles<*>) { - addExtendsFromRelation(runtimeOnlyConfigurationName, sourceSet.runtimeOnlyConfigurationName, forced = false) - } - - if (sourceSet.name != defaultSourceSetName) { - kotlinExtension.sourceSets.findByName(defaultSourceSetName)?.let { defaultSourceSet -> - // Temporary solution for checking consistency across source sets participating in a compilation that may - // not be interconnected with the dependsOn relation: check the settings as if the default source set of - // the compilation depends on the one added to the compilation: - defaultSourceSetLanguageSettingsChecker.runAllChecks( - defaultSourceSet, - sourceSet - ) - } - } - } - } - } - } - - override val compileDependencyConfigurationName: String - get() = lowerCamelCaseName( - target.disambiguationClassifier, - compilationName.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME }.orEmpty(), - "compileClasspath" - ) - - override val compileKotlinTaskName: String - get() = lowerCamelCaseName( - "compile", - compilationName.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME }, - "Kotlin", - target.targetName - ) - - override val compileAllTaskName: String - get() = lowerCamelCaseName(target.disambiguationClassifier, compilationName, "classes") - - override lateinit var compileDependencyFiles: FileCollection - - override val apiConfigurationName: String - get() = disambiguateName("api") - - override val implementationConfigurationName: String - get() = disambiguateName("implementation") - - override val compileOnlyConfigurationName: String - get() = disambiguateName("compileOnly") - - override val runtimeOnlyConfigurationName: String - get() = disambiguateName("runtimeOnly") - - override fun dependencies(configure: KotlinDependencyHandler.() -> Unit): Unit = - DefaultKotlinDependencyHandler(this, target.project).run(configure) - - override fun dependencies(configureClosure: Closure) = - dependencies f@{ ConfigureUtil.configure(configureClosure, this@f) } - - override fun toString(): String = "compilation '$compilationName' ($target)" -} - -abstract class AbstractKotlinCompilationToRunnableFiles( - target: KotlinTarget, - name: String -) : AbstractKotlinCompilation(target, name), KotlinCompilationToRunnableFiles { - override val runtimeDependencyConfigurationName: String - get() = lowerCamelCaseName( - target.disambiguationClassifier, - compilationName.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME }, - "runtimeClasspath" - ) - - override lateinit var runtimeDependencyFiles: FileCollection -} - -internal fun KotlinCompilation<*>.disambiguateName(simpleName: String): String { - return lowerCamelCaseName( - target.disambiguationClassifier, - compilationName.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME }, - simpleName - ) -} - -open class KotlinJvmCompilation( - target: KotlinTarget, - name: String -) : AbstractKotlinCompilationToRunnableFiles(target, name), KotlinCompilationWithResources { - override val processResourcesTaskName: String - get() = disambiguateName("processResources") - - override val compileKotlinTask: org.jetbrains.kotlin.gradle.tasks.KotlinCompile - get() = super.compileKotlinTask as org.jetbrains.kotlin.gradle.tasks.KotlinCompile -} - -class KotlinWithJavaCompilation( - target: KotlinWithJavaTarget, - name: String -) : AbstractKotlinCompilationToRunnableFiles(target, name), KotlinCompilationWithResources { - lateinit var javaSourceSet: SourceSet - - override val output: KotlinCompilationOutput by lazy { KotlinWithJavaCompilationOutput(this) } - - override val processResourcesTaskName: String - get() = javaSourceSet.processResourcesTaskName - - override var runtimeDependencyFiles: FileCollection - get() = javaSourceSet.runtimeClasspath - set(value) { - javaSourceSet.runtimeClasspath = value - } - - override val runtimeDependencyConfigurationName: String - get() = javaSourceSet.runtimeClasspathConfigurationName - - override val compileDependencyConfigurationName: String - get() = javaSourceSet.compileClasspathConfigurationName - - override val runtimeOnlyConfigurationName: String - get() = javaSourceSet.runtimeOnlyConfigurationName - - override val implementationConfigurationName: String - get() = javaSourceSet.implementationConfigurationName - - override val apiConfigurationName: String - get() = javaSourceSet.apiConfigurationName - - override val compileOnlyConfigurationName: String - get() = javaSourceSet.compileOnlyConfigurationName - - override val compileAllTaskName: String - get() = javaSourceSet.classesTaskName - - override var compileDependencyFiles: FileCollection - get() = javaSourceSet.compileClasspath - set(value) { - javaSourceSet.compileClasspath = value - } - - fun source(javaSourceSet: SourceSet) { - with(target.project) { - afterEvaluate { - (tasks.getByName(compileKotlinTaskName) as AbstractKotlinCompile<*>).source(javaSourceSet.java) - } - } - } -} +import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptions class KotlinJvmAndroidCompilation( target: KotlinAndroidTarget, @@ -274,198 +16,4 @@ class KotlinJvmAndroidCompilation( override val relatedConfigurationNames: List get() = super.relatedConfigurationNames + listOf("${name}ApiElements", "${name}RuntimeElements") -} - -class KotlinJsCompilation( - target: KotlinTarget, - name: String -) : AbstractKotlinCompilationToRunnableFiles(target, name), KotlinCompilationWithResources { - override val processResourcesTaskName: String - get() = disambiguateName("processResources") - - override val compileKotlinTask: Kotlin2JsCompile - get() = super.compileKotlinTask as Kotlin2JsCompile -} - -class KotlinCommonCompilation( - target: KotlinTarget, - name: String -) : AbstractKotlinCompilation(target, name) { - override val compileKotlinTask: KotlinCompileCommon - get() = super.compileKotlinTask as KotlinCompileCommon - - // TODO once we properly compile metadata for each source set, the default source sets will likely become just the source sets - // which are transformed to metadata - private val commonSourceSetName = when (compilationName) { - KotlinCompilation.MAIN_COMPILATION_NAME -> KotlinSourceSet.COMMON_MAIN_SOURCE_SET_NAME - else -> error("Custom metadata compilations are not supported yet") - } - - override val defaultSourceSet: KotlinSourceSet - get() = target.project.kotlinExtension.sourceSets.getByName(commonSourceSetName) -} - -class KotlinNativeCompilation( - override val target: KotlinNativeTarget, - name: String -) : AbstractKotlinCompilation(target, name), KotlinCompilationWithResources { - - override val kotlinOptions: KotlinCommonOptions - get() = compileKotlinTask.kotlinOptions - - override val compileKotlinTask: KotlinNativeCompile - get() = super.compileKotlinTask as KotlinNativeCompile - - private val project: Project - get() = target.project - - // A collection containing all source sets used by this compilation - // (taking into account dependencies between source sets). Used by both compilation - // and linking tasks. Unlike kotlinSourceSets, includes dependency source sets. - // TODO: Move into the compilation task when the linking task does klib linking instead of compilation. - internal val allSources: MutableSet = mutableSetOf() - - // TODO: Move into the compilation task when the linking task does klib linking instead of compilation. - internal val commonSources: MutableSet = mutableSetOf() - - var isTestCompilation = false - - var friendCompilationName: String? = null - - internal val friendCompilation: KotlinNativeCompilation? - get() = friendCompilationName?.let { - target.compilations.getByName(it) - } - - // Used only to support the old APIs. TODO: Remove when the old APIs are removed. - internal val binaries = mutableMapOf, NativeBinary>() - - // Native-specific DSL. - var extraOpts = mutableListOf() - - fun extraOpts(vararg values: Any) = extraOpts(values.toList()) - fun extraOpts(values: List) { - extraOpts.addAll(values.map { it.toString() }) - } - - var buildTypes = mutableListOf() - var outputKinds = mutableListOf() - - fun outputKind(kind: NativeOutputKind) = outputKinds.add(kind) - - fun outputKinds(vararg kinds: NativeOutputKind) { - outputKinds = kinds.toMutableList() - } - - fun outputKinds(vararg kinds: String) { - outputKinds = kinds.map { NativeOutputKind.valueOf(it.toUpperCase()) }.toMutableList() - } - - fun outputKinds(kinds: List) { - outputKinds = kinds.map { - when (it) { - is NativeOutputKind -> it - is String -> NativeOutputKind.valueOf(it.toUpperCase()) - else -> error("Cannot use $it as an output kind") - } - }.toMutableList() - } - - var entryPoint: String? = null - fun entryPoint(value: String) { - entryPoint = value - } - - // Interop DSL. - val cinterops = project.container(DefaultCInteropSettings::class.java) { cinteropName -> - DefaultCInteropSettings(project, cinteropName, this) - } - - var linkerOpts = mutableListOf() - - fun cinterops(action: NamedDomainObjectContainer.() -> Unit) = cinterops.action() - fun cinterops(action: Closure) = cinterops(ConfigureUtil.configureUsing(action)) - fun cinterops(action: Action>) = action.execute(cinterops) - - fun linkerOpts(vararg values: String) = linkerOpts(values.toList()) - fun linkerOpts(values: List) { - linkerOpts.addAll(values) - } - - // Task accessors. - fun findLinkTask(kind: NativeOutputKind, buildType: NativeBuildType): KotlinNativeLink? = binaries[kind to buildType]?.linkTask - - fun getLinkTask(kind: NativeOutputKind, buildType: NativeBuildType): KotlinNativeLink = - findLinkTask(kind, buildType) - ?: throw IllegalArgumentException("Cannot find a link task for the binary kind '$kind' and the build type '$buildType'") - - fun findLinkTask(kind: String, buildType: String) = - findLinkTask(NativeOutputKind.valueOf(kind.toUpperCase()), NativeBuildType.valueOf(buildType.toUpperCase())) - - fun getLinkTask(kind: String, buildType: String) = - getLinkTask(NativeOutputKind.valueOf(kind.toUpperCase()), NativeBuildType.valueOf(buildType.toUpperCase())) - - fun findBinary(kind: NativeOutputKind, buildType: NativeBuildType): File? = findLinkTask(kind, buildType)?.outputFile?.get() - - fun getBinary(kind: NativeOutputKind, buildType: NativeBuildType): File = getLinkTask(kind, buildType).outputFile.get() - - fun findBinary(kind: String, buildType: String) = - findBinary(NativeOutputKind.valueOf(kind.toUpperCase()), NativeBuildType.valueOf(buildType.toUpperCase())) - - fun getBinary(kind: String, buildType: String) = - getBinary(NativeOutputKind.valueOf(kind.toUpperCase()), NativeBuildType.valueOf(buildType.toUpperCase())) - - // Naming - override val processResourcesTaskName: String - get() = disambiguateName("processResources") - - fun linkTaskName(kind: NativeOutputKind, buildType: NativeBuildType): String = - lowerCamelCaseName( - "link", - KotlinNativeBinaryContainer.generateBinaryName(compilationName, buildType, kind.taskNameClassifier), - target.targetName - ) - - fun linkTaskName(kind: String, buildType: String) = - linkTaskName(NativeOutputKind.valueOf(kind.toUpperCase()), NativeBuildType.valueOf(buildType.toUpperCase())) - - override val compileDependencyConfigurationName: String - get() = lowerCamelCaseName( - target.disambiguationClassifier, - compilationName.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME }.orEmpty(), - "compileKlibraries" - ) - - override val compileAllTaskName: String - get() = lowerCamelCaseName(target.disambiguationClassifier, compilationName, "klibrary") - - val binariesTaskName: String - get() = lowerCamelCaseName(target.disambiguationClassifier, compilationName, "binaries") - - override fun addSourcesToCompileTask(sourceSet: KotlinSourceSet, addAsCommonSources: Boolean) { - allSources.add(sourceSet.kotlin) - if (addAsCommonSources) { - commonSources.add(sourceSet.kotlin) - } - } -} - -private object CompilationSourceSetUtil { - // Cache the results per project - private val projectSourceSetsInMultipleCompilationsCache = WeakHashMap>() - - fun sourceSetsInMultipleCompilations(project: Project) = - projectSourceSetsInMultipleCompilationsCache.computeIfAbsent(project) { _ -> - check(project.state.executed) { "Should only be computed after the project is evaluated" } - - val compilations = (project.kotlinExtension as? KotlinMultiplatformExtension)?.targets?.flatMap { it.compilations } - ?: return@computeIfAbsent null - - compilations - .flatMap { compilation -> compilation.allKotlinSourceSets.map { sourceSet -> compilation to sourceSet } } - .groupingBy { (_, sourceSet) -> sourceSet } - .eachCount() - .filterValues { it > 1 } - .keys - } } \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinJvmAndroidCompilationFactory.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinJvmAndroidCompilationFactory.kt index e63b6e6573d..3154204e1d0 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinJvmAndroidCompilationFactory.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinJvmAndroidCompilationFactory.kt @@ -6,49 +6,7 @@ package org.jetbrains.kotlin.gradle.plugin.mpp -import org.gradle.api.NamedDomainObjectFactory import org.gradle.api.Project -import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions -import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation - -interface KotlinCompilationFactory> : NamedDomainObjectFactory { - val itemClass: Class -} - -class KotlinCommonCompilationFactory( - val target: KotlinOnlyTarget -) : KotlinCompilationFactory { - override val itemClass: Class - get() = KotlinCommonCompilation::class.java - - override fun create(name: String): KotlinCommonCompilation = - KotlinCommonCompilation(target, name) -} - -class KotlinJvmCompilationFactory( - val target: KotlinOnlyTarget -) : KotlinCompilationFactory { - override val itemClass: Class - get() = KotlinJvmCompilation::class.java - - override fun create(name: String): KotlinJvmCompilation = - KotlinJvmCompilation(target, name) -} - -class KotlinWithJavaCompilationFactory( - val project: Project, - val target: KotlinWithJavaTarget -) : KotlinCompilationFactory> { - - override val itemClass: Class> - @Suppress("UNCHECKED_CAST") - get() = KotlinWithJavaCompilation::class.java as Class> - - override fun create(name: String): KotlinWithJavaCompilation { - val result = KotlinWithJavaCompilation(target, name) - return result - } -} class KotlinJvmAndroidCompilationFactory( val project: Project, @@ -60,34 +18,4 @@ class KotlinJvmAndroidCompilationFactory( override fun create(name: String): KotlinJvmAndroidCompilation = KotlinJvmAndroidCompilation(target, name) -} - -class KotlinJsCompilationFactory( - val project: Project, - val target: KotlinOnlyTarget -) : KotlinCompilationFactory { - override val itemClass: Class - get() = KotlinJsCompilation::class.java - - override fun create(name: String): KotlinJsCompilation = - KotlinJsCompilation(target, name) -} - -class KotlinNativeCompilationFactory( - val project: Project, - val target: KotlinNativeTarget -) : KotlinCompilationFactory { - - override val itemClass: Class - get() = KotlinNativeCompilation::class.java - - override fun create(name: String): KotlinNativeCompilation = - KotlinNativeCompilation(target, name).apply { - if (name == KotlinCompilation.TEST_COMPILATION_NAME) { - friendCompilationName = KotlinCompilation.MAIN_COMPILATION_NAME - isTestCompilation = true - } - buildTypes = mutableListOf(NativeBuildType.DEBUG, NativeBuildType.RELEASE) - } - } \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinJvmCompilation.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinJvmCompilation.kt index 1284fe446f3..e21e0623087 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinJvmCompilation.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinJvmCompilation.kt @@ -5,201 +5,9 @@ package org.jetbrains.kotlin.gradle.plugin.mpp -import groovy.lang.Closure -import org.gradle.api.Action -import org.gradle.api.NamedDomainObjectContainer -import org.gradle.api.Project -import org.gradle.api.attributes.AttributeContainer -import org.gradle.api.file.FileCollection -import org.gradle.api.file.SourceDirectorySet -import org.gradle.api.tasks.SourceSet -import org.gradle.util.ConfigureUtil -import org.jetbrains.kotlin.gradle.dsl.* -import org.jetbrains.kotlin.gradle.dsl.KotlinCompile -import org.jetbrains.kotlin.gradle.plugin.* -import org.jetbrains.kotlin.gradle.plugin.sources.defaultSourceSetLanguageSettingsChecker -import org.jetbrains.kotlin.gradle.plugin.sources.getSourceSetHierarchy -import org.jetbrains.kotlin.gradle.tasks.* -import org.jetbrains.kotlin.gradle.utils.addExtendsFromRelation -import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName -import java.io.File -import java.util.* -import java.util.concurrent.Callable - -internal fun KotlinCompilation<*>.composeName(prefix: String? = null, suffix: String? = null): String { - val compilationNamePart = compilationName.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME } - val targetNamePart = target.disambiguationClassifier - - return lowerCamelCaseName(prefix, targetNamePart, compilationNamePart, suffix) -} - -internal val KotlinCompilation<*>.defaultSourceSetName: String - get() = lowerCamelCaseName(target.disambiguationClassifier, compilationName) - -abstract class AbstractKotlinCompilation( - target: KotlinTarget, - override val compilationName: String -) : KotlinCompilation, HasKotlinDependencies { - - override val kotlinOptions: T - get() = compileKotlinTask.kotlinOptions - - override fun kotlinOptions(configure: T.() -> Unit) = - configure(kotlinOptions) - - @Suppress("UNCHECKED_CAST") - override val compileKotlinTask: KotlinCompile - get() = (target.project.tasks.getByName(compileKotlinTaskName) as KotlinCompile) - - // Don't declare this property in the constructor to avoid NPE - // when an overriding property of a subclass is accessed instead. - override val target: KotlinTarget = target - - private val attributeContainer = HierarchyAttributeContainer(target.attributes) - - override fun getAttributes(): AttributeContainer = attributeContainer - - override val kotlinSourceSets: MutableSet = mutableSetOf() - - override val allKotlinSourceSets: Set - get() = kotlinSourceSets.flatMapTo(mutableSetOf()) { it.getSourceSetHierarchy() } - - override val defaultSourceSet: KotlinSourceSet - get() = target.project.kotlinExtension.sourceSets.getByName(defaultSourceSetName) - - override fun defaultSourceSet(configure: KotlinSourceSet.() -> Unit) = - configure(defaultSourceSet) - - override val output: KotlinCompilationOutput by lazy { - DefaultKotlinCompilationOutput( - target.project, - Callable { target.project.buildDir.resolve("processedResources/${target.targetName}/$name") }) - } - - open fun addSourcesToCompileTask(sourceSet: KotlinSourceSet, addAsCommonSources: Boolean) { - fun AbstractKotlinCompile<*>.configureAction() { - source(sourceSet.kotlin) - sourceFilesExtensions(sourceSet.customSourceFilesExtensions) - if (addAsCommonSources) { - commonSourceSet += sourceSet.kotlin - } - } - - // Note! Invocation of withType-all results in preliminary task instantiation. - // After fix of this issue the following code should be uncommented: -// if (useLazyTaskConfiguration) { -// (target.project.tasks.named(compileKotlinTaskName) as TaskProvider>).configure { -// it.configureAction() -// } -// } - - target.project.tasks - // 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 -> - compileKotlinTask.configureAction() - } - } - - override fun source(sourceSet: KotlinSourceSet) { - if (kotlinSourceSets.add(sourceSet)) { - //TODO possibly issue with forced instantiation - target.project.whenEvaluated { - sourceSet.getSourceSetHierarchy().forEach { sourceSet -> - val isCommonSource = - CompilationSourceSetUtil.sourceSetsInMultipleCompilations(project)?.contains(sourceSet) ?: false - - addSourcesToCompileTask(sourceSet, addAsCommonSources = isCommonSource) - - // Use `forced = false` since `api`, `implementation`, and `compileOnly` may be missing in some cases like - // old Java & Android projects: - addExtendsFromRelation(apiConfigurationName, sourceSet.apiConfigurationName, forced = false) - addExtendsFromRelation(implementationConfigurationName, sourceSet.implementationConfigurationName, forced = false) - addExtendsFromRelation(compileOnlyConfigurationName, sourceSet.compileOnlyConfigurationName, forced = false) - - if (this@AbstractKotlinCompilation is KotlinCompilationToRunnableFiles<*>) { - addExtendsFromRelation(runtimeOnlyConfigurationName, sourceSet.runtimeOnlyConfigurationName, forced = false) - } - - if (sourceSet.name != defaultSourceSetName) { - kotlinExtension.sourceSets.findByName(defaultSourceSetName)?.let { defaultSourceSet -> - // Temporary solution for checking consistency across source sets participating in a compilation that may - // not be interconnected with the dependsOn relation: check the settings as if the default source set of - // the compilation depends on the one added to the compilation: - defaultSourceSetLanguageSettingsChecker.runAllChecks( - defaultSourceSet, - sourceSet - ) - } - } - } - } - } - } - - override val compileDependencyConfigurationName: String - get() = lowerCamelCaseName( - target.disambiguationClassifier, - compilationName.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME }.orEmpty(), - "compileClasspath" - ) - - override val compileKotlinTaskName: String - get() = lowerCamelCaseName( - "compile", - compilationName.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME }, - "Kotlin", - target.targetName - ) - - override val compileAllTaskName: String - get() = lowerCamelCaseName(target.disambiguationClassifier, compilationName, "classes") - - override lateinit var compileDependencyFiles: FileCollection - - override val apiConfigurationName: String - get() = disambiguateName("api") - - override val implementationConfigurationName: String - get() = disambiguateName("implementation") - - override val compileOnlyConfigurationName: String - get() = disambiguateName("compileOnly") - - override val runtimeOnlyConfigurationName: String - get() = disambiguateName("runtimeOnly") - - override fun dependencies(configure: KotlinDependencyHandler.() -> Unit): Unit = - DefaultKotlinDependencyHandler(this, target.project).run(configure) - - override fun dependencies(configureClosure: Closure) = - dependencies f@{ ConfigureUtil.configure(configureClosure, this@f) } - - override fun toString(): String = "compilation '$compilationName' ($target)" -} - -abstract class AbstractKotlinCompilationToRunnableFiles( - target: KotlinTarget, - name: String -) : AbstractKotlinCompilation(target, name), KotlinCompilationToRunnableFiles { - override val runtimeDependencyConfigurationName: String - get() = lowerCamelCaseName( - target.disambiguationClassifier, - compilationName.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME }, - "runtimeClasspath" - ) - - override lateinit var runtimeDependencyFiles: FileCollection -} - -internal fun KotlinCompilation<*>.disambiguateName(simpleName: String): String { - return lowerCamelCaseName( - target.disambiguationClassifier, - compilationName.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME }, - simpleName - ) -} +import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptions +import org.jetbrains.kotlin.gradle.plugin.KotlinCompilationWithResources +import org.jetbrains.kotlin.gradle.plugin.KotlinTarget open class KotlinJvmCompilation( target: KotlinTarget, @@ -210,262 +18,4 @@ open class KotlinJvmCompilation( override val compileKotlinTask: org.jetbrains.kotlin.gradle.tasks.KotlinCompile get() = super.compileKotlinTask as org.jetbrains.kotlin.gradle.tasks.KotlinCompile -} - -class KotlinWithJavaCompilation( - target: KotlinWithJavaTarget, - name: String -) : AbstractKotlinCompilationToRunnableFiles(target, name), KotlinCompilationWithResources { - lateinit var javaSourceSet: SourceSet - - override val output: KotlinCompilationOutput by lazy { KotlinWithJavaCompilationOutput(this) } - - override val processResourcesTaskName: String - get() = javaSourceSet.processResourcesTaskName - - override var runtimeDependencyFiles: FileCollection - get() = javaSourceSet.runtimeClasspath - set(value) { - javaSourceSet.runtimeClasspath = value - } - - override val runtimeDependencyConfigurationName: String - get() = javaSourceSet.runtimeClasspathConfigurationName - - override val compileDependencyConfigurationName: String - get() = javaSourceSet.compileClasspathConfigurationName - - override val runtimeOnlyConfigurationName: String - get() = javaSourceSet.runtimeOnlyConfigurationName - - override val implementationConfigurationName: String - get() = javaSourceSet.implementationConfigurationName - - override val apiConfigurationName: String - get() = javaSourceSet.apiConfigurationName - - override val compileOnlyConfigurationName: String - get() = javaSourceSet.compileOnlyConfigurationName - - override val compileAllTaskName: String - get() = javaSourceSet.classesTaskName - - override var compileDependencyFiles: FileCollection - get() = javaSourceSet.compileClasspath - set(value) { - javaSourceSet.compileClasspath = value - } - - fun source(javaSourceSet: SourceSet) { - with(target.project) { - afterEvaluate { - (tasks.getByName(compileKotlinTaskName) as AbstractKotlinCompile<*>).source(javaSourceSet.java) - } - } - } -} - -class KotlinJvmAndroidCompilation( - target: KotlinAndroidTarget, - name: String -) : AbstractKotlinCompilationToRunnableFiles(target, name) { - override val compileKotlinTask: org.jetbrains.kotlin.gradle.tasks.KotlinCompile - get() = super.compileKotlinTask as org.jetbrains.kotlin.gradle.tasks.KotlinCompile - - override val relatedConfigurationNames: List - get() = super.relatedConfigurationNames + listOf("${name}ApiElements", "${name}RuntimeElements") -} - -class KotlinJsCompilation( - target: KotlinTarget, - name: String -) : AbstractKotlinCompilationToRunnableFiles(target, name), KotlinCompilationWithResources { - override val processResourcesTaskName: String - get() = disambiguateName("processResources") - - override val compileKotlinTask: Kotlin2JsCompile - get() = super.compileKotlinTask as Kotlin2JsCompile -} - -class KotlinCommonCompilation( - target: KotlinTarget, - name: String -) : AbstractKotlinCompilation(target, name) { - override val compileKotlinTask: KotlinCompileCommon - get() = super.compileKotlinTask as KotlinCompileCommon - - // TODO once we properly compile metadata for each source set, the default source sets will likely become just the source sets - // which are transformed to metadata - private val commonSourceSetName = when (compilationName) { - KotlinCompilation.MAIN_COMPILATION_NAME -> KotlinSourceSet.COMMON_MAIN_SOURCE_SET_NAME - else -> error("Custom metadata compilations are not supported yet") - } - - override val defaultSourceSet: KotlinSourceSet - get() = target.project.kotlinExtension.sourceSets.getByName(commonSourceSetName) -} - -class KotlinNativeCompilation( - override val target: KotlinNativeTarget, - name: String -) : AbstractKotlinCompilation(target, name), KotlinCompilationWithResources { - - override val kotlinOptions: KotlinCommonOptions - get() = compileKotlinTask.kotlinOptions - - override val compileKotlinTask: KotlinNativeCompile - get() = super.compileKotlinTask as KotlinNativeCompile - - private val project: Project - get() = target.project - - // A collection containing all source sets used by this compilation - // (taking into account dependencies between source sets). Used by both compilation - // and linking tasks. Unlike kotlinSourceSets, includes dependency source sets. - // TODO: Move into the compilation task when the linking task does klib linking instead of compilation. - internal val allSources: MutableSet = mutableSetOf() - - // TODO: Move into the compilation task when the linking task does klib linking instead of compilation. - internal val commonSources: MutableSet = mutableSetOf() - - var isTestCompilation = false - - var friendCompilationName: String? = null - - internal val friendCompilation: KotlinNativeCompilation? - get() = friendCompilationName?.let { - target.compilations.getByName(it) - } - - // Used only to support the old APIs. TODO: Remove when the old APIs are removed. - internal val binaries = mutableMapOf, NativeBinary>() - - // Native-specific DSL. - var extraOpts = mutableListOf() - - fun extraOpts(vararg values: Any) = extraOpts(values.toList()) - fun extraOpts(values: List) { - extraOpts.addAll(values.map { it.toString() }) - } - - var buildTypes = mutableListOf() - var outputKinds = mutableListOf() - - fun outputKind(kind: NativeOutputKind) = outputKinds.add(kind) - - fun outputKinds(vararg kinds: NativeOutputKind) { - outputKinds = kinds.toMutableList() - } - - fun outputKinds(vararg kinds: String) { - outputKinds = kinds.map { NativeOutputKind.valueOf(it.toUpperCase()) }.toMutableList() - } - - fun outputKinds(kinds: List) { - outputKinds = kinds.map { - when (it) { - is NativeOutputKind -> it - is String -> NativeOutputKind.valueOf(it.toUpperCase()) - else -> error("Cannot use $it as an output kind") - } - }.toMutableList() - } - - var entryPoint: String? = null - fun entryPoint(value: String) { - entryPoint = value - } - - // Interop DSL. - val cinterops = project.container(DefaultCInteropSettings::class.java) { cinteropName -> - DefaultCInteropSettings(project, cinteropName, this) - } - - var linkerOpts = mutableListOf() - - fun cinterops(action: NamedDomainObjectContainer.() -> Unit) = cinterops.action() - fun cinterops(action: Closure) = cinterops(ConfigureUtil.configureUsing(action)) - fun cinterops(action: Action>) = action.execute(cinterops) - - fun linkerOpts(vararg values: String) = linkerOpts(values.toList()) - fun linkerOpts(values: List) { - linkerOpts.addAll(values) - } - - // Task accessors. - fun findLinkTask(kind: NativeOutputKind, buildType: NativeBuildType): KotlinNativeLink? = binaries[kind to buildType]?.linkTask - - fun getLinkTask(kind: NativeOutputKind, buildType: NativeBuildType): KotlinNativeLink = - findLinkTask(kind, buildType) - ?: throw IllegalArgumentException("Cannot find a link task for the binary kind '$kind' and the build type '$buildType'") - - fun findLinkTask(kind: String, buildType: String) = - findLinkTask(NativeOutputKind.valueOf(kind.toUpperCase()), NativeBuildType.valueOf(buildType.toUpperCase())) - - fun getLinkTask(kind: String, buildType: String) = - getLinkTask(NativeOutputKind.valueOf(kind.toUpperCase()), NativeBuildType.valueOf(buildType.toUpperCase())) - - fun findBinary(kind: NativeOutputKind, buildType: NativeBuildType): File? = findLinkTask(kind, buildType)?.outputFile?.get() - - fun getBinary(kind: NativeOutputKind, buildType: NativeBuildType): File = getLinkTask(kind, buildType).outputFile.get() - - fun findBinary(kind: String, buildType: String) = - findBinary(NativeOutputKind.valueOf(kind.toUpperCase()), NativeBuildType.valueOf(buildType.toUpperCase())) - - fun getBinary(kind: String, buildType: String) = - getBinary(NativeOutputKind.valueOf(kind.toUpperCase()), NativeBuildType.valueOf(buildType.toUpperCase())) - - // Naming - override val processResourcesTaskName: String - get() = disambiguateName("processResources") - - fun linkTaskName(kind: NativeOutputKind, buildType: NativeBuildType): String = - lowerCamelCaseName( - "link", - KotlinNativeBinaryContainer.generateBinaryName(compilationName, buildType, kind.taskNameClassifier), - target.targetName - ) - - fun linkTaskName(kind: String, buildType: String) = - linkTaskName(NativeOutputKind.valueOf(kind.toUpperCase()), NativeBuildType.valueOf(buildType.toUpperCase())) - - override val compileDependencyConfigurationName: String - get() = lowerCamelCaseName( - target.disambiguationClassifier, - compilationName.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME }.orEmpty(), - "compileKlibraries" - ) - - override val compileAllTaskName: String - get() = lowerCamelCaseName(target.disambiguationClassifier, compilationName, "klibrary") - - val binariesTaskName: String - get() = lowerCamelCaseName(target.disambiguationClassifier, compilationName, "binaries") - - override fun addSourcesToCompileTask(sourceSet: KotlinSourceSet, addAsCommonSources: Boolean) { - allSources.add(sourceSet.kotlin) - if (addAsCommonSources) { - commonSources.add(sourceSet.kotlin) - } - } -} - -private object CompilationSourceSetUtil { - // Cache the results per project - private val projectSourceSetsInMultipleCompilationsCache = WeakHashMap>() - - fun sourceSetsInMultipleCompilations(project: Project) = - projectSourceSetsInMultipleCompilationsCache.computeIfAbsent(project) { _ -> - check(project.state.executed) { "Should only be computed after the project is evaluated" } - - val compilations = (project.kotlinExtension as? KotlinMultiplatformExtension)?.targets?.flatMap { it.compilations } - ?: return@computeIfAbsent null - - compilations - .flatMap { compilation -> compilation.allKotlinSourceSets.map { sourceSet -> compilation to sourceSet } } - .groupingBy { (_, sourceSet) -> sourceSet } - .eachCount() - .filterValues { it > 1 } - .keys - } } \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinJvmCompilationFactory.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinJvmCompilationFactory.kt index e63b6e6573d..4e073769781 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinJvmCompilationFactory.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinJvmCompilationFactory.kt @@ -6,25 +6,6 @@ package org.jetbrains.kotlin.gradle.plugin.mpp -import org.gradle.api.NamedDomainObjectFactory -import org.gradle.api.Project -import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions -import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation - -interface KotlinCompilationFactory> : NamedDomainObjectFactory { - val itemClass: Class -} - -class KotlinCommonCompilationFactory( - val target: KotlinOnlyTarget -) : KotlinCompilationFactory { - override val itemClass: Class - get() = KotlinCommonCompilation::class.java - - override fun create(name: String): KotlinCommonCompilation = - KotlinCommonCompilation(target, name) -} - class KotlinJvmCompilationFactory( val target: KotlinOnlyTarget ) : KotlinCompilationFactory { @@ -33,61 +14,4 @@ class KotlinJvmCompilationFactory( override fun create(name: String): KotlinJvmCompilation = KotlinJvmCompilation(target, name) -} - -class KotlinWithJavaCompilationFactory( - val project: Project, - val target: KotlinWithJavaTarget -) : KotlinCompilationFactory> { - - override val itemClass: Class> - @Suppress("UNCHECKED_CAST") - get() = KotlinWithJavaCompilation::class.java as Class> - - override fun create(name: String): KotlinWithJavaCompilation { - val result = KotlinWithJavaCompilation(target, name) - return result - } -} - -class KotlinJvmAndroidCompilationFactory( - val project: Project, - val target: KotlinAndroidTarget -) : KotlinCompilationFactory { - - override val itemClass: Class - get() = KotlinJvmAndroidCompilation::class.java - - override fun create(name: String): KotlinJvmAndroidCompilation = - KotlinJvmAndroidCompilation(target, name) -} - -class KotlinJsCompilationFactory( - val project: Project, - val target: KotlinOnlyTarget -) : KotlinCompilationFactory { - override val itemClass: Class - get() = KotlinJsCompilation::class.java - - override fun create(name: String): KotlinJsCompilation = - KotlinJsCompilation(target, name) -} - -class KotlinNativeCompilationFactory( - val project: Project, - val target: KotlinNativeTarget -) : KotlinCompilationFactory { - - override val itemClass: Class - get() = KotlinNativeCompilation::class.java - - override fun create(name: String): KotlinNativeCompilation = - KotlinNativeCompilation(target, name).apply { - if (name == KotlinCompilation.TEST_COMPILATION_NAME) { - friendCompilationName = KotlinCompilation.MAIN_COMPILATION_NAME - isTestCompilation = true - } - buildTypes = mutableListOf(NativeBuildType.DEBUG, NativeBuildType.RELEASE) - } - } \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinJvmTargetPreset.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinJvmTargetPreset.kt index 921736ad861..982f213d94f 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinJvmTargetPreset.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinJvmTargetPreset.kt @@ -6,110 +6,12 @@ package org.jetbrains.kotlin.gradle.plugin.mpp import org.gradle.api.Project -import org.gradle.api.artifacts.Dependency import org.gradle.api.internal.file.FileResolver -import org.gradle.api.plugins.JavaPlugin import org.gradle.internal.reflect.Instantiator -import org.jetbrains.kotlin.compilerRunner.KotlinNativeProjectProperty -import org.jetbrains.kotlin.compilerRunner.hasProperty -import org.jetbrains.kotlin.compilerRunner.konanHome -import org.jetbrains.kotlin.gradle.dsl.KotlinCompile -import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptions -import org.jetbrains.kotlin.gradle.dsl.kotlinExtension -import org.jetbrains.kotlin.gradle.plugin.* -import org.jetbrains.kotlin.gradle.plugin.sources.applyLanguageSettingsToKotlinTask +import org.jetbrains.kotlin.gradle.plugin.Kotlin2JvmSourceSetProcessor +import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType +import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSetProcessor import org.jetbrains.kotlin.gradle.tasks.KotlinTasksProvider -import org.jetbrains.kotlin.gradle.utils.NativeCompilerDownloader -import org.jetbrains.kotlin.konan.KonanVersion -import org.jetbrains.kotlin.konan.target.HostManager -import org.jetbrains.kotlin.konan.target.KonanTarget -import java.io.File -import java.util.* - -abstract class KotlinOnlyTargetPreset>( - protected val project: Project, - private val instantiator: Instantiator, - private val fileResolver: FileResolver, - protected val kotlinPluginVersion: String -) : KotlinTargetPreset> { - - protected open fun createKotlinTargetConfigurator(): KotlinTargetConfigurator = - KotlinTargetConfigurator(createDefaultSourceSets = true, createTestCompilation = true) - - override fun createTarget(name: String): KotlinOnlyTarget { - val result = KotlinOnlyTarget(project, platformType).apply { - targetName = name - disambiguationClassifier = name - preset = this@KotlinOnlyTargetPreset - - val compilationFactory = createCompilationFactory(this) - compilations = project.container(compilationFactory.itemClass, compilationFactory) - } - - createKotlinTargetConfigurator().configureTarget(result) - - result.compilations.all { compilation -> - buildCompilationProcessor(compilation).run() - if (compilation.name == KotlinCompilation.MAIN_COMPILATION_NAME) { - sourcesJarTask(compilation, result.targetName, result.targetName.toLowerCase()) - } - } - - return result - } - - protected abstract fun createCompilationFactory(forTarget: KotlinOnlyTarget): KotlinCompilationFactory - protected abstract val platformType: KotlinPlatformType - internal abstract fun buildCompilationProcessor(compilation: T): KotlinSourceSetProcessor<*> -} - -class KotlinMetadataTargetPreset( - project: Project, - instantiator: Instantiator, - fileResolver: FileResolver, - kotlinPluginVersion: String -) : KotlinOnlyTargetPreset( - project, - instantiator, - fileResolver, - kotlinPluginVersion -) { - override fun getName(): String = PRESET_NAME - - override fun createCompilationFactory( - forTarget: KotlinOnlyTarget - ): KotlinCompilationFactory = - KotlinCommonCompilationFactory(forTarget) - - override val platformType: KotlinPlatformType - get() = KotlinPlatformType.common - - override fun buildCompilationProcessor(compilation: KotlinCommonCompilation): KotlinSourceSetProcessor<*> { - val tasksProvider = KotlinTasksProvider(compilation.target.targetName) - return KotlinCommonSourceSetProcessor(project, compilation, tasksProvider, kotlinPluginVersion) - } - - companion object { - const val PRESET_NAME = "metadata" - } - - override fun createKotlinTargetConfigurator(): KotlinTargetConfigurator = - KotlinTargetConfigurator(createDefaultSourceSets = false, createTestCompilation = false) - - override fun createTarget(name: String): KotlinOnlyTarget = - super.createTarget(name).apply { - val mainCompilation = compilations.getByName(KotlinCompilation.MAIN_COMPILATION_NAME) - val commonMainSourceSet = project.kotlinExtension.sourceSets.getByName(KotlinSourceSet.COMMON_MAIN_SOURCE_SET_NAME) - - mainCompilation.source(commonMainSourceSet) - - project.afterEvaluate { - // Since there's no default source set, apply language settings from commonMain: - val compileKotlinMetadata = project.tasks.getByName(mainCompilation.compileKotlinTaskName) as KotlinCompile<*> - applyLanguageSettingsToKotlinTask(commonMainSourceSet.languageSettings, compileKotlinMetadata) - } - } -} class KotlinJvmTargetPreset( project: Project, @@ -139,192 +41,3 @@ class KotlinJvmTargetPreset( const val PRESET_NAME = "jvm" } } - -class KotlinJsTargetPreset( - project: Project, - instantiator: Instantiator, - fileResolver: FileResolver, - kotlinPluginVersion: String -) : KotlinOnlyTargetPreset( - project, - instantiator, - fileResolver, - kotlinPluginVersion -) { - override fun getName(): String = PRESET_NAME - - override fun createCompilationFactory(forTarget: KotlinOnlyTarget) = - KotlinJsCompilationFactory(project, forTarget) - - override val platformType: KotlinPlatformType - get() = KotlinPlatformType.js - - override fun buildCompilationProcessor(compilation: KotlinJsCompilation): KotlinSourceSetProcessor<*> { - val tasksProvider = KotlinTasksProvider(compilation.target.targetName) - return Kotlin2JsSourceSetProcessor(project, tasksProvider, compilation, kotlinPluginVersion) - } - - companion object { - const val PRESET_NAME = "js" - } -} - -class KotlinAndroidTargetPreset( - private val project: Project, - private val kotlinPluginVersion: String -) : KotlinTargetPreset { - - override fun getName(): String = PRESET_NAME - - override fun createTarget(name: String): KotlinAndroidTarget { - val result = KotlinAndroidTarget(name, project).apply { - disambiguationClassifier = name - preset = this@KotlinAndroidTargetPreset - } - - KotlinAndroidPlugin.applyToTarget(kotlinPluginVersion, result) - return result - } - - companion object { - const val PRESET_NAME = "android" - } -} - -class KotlinJvmWithJavaTargetPreset( - private val project: Project, - private val kotlinPluginVersion: String -) : KotlinTargetPreset> { - - override fun getName(): String = PRESET_NAME - - override fun createTarget(name: String): KotlinWithJavaTarget { - project.plugins.apply(JavaPlugin::class.java) - - val target = KotlinWithJavaTarget(project, KotlinPlatformType.jvm, name).apply { - disambiguationClassifier = name - preset = this@KotlinJvmWithJavaTargetPreset - } - - AbstractKotlinPlugin.configureTarget(target) { compilation -> - Kotlin2JvmSourceSetProcessor(project, KotlinTasksProvider(name), compilation, kotlinPluginVersion) - } - - target.compilations.getByName("test").run { - val main = target.compilations.getByName(KotlinCompilation.MAIN_COMPILATION_NAME) - - compileDependencyFiles = project.files( - main.output.allOutputs, - project.configurations.maybeCreate(compileDependencyConfigurationName) - ) - runtimeDependencyFiles = project.files( - output.allOutputs, - main.output.allOutputs, - project.configurations.maybeCreate(runtimeDependencyConfigurationName) - ) - } - - return target - } - - companion object { - const val PRESET_NAME = "jvmWithJava" - } -} - -class KotlinNativeTargetPreset( - private val name: String, - val project: Project, - val konanTarget: KonanTarget, - private val kotlinPluginVersion: String -) : KotlinTargetPreset { - - init { - // This is required to obtain Kotlin/Native home in CLion plugin: - setupNativeHomePrivateProperty() - } - - override fun getName(): String = name - - private fun setupNativeHomePrivateProperty() = with(project) { - if (!hasProperty(KOTLIN_NATIVE_HOME_PRIVATE_PROPERTY)) - extensions.extraProperties.set(KOTLIN_NATIVE_HOME_PRIVATE_PROPERTY, konanHome) - } - - private fun setupNativeCompiler() = with(project) { - if (!hasProperty(KotlinNativeProjectProperty.KONAN_HOME_OVERRIDE)) { - NativeCompilerDownloader(this).downloadIfNeeded() - logger.info("Kotlin/Native distribution: $konanHome") - } else { - logger.info("User-provided Kotlin/Native distribution: $konanHome") - } - } - - // We declare default K/N dependencies as files to avoid searching them in remote repos (see KT-28128). - private fun defaultLibs(target: KonanTarget? = null): List = with(project) { - - val relPath = if (target != null) "platform/${target.name}" else "common" - - file("$konanHome/klib/$relPath") - .listFiles { file -> file.isDirectory } - ?.sortedBy { dir -> dir.name.toLowerCase() } - ?.map { dir -> dependencies.create(files(dir)) } ?: emptyList() - } - - override fun createTarget(name: String): KotlinNativeTarget { - setupNativeCompiler() - - val result = KotlinNativeTarget(project, konanTarget).apply { - targetName = name - disambiguationClassifier = name - preset = this@KotlinNativeTargetPreset - - val compilationFactory = KotlinNativeCompilationFactory(project, this) - compilations = project.container(compilationFactory.itemClass, compilationFactory) - } - - KotlinNativeTargetConfigurator(kotlinPluginVersion).configureTarget(result) - - // Allow IDE to resolve the libraries provided by the compiler by adding them into dependencies. - result.compilations.all { compilation -> - val target = compilation.target.konanTarget - // First, put common libs: - defaultLibs().forEach { - project.dependencies.add(compilation.compileDependencyConfigurationName, it) - } - // Then, platform-specific libs: - defaultLibs(target).forEach { - project.dependencies.add(compilation.compileDependencyConfigurationName, it) - } - } - - if (!konanTarget.enabledOnCurrentHost) { - with(HostManager()) { - val supportedHosts = enabledTargetsByHost.filterValues { konanTarget in it }.keys - val supportedHostsString = - if (supportedHosts.size == 1) - "a ${supportedHosts.single()} host" else - "one of the host platforms: ${supportedHosts.joinToString(", ")}" - project.logger.warn( - "Target '$name' for platform ${konanTarget} is ignored during build on this ${HostManager.host} machine. " + - "You can build it with $supportedHostsString." - ) - } - } - - return result - } - - companion object { - private const val KOTLIN_NATIVE_HOME_PRIVATE_PROPERTY = "konanHome" - } -} - -internal val KonanTarget.isCurrentHost: Boolean - get() = this == HostManager.host - -internal val KonanTarget.enabledOnCurrentHost - get() = HostManager().isEnabled(this) - -internal val KotlinNativeCompilation.isMainCompilation: Boolean - get() = name == KotlinCompilation.MAIN_COMPILATION_NAME diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinJvmWithJavaTargetPreset.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinJvmWithJavaTargetPreset.kt index 921736ad861..f66e788432c 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinJvmWithJavaTargetPreset.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinJvmWithJavaTargetPreset.kt @@ -6,190 +6,10 @@ package org.jetbrains.kotlin.gradle.plugin.mpp import org.gradle.api.Project -import org.gradle.api.artifacts.Dependency -import org.gradle.api.internal.file.FileResolver import org.gradle.api.plugins.JavaPlugin -import org.gradle.internal.reflect.Instantiator -import org.jetbrains.kotlin.compilerRunner.KotlinNativeProjectProperty -import org.jetbrains.kotlin.compilerRunner.hasProperty -import org.jetbrains.kotlin.compilerRunner.konanHome -import org.jetbrains.kotlin.gradle.dsl.KotlinCompile import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptions -import org.jetbrains.kotlin.gradle.dsl.kotlinExtension import org.jetbrains.kotlin.gradle.plugin.* -import org.jetbrains.kotlin.gradle.plugin.sources.applyLanguageSettingsToKotlinTask import org.jetbrains.kotlin.gradle.tasks.KotlinTasksProvider -import org.jetbrains.kotlin.gradle.utils.NativeCompilerDownloader -import org.jetbrains.kotlin.konan.KonanVersion -import org.jetbrains.kotlin.konan.target.HostManager -import org.jetbrains.kotlin.konan.target.KonanTarget -import java.io.File -import java.util.* - -abstract class KotlinOnlyTargetPreset>( - protected val project: Project, - private val instantiator: Instantiator, - private val fileResolver: FileResolver, - protected val kotlinPluginVersion: String -) : KotlinTargetPreset> { - - protected open fun createKotlinTargetConfigurator(): KotlinTargetConfigurator = - KotlinTargetConfigurator(createDefaultSourceSets = true, createTestCompilation = true) - - override fun createTarget(name: String): KotlinOnlyTarget { - val result = KotlinOnlyTarget(project, platformType).apply { - targetName = name - disambiguationClassifier = name - preset = this@KotlinOnlyTargetPreset - - val compilationFactory = createCompilationFactory(this) - compilations = project.container(compilationFactory.itemClass, compilationFactory) - } - - createKotlinTargetConfigurator().configureTarget(result) - - result.compilations.all { compilation -> - buildCompilationProcessor(compilation).run() - if (compilation.name == KotlinCompilation.MAIN_COMPILATION_NAME) { - sourcesJarTask(compilation, result.targetName, result.targetName.toLowerCase()) - } - } - - return result - } - - protected abstract fun createCompilationFactory(forTarget: KotlinOnlyTarget): KotlinCompilationFactory - protected abstract val platformType: KotlinPlatformType - internal abstract fun buildCompilationProcessor(compilation: T): KotlinSourceSetProcessor<*> -} - -class KotlinMetadataTargetPreset( - project: Project, - instantiator: Instantiator, - fileResolver: FileResolver, - kotlinPluginVersion: String -) : KotlinOnlyTargetPreset( - project, - instantiator, - fileResolver, - kotlinPluginVersion -) { - override fun getName(): String = PRESET_NAME - - override fun createCompilationFactory( - forTarget: KotlinOnlyTarget - ): KotlinCompilationFactory = - KotlinCommonCompilationFactory(forTarget) - - override val platformType: KotlinPlatformType - get() = KotlinPlatformType.common - - override fun buildCompilationProcessor(compilation: KotlinCommonCompilation): KotlinSourceSetProcessor<*> { - val tasksProvider = KotlinTasksProvider(compilation.target.targetName) - return KotlinCommonSourceSetProcessor(project, compilation, tasksProvider, kotlinPluginVersion) - } - - companion object { - const val PRESET_NAME = "metadata" - } - - override fun createKotlinTargetConfigurator(): KotlinTargetConfigurator = - KotlinTargetConfigurator(createDefaultSourceSets = false, createTestCompilation = false) - - override fun createTarget(name: String): KotlinOnlyTarget = - super.createTarget(name).apply { - val mainCompilation = compilations.getByName(KotlinCompilation.MAIN_COMPILATION_NAME) - val commonMainSourceSet = project.kotlinExtension.sourceSets.getByName(KotlinSourceSet.COMMON_MAIN_SOURCE_SET_NAME) - - mainCompilation.source(commonMainSourceSet) - - project.afterEvaluate { - // Since there's no default source set, apply language settings from commonMain: - val compileKotlinMetadata = project.tasks.getByName(mainCompilation.compileKotlinTaskName) as KotlinCompile<*> - applyLanguageSettingsToKotlinTask(commonMainSourceSet.languageSettings, compileKotlinMetadata) - } - } -} - -class KotlinJvmTargetPreset( - project: Project, - instantiator: Instantiator, - fileResolver: FileResolver, - kotlinPluginVersion: String -) : KotlinOnlyTargetPreset( - project, - instantiator, - fileResolver, - kotlinPluginVersion -) { - override fun getName(): String = PRESET_NAME - - override fun createCompilationFactory(forTarget: KotlinOnlyTarget): KotlinCompilationFactory = - KotlinJvmCompilationFactory(forTarget) - - override val platformType: KotlinPlatformType - get() = KotlinPlatformType.jvm - - override fun buildCompilationProcessor(compilation: KotlinJvmCompilation): KotlinSourceSetProcessor<*> { - val tasksProvider = KotlinTasksProvider(compilation.target.targetName) - return Kotlin2JvmSourceSetProcessor(project, tasksProvider, compilation, kotlinPluginVersion) - } - - companion object { - const val PRESET_NAME = "jvm" - } -} - -class KotlinJsTargetPreset( - project: Project, - instantiator: Instantiator, - fileResolver: FileResolver, - kotlinPluginVersion: String -) : KotlinOnlyTargetPreset( - project, - instantiator, - fileResolver, - kotlinPluginVersion -) { - override fun getName(): String = PRESET_NAME - - override fun createCompilationFactory(forTarget: KotlinOnlyTarget) = - KotlinJsCompilationFactory(project, forTarget) - - override val platformType: KotlinPlatformType - get() = KotlinPlatformType.js - - override fun buildCompilationProcessor(compilation: KotlinJsCompilation): KotlinSourceSetProcessor<*> { - val tasksProvider = KotlinTasksProvider(compilation.target.targetName) - return Kotlin2JsSourceSetProcessor(project, tasksProvider, compilation, kotlinPluginVersion) - } - - companion object { - const val PRESET_NAME = "js" - } -} - -class KotlinAndroidTargetPreset( - private val project: Project, - private val kotlinPluginVersion: String -) : KotlinTargetPreset { - - override fun getName(): String = PRESET_NAME - - override fun createTarget(name: String): KotlinAndroidTarget { - val result = KotlinAndroidTarget(name, project).apply { - disambiguationClassifier = name - preset = this@KotlinAndroidTargetPreset - } - - KotlinAndroidPlugin.applyToTarget(kotlinPluginVersion, result) - return result - } - - companion object { - const val PRESET_NAME = "android" - } -} class KotlinJvmWithJavaTargetPreset( private val project: Project, @@ -231,100 +51,3 @@ class KotlinJvmWithJavaTargetPreset( const val PRESET_NAME = "jvmWithJava" } } - -class KotlinNativeTargetPreset( - private val name: String, - val project: Project, - val konanTarget: KonanTarget, - private val kotlinPluginVersion: String -) : KotlinTargetPreset { - - init { - // This is required to obtain Kotlin/Native home in CLion plugin: - setupNativeHomePrivateProperty() - } - - override fun getName(): String = name - - private fun setupNativeHomePrivateProperty() = with(project) { - if (!hasProperty(KOTLIN_NATIVE_HOME_PRIVATE_PROPERTY)) - extensions.extraProperties.set(KOTLIN_NATIVE_HOME_PRIVATE_PROPERTY, konanHome) - } - - private fun setupNativeCompiler() = with(project) { - if (!hasProperty(KotlinNativeProjectProperty.KONAN_HOME_OVERRIDE)) { - NativeCompilerDownloader(this).downloadIfNeeded() - logger.info("Kotlin/Native distribution: $konanHome") - } else { - logger.info("User-provided Kotlin/Native distribution: $konanHome") - } - } - - // We declare default K/N dependencies as files to avoid searching them in remote repos (see KT-28128). - private fun defaultLibs(target: KonanTarget? = null): List = with(project) { - - val relPath = if (target != null) "platform/${target.name}" else "common" - - file("$konanHome/klib/$relPath") - .listFiles { file -> file.isDirectory } - ?.sortedBy { dir -> dir.name.toLowerCase() } - ?.map { dir -> dependencies.create(files(dir)) } ?: emptyList() - } - - override fun createTarget(name: String): KotlinNativeTarget { - setupNativeCompiler() - - val result = KotlinNativeTarget(project, konanTarget).apply { - targetName = name - disambiguationClassifier = name - preset = this@KotlinNativeTargetPreset - - val compilationFactory = KotlinNativeCompilationFactory(project, this) - compilations = project.container(compilationFactory.itemClass, compilationFactory) - } - - KotlinNativeTargetConfigurator(kotlinPluginVersion).configureTarget(result) - - // Allow IDE to resolve the libraries provided by the compiler by adding them into dependencies. - result.compilations.all { compilation -> - val target = compilation.target.konanTarget - // First, put common libs: - defaultLibs().forEach { - project.dependencies.add(compilation.compileDependencyConfigurationName, it) - } - // Then, platform-specific libs: - defaultLibs(target).forEach { - project.dependencies.add(compilation.compileDependencyConfigurationName, it) - } - } - - if (!konanTarget.enabledOnCurrentHost) { - with(HostManager()) { - val supportedHosts = enabledTargetsByHost.filterValues { konanTarget in it }.keys - val supportedHostsString = - if (supportedHosts.size == 1) - "a ${supportedHosts.single()} host" else - "one of the host platforms: ${supportedHosts.joinToString(", ")}" - project.logger.warn( - "Target '$name' for platform ${konanTarget} is ignored during build on this ${HostManager.host} machine. " + - "You can build it with $supportedHostsString." - ) - } - } - - return result - } - - companion object { - private const val KOTLIN_NATIVE_HOME_PRIVATE_PROPERTY = "konanHome" - } -} - -internal val KonanTarget.isCurrentHost: Boolean - get() = this == HostManager.host - -internal val KonanTarget.enabledOnCurrentHost - get() = HostManager().isEnabled(this) - -internal val KotlinNativeCompilation.isMainCompilation: Boolean - get() = name == KotlinCompilation.MAIN_COMPILATION_NAME diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinMetadataTargetPreset.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinMetadataTargetPreset.kt index 921736ad861..1dec0e555c6 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinMetadataTargetPreset.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinMetadataTargetPreset.kt @@ -6,62 +6,13 @@ package org.jetbrains.kotlin.gradle.plugin.mpp import org.gradle.api.Project -import org.gradle.api.artifacts.Dependency import org.gradle.api.internal.file.FileResolver -import org.gradle.api.plugins.JavaPlugin import org.gradle.internal.reflect.Instantiator -import org.jetbrains.kotlin.compilerRunner.KotlinNativeProjectProperty -import org.jetbrains.kotlin.compilerRunner.hasProperty -import org.jetbrains.kotlin.compilerRunner.konanHome import org.jetbrains.kotlin.gradle.dsl.KotlinCompile -import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptions import org.jetbrains.kotlin.gradle.dsl.kotlinExtension import org.jetbrains.kotlin.gradle.plugin.* import org.jetbrains.kotlin.gradle.plugin.sources.applyLanguageSettingsToKotlinTask import org.jetbrains.kotlin.gradle.tasks.KotlinTasksProvider -import org.jetbrains.kotlin.gradle.utils.NativeCompilerDownloader -import org.jetbrains.kotlin.konan.KonanVersion -import org.jetbrains.kotlin.konan.target.HostManager -import org.jetbrains.kotlin.konan.target.KonanTarget -import java.io.File -import java.util.* - -abstract class KotlinOnlyTargetPreset>( - protected val project: Project, - private val instantiator: Instantiator, - private val fileResolver: FileResolver, - protected val kotlinPluginVersion: String -) : KotlinTargetPreset> { - - protected open fun createKotlinTargetConfigurator(): KotlinTargetConfigurator = - KotlinTargetConfigurator(createDefaultSourceSets = true, createTestCompilation = true) - - override fun createTarget(name: String): KotlinOnlyTarget { - val result = KotlinOnlyTarget(project, platformType).apply { - targetName = name - disambiguationClassifier = name - preset = this@KotlinOnlyTargetPreset - - val compilationFactory = createCompilationFactory(this) - compilations = project.container(compilationFactory.itemClass, compilationFactory) - } - - createKotlinTargetConfigurator().configureTarget(result) - - result.compilations.all { compilation -> - buildCompilationProcessor(compilation).run() - if (compilation.name == KotlinCompilation.MAIN_COMPILATION_NAME) { - sourcesJarTask(compilation, result.targetName, result.targetName.toLowerCase()) - } - } - - return result - } - - protected abstract fun createCompilationFactory(forTarget: KotlinOnlyTarget): KotlinCompilationFactory - protected abstract val platformType: KotlinPlatformType - internal abstract fun buildCompilationProcessor(compilation: T): KotlinSourceSetProcessor<*> -} class KotlinMetadataTargetPreset( project: Project, @@ -110,221 +61,3 @@ class KotlinMetadataTargetPreset( } } } - -class KotlinJvmTargetPreset( - project: Project, - instantiator: Instantiator, - fileResolver: FileResolver, - kotlinPluginVersion: String -) : KotlinOnlyTargetPreset( - project, - instantiator, - fileResolver, - kotlinPluginVersion -) { - override fun getName(): String = PRESET_NAME - - override fun createCompilationFactory(forTarget: KotlinOnlyTarget): KotlinCompilationFactory = - KotlinJvmCompilationFactory(forTarget) - - override val platformType: KotlinPlatformType - get() = KotlinPlatformType.jvm - - override fun buildCompilationProcessor(compilation: KotlinJvmCompilation): KotlinSourceSetProcessor<*> { - val tasksProvider = KotlinTasksProvider(compilation.target.targetName) - return Kotlin2JvmSourceSetProcessor(project, tasksProvider, compilation, kotlinPluginVersion) - } - - companion object { - const val PRESET_NAME = "jvm" - } -} - -class KotlinJsTargetPreset( - project: Project, - instantiator: Instantiator, - fileResolver: FileResolver, - kotlinPluginVersion: String -) : KotlinOnlyTargetPreset( - project, - instantiator, - fileResolver, - kotlinPluginVersion -) { - override fun getName(): String = PRESET_NAME - - override fun createCompilationFactory(forTarget: KotlinOnlyTarget) = - KotlinJsCompilationFactory(project, forTarget) - - override val platformType: KotlinPlatformType - get() = KotlinPlatformType.js - - override fun buildCompilationProcessor(compilation: KotlinJsCompilation): KotlinSourceSetProcessor<*> { - val tasksProvider = KotlinTasksProvider(compilation.target.targetName) - return Kotlin2JsSourceSetProcessor(project, tasksProvider, compilation, kotlinPluginVersion) - } - - companion object { - const val PRESET_NAME = "js" - } -} - -class KotlinAndroidTargetPreset( - private val project: Project, - private val kotlinPluginVersion: String -) : KotlinTargetPreset { - - override fun getName(): String = PRESET_NAME - - override fun createTarget(name: String): KotlinAndroidTarget { - val result = KotlinAndroidTarget(name, project).apply { - disambiguationClassifier = name - preset = this@KotlinAndroidTargetPreset - } - - KotlinAndroidPlugin.applyToTarget(kotlinPluginVersion, result) - return result - } - - companion object { - const val PRESET_NAME = "android" - } -} - -class KotlinJvmWithJavaTargetPreset( - private val project: Project, - private val kotlinPluginVersion: String -) : KotlinTargetPreset> { - - override fun getName(): String = PRESET_NAME - - override fun createTarget(name: String): KotlinWithJavaTarget { - project.plugins.apply(JavaPlugin::class.java) - - val target = KotlinWithJavaTarget(project, KotlinPlatformType.jvm, name).apply { - disambiguationClassifier = name - preset = this@KotlinJvmWithJavaTargetPreset - } - - AbstractKotlinPlugin.configureTarget(target) { compilation -> - Kotlin2JvmSourceSetProcessor(project, KotlinTasksProvider(name), compilation, kotlinPluginVersion) - } - - target.compilations.getByName("test").run { - val main = target.compilations.getByName(KotlinCompilation.MAIN_COMPILATION_NAME) - - compileDependencyFiles = project.files( - main.output.allOutputs, - project.configurations.maybeCreate(compileDependencyConfigurationName) - ) - runtimeDependencyFiles = project.files( - output.allOutputs, - main.output.allOutputs, - project.configurations.maybeCreate(runtimeDependencyConfigurationName) - ) - } - - return target - } - - companion object { - const val PRESET_NAME = "jvmWithJava" - } -} - -class KotlinNativeTargetPreset( - private val name: String, - val project: Project, - val konanTarget: KonanTarget, - private val kotlinPluginVersion: String -) : KotlinTargetPreset { - - init { - // This is required to obtain Kotlin/Native home in CLion plugin: - setupNativeHomePrivateProperty() - } - - override fun getName(): String = name - - private fun setupNativeHomePrivateProperty() = with(project) { - if (!hasProperty(KOTLIN_NATIVE_HOME_PRIVATE_PROPERTY)) - extensions.extraProperties.set(KOTLIN_NATIVE_HOME_PRIVATE_PROPERTY, konanHome) - } - - private fun setupNativeCompiler() = with(project) { - if (!hasProperty(KotlinNativeProjectProperty.KONAN_HOME_OVERRIDE)) { - NativeCompilerDownloader(this).downloadIfNeeded() - logger.info("Kotlin/Native distribution: $konanHome") - } else { - logger.info("User-provided Kotlin/Native distribution: $konanHome") - } - } - - // We declare default K/N dependencies as files to avoid searching them in remote repos (see KT-28128). - private fun defaultLibs(target: KonanTarget? = null): List = with(project) { - - val relPath = if (target != null) "platform/${target.name}" else "common" - - file("$konanHome/klib/$relPath") - .listFiles { file -> file.isDirectory } - ?.sortedBy { dir -> dir.name.toLowerCase() } - ?.map { dir -> dependencies.create(files(dir)) } ?: emptyList() - } - - override fun createTarget(name: String): KotlinNativeTarget { - setupNativeCompiler() - - val result = KotlinNativeTarget(project, konanTarget).apply { - targetName = name - disambiguationClassifier = name - preset = this@KotlinNativeTargetPreset - - val compilationFactory = KotlinNativeCompilationFactory(project, this) - compilations = project.container(compilationFactory.itemClass, compilationFactory) - } - - KotlinNativeTargetConfigurator(kotlinPluginVersion).configureTarget(result) - - // Allow IDE to resolve the libraries provided by the compiler by adding them into dependencies. - result.compilations.all { compilation -> - val target = compilation.target.konanTarget - // First, put common libs: - defaultLibs().forEach { - project.dependencies.add(compilation.compileDependencyConfigurationName, it) - } - // Then, platform-specific libs: - defaultLibs(target).forEach { - project.dependencies.add(compilation.compileDependencyConfigurationName, it) - } - } - - if (!konanTarget.enabledOnCurrentHost) { - with(HostManager()) { - val supportedHosts = enabledTargetsByHost.filterValues { konanTarget in it }.keys - val supportedHostsString = - if (supportedHosts.size == 1) - "a ${supportedHosts.single()} host" else - "one of the host platforms: ${supportedHosts.joinToString(", ")}" - project.logger.warn( - "Target '$name' for platform ${konanTarget} is ignored during build on this ${HostManager.host} machine. " + - "You can build it with $supportedHostsString." - ) - } - } - - return result - } - - companion object { - private const val KOTLIN_NATIVE_HOME_PRIVATE_PROPERTY = "konanHome" - } -} - -internal val KonanTarget.isCurrentHost: Boolean - get() = this == HostManager.host - -internal val KonanTarget.enabledOnCurrentHost - get() = HostManager().isEnabled(this) - -internal val KotlinNativeCompilation.isMainCompilation: Boolean - get() = name == KotlinCompilation.MAIN_COMPILATION_NAME diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinNativeCompilation.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinNativeCompilation.kt index 1284fe446f3..cdb73b4fced 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinNativeCompilation.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinNativeCompilation.kt @@ -9,301 +9,17 @@ import groovy.lang.Closure import org.gradle.api.Action import org.gradle.api.NamedDomainObjectContainer import org.gradle.api.Project -import org.gradle.api.attributes.AttributeContainer -import org.gradle.api.file.FileCollection import org.gradle.api.file.SourceDirectorySet -import org.gradle.api.tasks.SourceSet import org.gradle.util.ConfigureUtil -import org.jetbrains.kotlin.gradle.dsl.* -import org.jetbrains.kotlin.gradle.dsl.KotlinCompile -import org.jetbrains.kotlin.gradle.plugin.* -import org.jetbrains.kotlin.gradle.plugin.sources.defaultSourceSetLanguageSettingsChecker -import org.jetbrains.kotlin.gradle.plugin.sources.getSourceSetHierarchy -import org.jetbrains.kotlin.gradle.tasks.* -import org.jetbrains.kotlin.gradle.utils.addExtendsFromRelation +import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions +import org.jetbrains.kotlin.gradle.dsl.KotlinNativeBinaryContainer +import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation +import org.jetbrains.kotlin.gradle.plugin.KotlinCompilationWithResources +import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet +import org.jetbrains.kotlin.gradle.tasks.KotlinNativeCompile +import org.jetbrains.kotlin.gradle.tasks.KotlinNativeLink import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName import java.io.File -import java.util.* -import java.util.concurrent.Callable - -internal fun KotlinCompilation<*>.composeName(prefix: String? = null, suffix: String? = null): String { - val compilationNamePart = compilationName.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME } - val targetNamePart = target.disambiguationClassifier - - return lowerCamelCaseName(prefix, targetNamePart, compilationNamePart, suffix) -} - -internal val KotlinCompilation<*>.defaultSourceSetName: String - get() = lowerCamelCaseName(target.disambiguationClassifier, compilationName) - -abstract class AbstractKotlinCompilation( - target: KotlinTarget, - override val compilationName: String -) : KotlinCompilation, HasKotlinDependencies { - - override val kotlinOptions: T - get() = compileKotlinTask.kotlinOptions - - override fun kotlinOptions(configure: T.() -> Unit) = - configure(kotlinOptions) - - @Suppress("UNCHECKED_CAST") - override val compileKotlinTask: KotlinCompile - get() = (target.project.tasks.getByName(compileKotlinTaskName) as KotlinCompile) - - // Don't declare this property in the constructor to avoid NPE - // when an overriding property of a subclass is accessed instead. - override val target: KotlinTarget = target - - private val attributeContainer = HierarchyAttributeContainer(target.attributes) - - override fun getAttributes(): AttributeContainer = attributeContainer - - override val kotlinSourceSets: MutableSet = mutableSetOf() - - override val allKotlinSourceSets: Set - get() = kotlinSourceSets.flatMapTo(mutableSetOf()) { it.getSourceSetHierarchy() } - - override val defaultSourceSet: KotlinSourceSet - get() = target.project.kotlinExtension.sourceSets.getByName(defaultSourceSetName) - - override fun defaultSourceSet(configure: KotlinSourceSet.() -> Unit) = - configure(defaultSourceSet) - - override val output: KotlinCompilationOutput by lazy { - DefaultKotlinCompilationOutput( - target.project, - Callable { target.project.buildDir.resolve("processedResources/${target.targetName}/$name") }) - } - - open fun addSourcesToCompileTask(sourceSet: KotlinSourceSet, addAsCommonSources: Boolean) { - fun AbstractKotlinCompile<*>.configureAction() { - source(sourceSet.kotlin) - sourceFilesExtensions(sourceSet.customSourceFilesExtensions) - if (addAsCommonSources) { - commonSourceSet += sourceSet.kotlin - } - } - - // Note! Invocation of withType-all results in preliminary task instantiation. - // After fix of this issue the following code should be uncommented: -// if (useLazyTaskConfiguration) { -// (target.project.tasks.named(compileKotlinTaskName) as TaskProvider>).configure { -// it.configureAction() -// } -// } - - target.project.tasks - // 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 -> - compileKotlinTask.configureAction() - } - } - - override fun source(sourceSet: KotlinSourceSet) { - if (kotlinSourceSets.add(sourceSet)) { - //TODO possibly issue with forced instantiation - target.project.whenEvaluated { - sourceSet.getSourceSetHierarchy().forEach { sourceSet -> - val isCommonSource = - CompilationSourceSetUtil.sourceSetsInMultipleCompilations(project)?.contains(sourceSet) ?: false - - addSourcesToCompileTask(sourceSet, addAsCommonSources = isCommonSource) - - // Use `forced = false` since `api`, `implementation`, and `compileOnly` may be missing in some cases like - // old Java & Android projects: - addExtendsFromRelation(apiConfigurationName, sourceSet.apiConfigurationName, forced = false) - addExtendsFromRelation(implementationConfigurationName, sourceSet.implementationConfigurationName, forced = false) - addExtendsFromRelation(compileOnlyConfigurationName, sourceSet.compileOnlyConfigurationName, forced = false) - - if (this@AbstractKotlinCompilation is KotlinCompilationToRunnableFiles<*>) { - addExtendsFromRelation(runtimeOnlyConfigurationName, sourceSet.runtimeOnlyConfigurationName, forced = false) - } - - if (sourceSet.name != defaultSourceSetName) { - kotlinExtension.sourceSets.findByName(defaultSourceSetName)?.let { defaultSourceSet -> - // Temporary solution for checking consistency across source sets participating in a compilation that may - // not be interconnected with the dependsOn relation: check the settings as if the default source set of - // the compilation depends on the one added to the compilation: - defaultSourceSetLanguageSettingsChecker.runAllChecks( - defaultSourceSet, - sourceSet - ) - } - } - } - } - } - } - - override val compileDependencyConfigurationName: String - get() = lowerCamelCaseName( - target.disambiguationClassifier, - compilationName.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME }.orEmpty(), - "compileClasspath" - ) - - override val compileKotlinTaskName: String - get() = lowerCamelCaseName( - "compile", - compilationName.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME }, - "Kotlin", - target.targetName - ) - - override val compileAllTaskName: String - get() = lowerCamelCaseName(target.disambiguationClassifier, compilationName, "classes") - - override lateinit var compileDependencyFiles: FileCollection - - override val apiConfigurationName: String - get() = disambiguateName("api") - - override val implementationConfigurationName: String - get() = disambiguateName("implementation") - - override val compileOnlyConfigurationName: String - get() = disambiguateName("compileOnly") - - override val runtimeOnlyConfigurationName: String - get() = disambiguateName("runtimeOnly") - - override fun dependencies(configure: KotlinDependencyHandler.() -> Unit): Unit = - DefaultKotlinDependencyHandler(this, target.project).run(configure) - - override fun dependencies(configureClosure: Closure) = - dependencies f@{ ConfigureUtil.configure(configureClosure, this@f) } - - override fun toString(): String = "compilation '$compilationName' ($target)" -} - -abstract class AbstractKotlinCompilationToRunnableFiles( - target: KotlinTarget, - name: String -) : AbstractKotlinCompilation(target, name), KotlinCompilationToRunnableFiles { - override val runtimeDependencyConfigurationName: String - get() = lowerCamelCaseName( - target.disambiguationClassifier, - compilationName.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME }, - "runtimeClasspath" - ) - - override lateinit var runtimeDependencyFiles: FileCollection -} - -internal fun KotlinCompilation<*>.disambiguateName(simpleName: String): String { - return lowerCamelCaseName( - target.disambiguationClassifier, - compilationName.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME }, - simpleName - ) -} - -open class KotlinJvmCompilation( - target: KotlinTarget, - name: String -) : AbstractKotlinCompilationToRunnableFiles(target, name), KotlinCompilationWithResources { - override val processResourcesTaskName: String - get() = disambiguateName("processResources") - - override val compileKotlinTask: org.jetbrains.kotlin.gradle.tasks.KotlinCompile - get() = super.compileKotlinTask as org.jetbrains.kotlin.gradle.tasks.KotlinCompile -} - -class KotlinWithJavaCompilation( - target: KotlinWithJavaTarget, - name: String -) : AbstractKotlinCompilationToRunnableFiles(target, name), KotlinCompilationWithResources { - lateinit var javaSourceSet: SourceSet - - override val output: KotlinCompilationOutput by lazy { KotlinWithJavaCompilationOutput(this) } - - override val processResourcesTaskName: String - get() = javaSourceSet.processResourcesTaskName - - override var runtimeDependencyFiles: FileCollection - get() = javaSourceSet.runtimeClasspath - set(value) { - javaSourceSet.runtimeClasspath = value - } - - override val runtimeDependencyConfigurationName: String - get() = javaSourceSet.runtimeClasspathConfigurationName - - override val compileDependencyConfigurationName: String - get() = javaSourceSet.compileClasspathConfigurationName - - override val runtimeOnlyConfigurationName: String - get() = javaSourceSet.runtimeOnlyConfigurationName - - override val implementationConfigurationName: String - get() = javaSourceSet.implementationConfigurationName - - override val apiConfigurationName: String - get() = javaSourceSet.apiConfigurationName - - override val compileOnlyConfigurationName: String - get() = javaSourceSet.compileOnlyConfigurationName - - override val compileAllTaskName: String - get() = javaSourceSet.classesTaskName - - override var compileDependencyFiles: FileCollection - get() = javaSourceSet.compileClasspath - set(value) { - javaSourceSet.compileClasspath = value - } - - fun source(javaSourceSet: SourceSet) { - with(target.project) { - afterEvaluate { - (tasks.getByName(compileKotlinTaskName) as AbstractKotlinCompile<*>).source(javaSourceSet.java) - } - } - } -} - -class KotlinJvmAndroidCompilation( - target: KotlinAndroidTarget, - name: String -) : AbstractKotlinCompilationToRunnableFiles(target, name) { - override val compileKotlinTask: org.jetbrains.kotlin.gradle.tasks.KotlinCompile - get() = super.compileKotlinTask as org.jetbrains.kotlin.gradle.tasks.KotlinCompile - - override val relatedConfigurationNames: List - get() = super.relatedConfigurationNames + listOf("${name}ApiElements", "${name}RuntimeElements") -} - -class KotlinJsCompilation( - target: KotlinTarget, - name: String -) : AbstractKotlinCompilationToRunnableFiles(target, name), KotlinCompilationWithResources { - override val processResourcesTaskName: String - get() = disambiguateName("processResources") - - override val compileKotlinTask: Kotlin2JsCompile - get() = super.compileKotlinTask as Kotlin2JsCompile -} - -class KotlinCommonCompilation( - target: KotlinTarget, - name: String -) : AbstractKotlinCompilation(target, name) { - override val compileKotlinTask: KotlinCompileCommon - get() = super.compileKotlinTask as KotlinCompileCommon - - // TODO once we properly compile metadata for each source set, the default source sets will likely become just the source sets - // which are transformed to metadata - private val commonSourceSetName = when (compilationName) { - KotlinCompilation.MAIN_COMPILATION_NAME -> KotlinSourceSet.COMMON_MAIN_SOURCE_SET_NAME - else -> error("Custom metadata compilations are not supported yet") - } - - override val defaultSourceSet: KotlinSourceSet - get() = target.project.kotlinExtension.sourceSets.getByName(commonSourceSetName) -} class KotlinNativeCompilation( override val target: KotlinNativeTarget, @@ -448,24 +164,4 @@ class KotlinNativeCompilation( commonSources.add(sourceSet.kotlin) } } -} - -private object CompilationSourceSetUtil { - // Cache the results per project - private val projectSourceSetsInMultipleCompilationsCache = WeakHashMap>() - - fun sourceSetsInMultipleCompilations(project: Project) = - projectSourceSetsInMultipleCompilationsCache.computeIfAbsent(project) { _ -> - check(project.state.executed) { "Should only be computed after the project is evaluated" } - - val compilations = (project.kotlinExtension as? KotlinMultiplatformExtension)?.targets?.flatMap { it.compilations } - ?: return@computeIfAbsent null - - compilations - .flatMap { compilation -> compilation.allKotlinSourceSets.map { sourceSet -> compilation to sourceSet } } - .groupingBy { (_, sourceSet) -> sourceSet } - .eachCount() - .filterValues { it > 1 } - .keys - } } \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinNativeCompilationFactory.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinNativeCompilationFactory.kt index e63b6e6573d..3ec8dc52dab 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinNativeCompilationFactory.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinNativeCompilationFactory.kt @@ -6,73 +6,9 @@ package org.jetbrains.kotlin.gradle.plugin.mpp -import org.gradle.api.NamedDomainObjectFactory import org.gradle.api.Project -import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation -interface KotlinCompilationFactory> : NamedDomainObjectFactory { - val itemClass: Class -} - -class KotlinCommonCompilationFactory( - val target: KotlinOnlyTarget -) : KotlinCompilationFactory { - override val itemClass: Class - get() = KotlinCommonCompilation::class.java - - override fun create(name: String): KotlinCommonCompilation = - KotlinCommonCompilation(target, name) -} - -class KotlinJvmCompilationFactory( - val target: KotlinOnlyTarget -) : KotlinCompilationFactory { - override val itemClass: Class - get() = KotlinJvmCompilation::class.java - - override fun create(name: String): KotlinJvmCompilation = - KotlinJvmCompilation(target, name) -} - -class KotlinWithJavaCompilationFactory( - val project: Project, - val target: KotlinWithJavaTarget -) : KotlinCompilationFactory> { - - override val itemClass: Class> - @Suppress("UNCHECKED_CAST") - get() = KotlinWithJavaCompilation::class.java as Class> - - override fun create(name: String): KotlinWithJavaCompilation { - val result = KotlinWithJavaCompilation(target, name) - return result - } -} - -class KotlinJvmAndroidCompilationFactory( - val project: Project, - val target: KotlinAndroidTarget -) : KotlinCompilationFactory { - - override val itemClass: Class - get() = KotlinJvmAndroidCompilation::class.java - - override fun create(name: String): KotlinJvmAndroidCompilation = - KotlinJvmAndroidCompilation(target, name) -} - -class KotlinJsCompilationFactory( - val project: Project, - val target: KotlinOnlyTarget -) : KotlinCompilationFactory { - override val itemClass: Class - get() = KotlinJsCompilation::class.java - - override fun create(name: String): KotlinJsCompilation = - KotlinJsCompilation(target, name) -} - class KotlinNativeCompilationFactory( val project: Project, val target: KotlinNativeTarget diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinNativeTarget.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinNativeTarget.kt index f4bbb5d60f9..1e06e46830e 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinNativeTarget.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinNativeTarget.kt @@ -5,389 +5,15 @@ package org.jetbrains.kotlin.gradle.plugin.mpp import groovy.lang.Closure -import org.gradle.api.* -import org.gradle.api.artifacts.ConfigurablePublishArtifact -import org.gradle.api.artifacts.Dependency -import org.gradle.api.artifacts.PublishArtifact +import org.gradle.api.Project import org.gradle.api.attributes.Attribute -import org.gradle.api.attributes.AttributeContainer -import org.gradle.api.attributes.Usage.JAVA_API -import org.gradle.api.attributes.Usage.JAVA_RUNTIME_JARS -import org.gradle.api.plugins.JavaPlugin -import org.gradle.api.publish.maven.MavenPublication import org.gradle.util.ConfigureUtil import org.gradle.util.WrapUtil -import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions -import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension import org.jetbrains.kotlin.gradle.dsl.KotlinNativeBinaryContainer -import org.jetbrains.kotlin.gradle.dsl.kotlinExtension -import org.jetbrains.kotlin.gradle.plugin.* -import org.jetbrains.kotlin.gradle.utils.dashSeparatedName +import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType import org.jetbrains.kotlin.gradle.utils.isGradleVersionAtLeast -import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName import org.jetbrains.kotlin.konan.target.KonanTarget -abstract class AbstractKotlinTarget( - final override val project: Project -) : KotlinTarget { - private val attributeContainer = HierarchyAttributeContainer(parent = null) - - override fun getAttributes(): AttributeContainer = attributeContainer - - override val defaultConfigurationName: String - get() = disambiguateName("default") - - override val apiElementsConfigurationName: String - get() = disambiguateName("apiElements") - - override val runtimeElementsConfigurationName: String - get() = disambiguateName("runtimeElements") - - override val artifactsTaskName: String - get() = disambiguateName("jar") - - override fun toString(): String = "target $name ($platformType)" - - override val publishable: Boolean - get() = true - - override val components: Set by lazy { - val mainCompilation = compilations.getByName(KotlinCompilation.MAIN_COMPILATION_NAME) - val usageContexts = createUsageContexts(mainCompilation) - setOf( - if (isGradleVersionAtLeast(4, 7)) { - val componentName = mainCompilation.target.name - createKotlinVariant(componentName, mainCompilation, usageContexts).apply { - sourcesArtifacts = setOf( - sourcesJarArtifact( - mainCompilation, componentName, - dashSeparatedName(target.name.toLowerCase(), componentName.toLowerCase()) - ) - ) - } - } else { - KotlinVariant(mainCompilation, usageContexts) - } - ).also { project.components.addAll(it) } - } - - protected fun createKotlinVariant( - componentName: String, - compilation: KotlinCompilation<*>, - usageContexts: Set - ): KotlinVariant { - - val kotlinExtension = project.kotlinExtension as? KotlinMultiplatformExtension - ?: return KotlinVariantWithCoordinates(compilation, usageContexts) - - if (targetName == KotlinMultiplatformPlugin.METADATA_TARGET_NAME) - return KotlinVariantWithCoordinates(compilation, usageContexts) - - val separateMetadataTarget = kotlinExtension.targets.getByName(KotlinMultiplatformPlugin.METADATA_TARGET_NAME) - - val result = if (kotlinExtension.isGradleMetadataAvailable) { - KotlinVariantWithMetadataVariant(compilation, usageContexts, separateMetadataTarget) - } else { - // we should only add the Kotlin metadata dependency if we publish no Gradle metadata related to Kotlin MPP; - // with metadata, such a dependency would get invalid, since a platform module should only depend on modules for that - // same platform, not Kotlin metadata modules - KotlinVariantWithMetadataDependency(compilation, usageContexts, separateMetadataTarget) - } - - result.componentName = componentName - return result - } - - private fun createUsageContexts( - producingCompilation: KotlinCompilation<*> - ): Set { - // Here, `JAVA_API` and `JAVA_RUNTIME_JARS` are used intentionally as Gradle needs this for - // ordering of the usage contexts (prioritizing the dependencies) when merging them into the POM; - // These Java usages should not be replaced with the custom Kotlin usages. - return listOfNotNull( - JAVA_API to apiElementsConfigurationName, - (JAVA_RUNTIME_JARS to runtimeElementsConfigurationName).takeIf { producingCompilation is KotlinCompilationToRunnableFiles } - ).mapTo(mutableSetOf()) { (usageName, dependenciesConfigurationName) -> - DefaultKotlinUsageContext( - producingCompilation, - project.usageByName(usageName), - dependenciesConfigurationName - ) - } - } - - protected fun sourcesJarArtifact( - producingCompilation: KotlinCompilation<*>, - componentName: String, - artifactNameAppendix: String, - classifierPrefix: String? = null - ): PublishArtifact { - val sourcesJarTask = sourcesJarTask(producingCompilation, componentName, artifactNameAppendix) - val sourceArtifactConfigurationName = producingCompilation.disambiguateName("sourceArtifacts") - return producingCompilation.target.project.run { - (configurations.findByName(sourceArtifactConfigurationName) ?: run { - val configuration = configurations.create(sourceArtifactConfigurationName) { - it.isCanBeResolved = false - it.isCanBeConsumed = false - } - artifacts.add(sourceArtifactConfigurationName, sourcesJarTask) - configuration - }).artifacts.single().apply { - this as ConfigurablePublishArtifact - classifier = dashSeparatedName(classifierPrefix, "sources") - } - } - } - - @Suppress("UNCHECKED_CAST") - internal val publicationConfigureActions = - WrapUtil.toDomainObjectSet(Action::class.java) as DomainObjectSet> - - override fun mavenPublication(action: Action) { - publicationConfigureActions.add(action) - } - - override fun mavenPublication(action: Closure) = - mavenPublication(ConfigureUtil.configureUsing(action)) - - override var preset: KotlinTargetPreset? = null - internal set -} - -internal fun KotlinTarget.disambiguateName(simpleName: String) = - lowerCamelCaseName(targetName, simpleName) - -open class KotlinAndroidTarget( - override val targetName: String, - project: Project -) : AbstractKotlinTarget(project) { - - override var disambiguationClassifier: String? = null - internal set - - override val platformType: KotlinPlatformType - get() = KotlinPlatformType.androidJvm - - private val compilationFactory = KotlinJvmAndroidCompilationFactory(project, this) - - override val compilations: NamedDomainObjectContainer = - project.container(compilationFactory.itemClass, compilationFactory) - - /** Names of the Android library variants that should be published from the target's project within the default publications which are - * set up if the `maven-publish` Gradle plugin is applied. - * - * Item examples: - * * 'release' (in case no product flavors were defined) - * * 'fooRelease' (for the release build type of a flavor 'foo') - * * 'fooBarRelease' (for the release build type multi-dimensional flavors 'foo' and 'bar'). - * - * If set to null, which can also be done with [publishAllLibraryVariants], - * all library variants will be published, but not test or application variants. */ - var publishLibraryVariants: List? = listOf() - // Workaround for Groovy GString items in a list: - set(value) { field = value?.map(Any::toString) } - - /** Add Android library variant names to [publishLibraryVariants]. */ - fun publishLibraryVariants(vararg names: String) { - publishLibraryVariants = publishLibraryVariants.orEmpty() + names - } - - /** Set up all of the Android library variants to be published from this target's project within the default publications, which are - * set up if the `maven-publish` Gradle plugin is applied. This overrides the variants chosen with [publishLibraryVariants] */ - fun publishAllLibraryVariants() { - publishLibraryVariants = null - } - - /** If true, a publication will be created per merged product flavor, with the build types used as classifiers for the artifacts - * published within each publication. If set to false, each Android variant will have a separate publication. */ - var publishLibraryVariantsGroupedByFlavor = false - - private fun checkPublishLibraryVariantsExist() { - // Capture type parameter T - fun AbstractAndroidProjectHandler.getLibraryVariantNames() = - mutableSetOf().apply { - forEachVariant(project) { - if (getLibraryOutputTask(it) != null) - add(getVariantName(it)) - } - } - - val variantNames = - KotlinAndroidPlugin.androidTargetHandler(project.getKotlinPluginVersion()!!, this) - .getLibraryVariantNames() - - val missingVariants = - publishLibraryVariants?.minus(variantNames).orEmpty() - - if (missingVariants.isNotEmpty()) - throw InvalidUserDataException( - "Kotlin target '$targetName' tried to set up publishing for Android build variants that are not library variants " + - "or do not exist:\n" + missingVariants.joinToString("\n") { "* $it" } + - "\nCheck the 'publishLibraryVariants' property, it should point to existing Android library variants. Publishing " + - "of application and test variants is not supported." - ) - } - - override val components by lazy { - checkPublishLibraryVariantsExist() - - KotlinAndroidPlugin.androidTargetHandler(project.getKotlinPluginVersion()!!, this).doCreateComponents() - .also { project.components.addAll(it) } - } - - // Capture the type parameter T for `AbstractAndroidProjectHandler` - private fun AbstractAndroidProjectHandler.doCreateComponents(): Set { - if (!isGradleVersionAtLeast(4, 7)) - return emptySet() - - val publishableVariants = mutableListOf() - .apply { forEachVariant(project) { add(it) } } - .toList() // Defensive copy against unlikely modification by the lambda that captures the list above in forEachVariant { } - .filter { getLibraryOutputTask(it) != null && publishLibraryVariants?.contains(getVariantName(it)) ?: true } - - val publishableVariantGroups = publishableVariants.groupBy { variant -> - val flavorNames = getFlavorNames(variant) - if (publishLibraryVariantsGroupedByFlavor) { - // For each flavor, we group its variants (which differ only in the build type) in a single component in order to publish - // all of the build types of the flavor as a single module with the build type as the classifier of the artifacts - flavorNames - } else { - flavorNames + getBuildTypeName(variant) - } - } - - return publishableVariantGroups.map { (flavorGroupNameParts, androidVariants) -> - val nestedVariants = androidVariants.mapTo(mutableSetOf()) { androidVariant -> - val androidVariantName = getVariantName(androidVariant) - val compilation = compilations.getByName(androidVariantName) - - val flavorNames = getFlavorNames(androidVariant) - val buildTypeName = getBuildTypeName(androidVariant) - - val artifactClassifier = buildTypeName.takeIf { it != "release" && publishLibraryVariantsGroupedByFlavor } - - val usageContexts = createAndroidUsageContexts(androidVariant, compilation, artifactClassifier) - createKotlinVariant( - lowerCamelCaseName(compilation.target.name, *flavorGroupNameParts.toTypedArray()), - compilation, - usageContexts - ).apply { - sourcesArtifacts = setOf( - sourcesJarArtifact( - compilation, compilation.disambiguateName(""), - dashSeparatedName( - compilation.target.name.toLowerCase(), - *flavorNames.map { it.toLowerCase() }.toTypedArray(), - buildTypeName.takeIf { it != "release" }?.toLowerCase() - ), - classifierPrefix = artifactClassifier - ) - ) - - if (!publishLibraryVariantsGroupedByFlavor) { - defaultArtifactIdSuffix = - dashSeparatedName( - (getFlavorNames(androidVariant) + getBuildTypeName(androidVariant).takeIf { it != "release" }) - .map { it?.toLowerCase() } - ).takeIf { it.isNotEmpty() } - } - } - } - - if (publishLibraryVariantsGroupedByFlavor) { - JointAndroidKotlinTargetComponent( - this@KotlinAndroidTarget, - nestedVariants, - flavorGroupNameParts, - nestedVariants.flatMap { it.sourcesArtifacts }.toSet() - ) - } else { - nestedVariants.single() - } as KotlinTargetComponent - }.toSet() - } - - private fun AbstractAndroidProjectHandler.createAndroidUsageContexts( - variant: T, - compilation: KotlinCompilation<*>, - artifactClassifier: String? - ): Set { - val variantName = getVariantName(variant) - val outputTask = getLibraryOutputTask(variant) ?: return emptySet() - val artifact = run { - val archivesConfigurationName = lowerCamelCaseName(targetName, variantName, "archives") - project.configurations.maybeCreate(archivesConfigurationName).apply { - isCanBeConsumed = false - isCanBeResolved = false - } - project.artifacts.add(archivesConfigurationName, outputTask) { artifact -> - artifact.classifier = artifactClassifier - } - } - - val apiElementsConfigurationName = lowerCamelCaseName(variantName, "apiElements") - val runtimeElementsConfigurationName = lowerCamelCaseName(variantName, "runtimeElements") - - // Here, `JAVA_API` and `JAVA_RUNTIME_JARS` are used intentionally as Gradle needs this for - // ordering of the usage contexts (prioritizing the dependencies) when merging them into the POM; - // These Java usages should not be replaced with the custom Kotlin usages. - return listOf( - apiElementsConfigurationName to JAVA_API, - runtimeElementsConfigurationName to JAVA_RUNTIME_JARS - ).mapTo(mutableSetOf()) { (dependencyConfigurationName, usageName) -> - DefaultKotlinUsageContext( - compilation, - project.usageByName(usageName), - dependencyConfigurationName, - overrideConfigurationArtifacts = setOf(artifact) - ) - } - } -} - -open class KotlinWithJavaTarget( - project: Project, - override val platformType: KotlinPlatformType, - override val targetName: String -) : AbstractKotlinTarget(project) { - override var disambiguationClassifier: String? = null - internal set - - override val defaultConfigurationName: String - get() = Dependency.DEFAULT_CONFIGURATION - - override val apiElementsConfigurationName: String - get() = JavaPlugin.API_ELEMENTS_CONFIGURATION_NAME - - override val runtimeElementsConfigurationName: String - get() = JavaPlugin.RUNTIME_ELEMENTS_CONFIGURATION_NAME - - override val artifactsTaskName: String - get() = JavaPlugin.JAR_TASK_NAME - - override val compilations: NamedDomainObjectContainer> = - @Suppress("UNCHECKED_CAST") - project.container( - KotlinWithJavaCompilation::class.java as Class>, - KotlinWithJavaCompilationFactory(project, this) - ) -} - -open class KotlinOnlyTarget>( - project: Project, - override val platformType: KotlinPlatformType -) : AbstractKotlinTarget(project) { - - override lateinit var compilations: NamedDomainObjectContainer - internal set - - override lateinit var targetName: String - internal set - - override var disambiguationClassifier: String? = null - internal set -} - class KotlinNativeTarget( project: Project, val konanTarget: KonanTarget diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinNativeTargetPreset.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinNativeTargetPreset.kt index 921736ad861..481bb8c1cbf 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinNativeTargetPreset.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinNativeTargetPreset.kt @@ -26,212 +26,6 @@ import org.jetbrains.kotlin.konan.target.KonanTarget import java.io.File import java.util.* -abstract class KotlinOnlyTargetPreset>( - protected val project: Project, - private val instantiator: Instantiator, - private val fileResolver: FileResolver, - protected val kotlinPluginVersion: String -) : KotlinTargetPreset> { - - protected open fun createKotlinTargetConfigurator(): KotlinTargetConfigurator = - KotlinTargetConfigurator(createDefaultSourceSets = true, createTestCompilation = true) - - override fun createTarget(name: String): KotlinOnlyTarget { - val result = KotlinOnlyTarget(project, platformType).apply { - targetName = name - disambiguationClassifier = name - preset = this@KotlinOnlyTargetPreset - - val compilationFactory = createCompilationFactory(this) - compilations = project.container(compilationFactory.itemClass, compilationFactory) - } - - createKotlinTargetConfigurator().configureTarget(result) - - result.compilations.all { compilation -> - buildCompilationProcessor(compilation).run() - if (compilation.name == KotlinCompilation.MAIN_COMPILATION_NAME) { - sourcesJarTask(compilation, result.targetName, result.targetName.toLowerCase()) - } - } - - return result - } - - protected abstract fun createCompilationFactory(forTarget: KotlinOnlyTarget): KotlinCompilationFactory - protected abstract val platformType: KotlinPlatformType - internal abstract fun buildCompilationProcessor(compilation: T): KotlinSourceSetProcessor<*> -} - -class KotlinMetadataTargetPreset( - project: Project, - instantiator: Instantiator, - fileResolver: FileResolver, - kotlinPluginVersion: String -) : KotlinOnlyTargetPreset( - project, - instantiator, - fileResolver, - kotlinPluginVersion -) { - override fun getName(): String = PRESET_NAME - - override fun createCompilationFactory( - forTarget: KotlinOnlyTarget - ): KotlinCompilationFactory = - KotlinCommonCompilationFactory(forTarget) - - override val platformType: KotlinPlatformType - get() = KotlinPlatformType.common - - override fun buildCompilationProcessor(compilation: KotlinCommonCompilation): KotlinSourceSetProcessor<*> { - val tasksProvider = KotlinTasksProvider(compilation.target.targetName) - return KotlinCommonSourceSetProcessor(project, compilation, tasksProvider, kotlinPluginVersion) - } - - companion object { - const val PRESET_NAME = "metadata" - } - - override fun createKotlinTargetConfigurator(): KotlinTargetConfigurator = - KotlinTargetConfigurator(createDefaultSourceSets = false, createTestCompilation = false) - - override fun createTarget(name: String): KotlinOnlyTarget = - super.createTarget(name).apply { - val mainCompilation = compilations.getByName(KotlinCompilation.MAIN_COMPILATION_NAME) - val commonMainSourceSet = project.kotlinExtension.sourceSets.getByName(KotlinSourceSet.COMMON_MAIN_SOURCE_SET_NAME) - - mainCompilation.source(commonMainSourceSet) - - project.afterEvaluate { - // Since there's no default source set, apply language settings from commonMain: - val compileKotlinMetadata = project.tasks.getByName(mainCompilation.compileKotlinTaskName) as KotlinCompile<*> - applyLanguageSettingsToKotlinTask(commonMainSourceSet.languageSettings, compileKotlinMetadata) - } - } -} - -class KotlinJvmTargetPreset( - project: Project, - instantiator: Instantiator, - fileResolver: FileResolver, - kotlinPluginVersion: String -) : KotlinOnlyTargetPreset( - project, - instantiator, - fileResolver, - kotlinPluginVersion -) { - override fun getName(): String = PRESET_NAME - - override fun createCompilationFactory(forTarget: KotlinOnlyTarget): KotlinCompilationFactory = - KotlinJvmCompilationFactory(forTarget) - - override val platformType: KotlinPlatformType - get() = KotlinPlatformType.jvm - - override fun buildCompilationProcessor(compilation: KotlinJvmCompilation): KotlinSourceSetProcessor<*> { - val tasksProvider = KotlinTasksProvider(compilation.target.targetName) - return Kotlin2JvmSourceSetProcessor(project, tasksProvider, compilation, kotlinPluginVersion) - } - - companion object { - const val PRESET_NAME = "jvm" - } -} - -class KotlinJsTargetPreset( - project: Project, - instantiator: Instantiator, - fileResolver: FileResolver, - kotlinPluginVersion: String -) : KotlinOnlyTargetPreset( - project, - instantiator, - fileResolver, - kotlinPluginVersion -) { - override fun getName(): String = PRESET_NAME - - override fun createCompilationFactory(forTarget: KotlinOnlyTarget) = - KotlinJsCompilationFactory(project, forTarget) - - override val platformType: KotlinPlatformType - get() = KotlinPlatformType.js - - override fun buildCompilationProcessor(compilation: KotlinJsCompilation): KotlinSourceSetProcessor<*> { - val tasksProvider = KotlinTasksProvider(compilation.target.targetName) - return Kotlin2JsSourceSetProcessor(project, tasksProvider, compilation, kotlinPluginVersion) - } - - companion object { - const val PRESET_NAME = "js" - } -} - -class KotlinAndroidTargetPreset( - private val project: Project, - private val kotlinPluginVersion: String -) : KotlinTargetPreset { - - override fun getName(): String = PRESET_NAME - - override fun createTarget(name: String): KotlinAndroidTarget { - val result = KotlinAndroidTarget(name, project).apply { - disambiguationClassifier = name - preset = this@KotlinAndroidTargetPreset - } - - KotlinAndroidPlugin.applyToTarget(kotlinPluginVersion, result) - return result - } - - companion object { - const val PRESET_NAME = "android" - } -} - -class KotlinJvmWithJavaTargetPreset( - private val project: Project, - private val kotlinPluginVersion: String -) : KotlinTargetPreset> { - - override fun getName(): String = PRESET_NAME - - override fun createTarget(name: String): KotlinWithJavaTarget { - project.plugins.apply(JavaPlugin::class.java) - - val target = KotlinWithJavaTarget(project, KotlinPlatformType.jvm, name).apply { - disambiguationClassifier = name - preset = this@KotlinJvmWithJavaTargetPreset - } - - AbstractKotlinPlugin.configureTarget(target) { compilation -> - Kotlin2JvmSourceSetProcessor(project, KotlinTasksProvider(name), compilation, kotlinPluginVersion) - } - - target.compilations.getByName("test").run { - val main = target.compilations.getByName(KotlinCompilation.MAIN_COMPILATION_NAME) - - compileDependencyFiles = project.files( - main.output.allOutputs, - project.configurations.maybeCreate(compileDependencyConfigurationName) - ) - runtimeDependencyFiles = project.files( - output.allOutputs, - main.output.allOutputs, - project.configurations.maybeCreate(runtimeDependencyConfigurationName) - ) - } - - return target - } - - companion object { - const val PRESET_NAME = "jvmWithJava" - } -} - class KotlinNativeTargetPreset( private val name: String, val project: Project, diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinWithJavaCompilation.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinWithJavaCompilation.kt index 1284fe446f3..39b97f6e389 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinWithJavaCompilation.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinWithJavaCompilation.kt @@ -5,214 +5,14 @@ package org.jetbrains.kotlin.gradle.plugin.mpp -import groovy.lang.Closure -import org.gradle.api.Action -import org.gradle.api.NamedDomainObjectContainer -import org.gradle.api.Project -import org.gradle.api.attributes.AttributeContainer import org.gradle.api.file.FileCollection -import org.gradle.api.file.SourceDirectorySet import org.gradle.api.tasks.SourceSet -import org.gradle.util.ConfigureUtil -import org.jetbrains.kotlin.gradle.dsl.* -import org.jetbrains.kotlin.gradle.dsl.KotlinCompile -import org.jetbrains.kotlin.gradle.plugin.* -import org.jetbrains.kotlin.gradle.plugin.sources.defaultSourceSetLanguageSettingsChecker -import org.jetbrains.kotlin.gradle.plugin.sources.getSourceSetHierarchy -import org.jetbrains.kotlin.gradle.tasks.* -import org.jetbrains.kotlin.gradle.utils.addExtendsFromRelation -import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName -import java.io.File -import java.util.* -import java.util.concurrent.Callable +import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions +import org.jetbrains.kotlin.gradle.plugin.KotlinCompilationOutput +import org.jetbrains.kotlin.gradle.plugin.KotlinCompilationWithResources +import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile -internal fun KotlinCompilation<*>.composeName(prefix: String? = null, suffix: String? = null): String { - val compilationNamePart = compilationName.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME } - val targetNamePart = target.disambiguationClassifier - - return lowerCamelCaseName(prefix, targetNamePart, compilationNamePart, suffix) -} - -internal val KotlinCompilation<*>.defaultSourceSetName: String - get() = lowerCamelCaseName(target.disambiguationClassifier, compilationName) - -abstract class AbstractKotlinCompilation( - target: KotlinTarget, - override val compilationName: String -) : KotlinCompilation, HasKotlinDependencies { - - override val kotlinOptions: T - get() = compileKotlinTask.kotlinOptions - - override fun kotlinOptions(configure: T.() -> Unit) = - configure(kotlinOptions) - - @Suppress("UNCHECKED_CAST") - override val compileKotlinTask: KotlinCompile - get() = (target.project.tasks.getByName(compileKotlinTaskName) as KotlinCompile) - - // Don't declare this property in the constructor to avoid NPE - // when an overriding property of a subclass is accessed instead. - override val target: KotlinTarget = target - - private val attributeContainer = HierarchyAttributeContainer(target.attributes) - - override fun getAttributes(): AttributeContainer = attributeContainer - - override val kotlinSourceSets: MutableSet = mutableSetOf() - - override val allKotlinSourceSets: Set - get() = kotlinSourceSets.flatMapTo(mutableSetOf()) { it.getSourceSetHierarchy() } - - override val defaultSourceSet: KotlinSourceSet - get() = target.project.kotlinExtension.sourceSets.getByName(defaultSourceSetName) - - override fun defaultSourceSet(configure: KotlinSourceSet.() -> Unit) = - configure(defaultSourceSet) - - override val output: KotlinCompilationOutput by lazy { - DefaultKotlinCompilationOutput( - target.project, - Callable { target.project.buildDir.resolve("processedResources/${target.targetName}/$name") }) - } - - open fun addSourcesToCompileTask(sourceSet: KotlinSourceSet, addAsCommonSources: Boolean) { - fun AbstractKotlinCompile<*>.configureAction() { - source(sourceSet.kotlin) - sourceFilesExtensions(sourceSet.customSourceFilesExtensions) - if (addAsCommonSources) { - commonSourceSet += sourceSet.kotlin - } - } - - // Note! Invocation of withType-all results in preliminary task instantiation. - // After fix of this issue the following code should be uncommented: -// if (useLazyTaskConfiguration) { -// (target.project.tasks.named(compileKotlinTaskName) as TaskProvider>).configure { -// it.configureAction() -// } -// } - - target.project.tasks - // 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 -> - compileKotlinTask.configureAction() - } - } - - override fun source(sourceSet: KotlinSourceSet) { - if (kotlinSourceSets.add(sourceSet)) { - //TODO possibly issue with forced instantiation - target.project.whenEvaluated { - sourceSet.getSourceSetHierarchy().forEach { sourceSet -> - val isCommonSource = - CompilationSourceSetUtil.sourceSetsInMultipleCompilations(project)?.contains(sourceSet) ?: false - - addSourcesToCompileTask(sourceSet, addAsCommonSources = isCommonSource) - - // Use `forced = false` since `api`, `implementation`, and `compileOnly` may be missing in some cases like - // old Java & Android projects: - addExtendsFromRelation(apiConfigurationName, sourceSet.apiConfigurationName, forced = false) - addExtendsFromRelation(implementationConfigurationName, sourceSet.implementationConfigurationName, forced = false) - addExtendsFromRelation(compileOnlyConfigurationName, sourceSet.compileOnlyConfigurationName, forced = false) - - if (this@AbstractKotlinCompilation is KotlinCompilationToRunnableFiles<*>) { - addExtendsFromRelation(runtimeOnlyConfigurationName, sourceSet.runtimeOnlyConfigurationName, forced = false) - } - - if (sourceSet.name != defaultSourceSetName) { - kotlinExtension.sourceSets.findByName(defaultSourceSetName)?.let { defaultSourceSet -> - // Temporary solution for checking consistency across source sets participating in a compilation that may - // not be interconnected with the dependsOn relation: check the settings as if the default source set of - // the compilation depends on the one added to the compilation: - defaultSourceSetLanguageSettingsChecker.runAllChecks( - defaultSourceSet, - sourceSet - ) - } - } - } - } - } - } - - override val compileDependencyConfigurationName: String - get() = lowerCamelCaseName( - target.disambiguationClassifier, - compilationName.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME }.orEmpty(), - "compileClasspath" - ) - - override val compileKotlinTaskName: String - get() = lowerCamelCaseName( - "compile", - compilationName.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME }, - "Kotlin", - target.targetName - ) - - override val compileAllTaskName: String - get() = lowerCamelCaseName(target.disambiguationClassifier, compilationName, "classes") - - override lateinit var compileDependencyFiles: FileCollection - - override val apiConfigurationName: String - get() = disambiguateName("api") - - override val implementationConfigurationName: String - get() = disambiguateName("implementation") - - override val compileOnlyConfigurationName: String - get() = disambiguateName("compileOnly") - - override val runtimeOnlyConfigurationName: String - get() = disambiguateName("runtimeOnly") - - override fun dependencies(configure: KotlinDependencyHandler.() -> Unit): Unit = - DefaultKotlinDependencyHandler(this, target.project).run(configure) - - override fun dependencies(configureClosure: Closure) = - dependencies f@{ ConfigureUtil.configure(configureClosure, this@f) } - - override fun toString(): String = "compilation '$compilationName' ($target)" -} - -abstract class AbstractKotlinCompilationToRunnableFiles( - target: KotlinTarget, - name: String -) : AbstractKotlinCompilation(target, name), KotlinCompilationToRunnableFiles { - override val runtimeDependencyConfigurationName: String - get() = lowerCamelCaseName( - target.disambiguationClassifier, - compilationName.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME }, - "runtimeClasspath" - ) - - override lateinit var runtimeDependencyFiles: FileCollection -} - -internal fun KotlinCompilation<*>.disambiguateName(simpleName: String): String { - return lowerCamelCaseName( - target.disambiguationClassifier, - compilationName.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME }, - simpleName - ) -} - -open class KotlinJvmCompilation( - target: KotlinTarget, - name: String -) : AbstractKotlinCompilationToRunnableFiles(target, name), KotlinCompilationWithResources { - override val processResourcesTaskName: String - get() = disambiguateName("processResources") - - override val compileKotlinTask: org.jetbrains.kotlin.gradle.tasks.KotlinCompile - get() = super.compileKotlinTask as org.jetbrains.kotlin.gradle.tasks.KotlinCompile -} - -class KotlinWithJavaCompilation( + class KotlinWithJavaCompilation( target: KotlinWithJavaTarget, name: String ) : AbstractKotlinCompilationToRunnableFiles(target, name), KotlinCompilationWithResources { @@ -263,209 +63,4 @@ class KotlinWithJavaCompilation( } } } -} - -class KotlinJvmAndroidCompilation( - target: KotlinAndroidTarget, - name: String -) : AbstractKotlinCompilationToRunnableFiles(target, name) { - override val compileKotlinTask: org.jetbrains.kotlin.gradle.tasks.KotlinCompile - get() = super.compileKotlinTask as org.jetbrains.kotlin.gradle.tasks.KotlinCompile - - override val relatedConfigurationNames: List - get() = super.relatedConfigurationNames + listOf("${name}ApiElements", "${name}RuntimeElements") -} - -class KotlinJsCompilation( - target: KotlinTarget, - name: String -) : AbstractKotlinCompilationToRunnableFiles(target, name), KotlinCompilationWithResources { - override val processResourcesTaskName: String - get() = disambiguateName("processResources") - - override val compileKotlinTask: Kotlin2JsCompile - get() = super.compileKotlinTask as Kotlin2JsCompile -} - -class KotlinCommonCompilation( - target: KotlinTarget, - name: String -) : AbstractKotlinCompilation(target, name) { - override val compileKotlinTask: KotlinCompileCommon - get() = super.compileKotlinTask as KotlinCompileCommon - - // TODO once we properly compile metadata for each source set, the default source sets will likely become just the source sets - // which are transformed to metadata - private val commonSourceSetName = when (compilationName) { - KotlinCompilation.MAIN_COMPILATION_NAME -> KotlinSourceSet.COMMON_MAIN_SOURCE_SET_NAME - else -> error("Custom metadata compilations are not supported yet") - } - - override val defaultSourceSet: KotlinSourceSet - get() = target.project.kotlinExtension.sourceSets.getByName(commonSourceSetName) -} - -class KotlinNativeCompilation( - override val target: KotlinNativeTarget, - name: String -) : AbstractKotlinCompilation(target, name), KotlinCompilationWithResources { - - override val kotlinOptions: KotlinCommonOptions - get() = compileKotlinTask.kotlinOptions - - override val compileKotlinTask: KotlinNativeCompile - get() = super.compileKotlinTask as KotlinNativeCompile - - private val project: Project - get() = target.project - - // A collection containing all source sets used by this compilation - // (taking into account dependencies between source sets). Used by both compilation - // and linking tasks. Unlike kotlinSourceSets, includes dependency source sets. - // TODO: Move into the compilation task when the linking task does klib linking instead of compilation. - internal val allSources: MutableSet = mutableSetOf() - - // TODO: Move into the compilation task when the linking task does klib linking instead of compilation. - internal val commonSources: MutableSet = mutableSetOf() - - var isTestCompilation = false - - var friendCompilationName: String? = null - - internal val friendCompilation: KotlinNativeCompilation? - get() = friendCompilationName?.let { - target.compilations.getByName(it) - } - - // Used only to support the old APIs. TODO: Remove when the old APIs are removed. - internal val binaries = mutableMapOf, NativeBinary>() - - // Native-specific DSL. - var extraOpts = mutableListOf() - - fun extraOpts(vararg values: Any) = extraOpts(values.toList()) - fun extraOpts(values: List) { - extraOpts.addAll(values.map { it.toString() }) - } - - var buildTypes = mutableListOf() - var outputKinds = mutableListOf() - - fun outputKind(kind: NativeOutputKind) = outputKinds.add(kind) - - fun outputKinds(vararg kinds: NativeOutputKind) { - outputKinds = kinds.toMutableList() - } - - fun outputKinds(vararg kinds: String) { - outputKinds = kinds.map { NativeOutputKind.valueOf(it.toUpperCase()) }.toMutableList() - } - - fun outputKinds(kinds: List) { - outputKinds = kinds.map { - when (it) { - is NativeOutputKind -> it - is String -> NativeOutputKind.valueOf(it.toUpperCase()) - else -> error("Cannot use $it as an output kind") - } - }.toMutableList() - } - - var entryPoint: String? = null - fun entryPoint(value: String) { - entryPoint = value - } - - // Interop DSL. - val cinterops = project.container(DefaultCInteropSettings::class.java) { cinteropName -> - DefaultCInteropSettings(project, cinteropName, this) - } - - var linkerOpts = mutableListOf() - - fun cinterops(action: NamedDomainObjectContainer.() -> Unit) = cinterops.action() - fun cinterops(action: Closure) = cinterops(ConfigureUtil.configureUsing(action)) - fun cinterops(action: Action>) = action.execute(cinterops) - - fun linkerOpts(vararg values: String) = linkerOpts(values.toList()) - fun linkerOpts(values: List) { - linkerOpts.addAll(values) - } - - // Task accessors. - fun findLinkTask(kind: NativeOutputKind, buildType: NativeBuildType): KotlinNativeLink? = binaries[kind to buildType]?.linkTask - - fun getLinkTask(kind: NativeOutputKind, buildType: NativeBuildType): KotlinNativeLink = - findLinkTask(kind, buildType) - ?: throw IllegalArgumentException("Cannot find a link task for the binary kind '$kind' and the build type '$buildType'") - - fun findLinkTask(kind: String, buildType: String) = - findLinkTask(NativeOutputKind.valueOf(kind.toUpperCase()), NativeBuildType.valueOf(buildType.toUpperCase())) - - fun getLinkTask(kind: String, buildType: String) = - getLinkTask(NativeOutputKind.valueOf(kind.toUpperCase()), NativeBuildType.valueOf(buildType.toUpperCase())) - - fun findBinary(kind: NativeOutputKind, buildType: NativeBuildType): File? = findLinkTask(kind, buildType)?.outputFile?.get() - - fun getBinary(kind: NativeOutputKind, buildType: NativeBuildType): File = getLinkTask(kind, buildType).outputFile.get() - - fun findBinary(kind: String, buildType: String) = - findBinary(NativeOutputKind.valueOf(kind.toUpperCase()), NativeBuildType.valueOf(buildType.toUpperCase())) - - fun getBinary(kind: String, buildType: String) = - getBinary(NativeOutputKind.valueOf(kind.toUpperCase()), NativeBuildType.valueOf(buildType.toUpperCase())) - - // Naming - override val processResourcesTaskName: String - get() = disambiguateName("processResources") - - fun linkTaskName(kind: NativeOutputKind, buildType: NativeBuildType): String = - lowerCamelCaseName( - "link", - KotlinNativeBinaryContainer.generateBinaryName(compilationName, buildType, kind.taskNameClassifier), - target.targetName - ) - - fun linkTaskName(kind: String, buildType: String) = - linkTaskName(NativeOutputKind.valueOf(kind.toUpperCase()), NativeBuildType.valueOf(buildType.toUpperCase())) - - override val compileDependencyConfigurationName: String - get() = lowerCamelCaseName( - target.disambiguationClassifier, - compilationName.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME }.orEmpty(), - "compileKlibraries" - ) - - override val compileAllTaskName: String - get() = lowerCamelCaseName(target.disambiguationClassifier, compilationName, "klibrary") - - val binariesTaskName: String - get() = lowerCamelCaseName(target.disambiguationClassifier, compilationName, "binaries") - - override fun addSourcesToCompileTask(sourceSet: KotlinSourceSet, addAsCommonSources: Boolean) { - allSources.add(sourceSet.kotlin) - if (addAsCommonSources) { - commonSources.add(sourceSet.kotlin) - } - } -} - -private object CompilationSourceSetUtil { - // Cache the results per project - private val projectSourceSetsInMultipleCompilationsCache = WeakHashMap>() - - fun sourceSetsInMultipleCompilations(project: Project) = - projectSourceSetsInMultipleCompilationsCache.computeIfAbsent(project) { _ -> - check(project.state.executed) { "Should only be computed after the project is evaluated" } - - val compilations = (project.kotlinExtension as? KotlinMultiplatformExtension)?.targets?.flatMap { it.compilations } - ?: return@computeIfAbsent null - - compilations - .flatMap { compilation -> compilation.allKotlinSourceSets.map { sourceSet -> compilation to sourceSet } } - .groupingBy { (_, sourceSet) -> sourceSet } - .eachCount() - .filterValues { it > 1 } - .keys - } } \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinWithJavaCompilationFactory.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinWithJavaCompilationFactory.kt index e63b6e6573d..893491a0785 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinWithJavaCompilationFactory.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinWithJavaCompilationFactory.kt @@ -11,30 +11,6 @@ import org.gradle.api.Project import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation -interface KotlinCompilationFactory> : NamedDomainObjectFactory { - val itemClass: Class -} - -class KotlinCommonCompilationFactory( - val target: KotlinOnlyTarget -) : KotlinCompilationFactory { - override val itemClass: Class - get() = KotlinCommonCompilation::class.java - - override fun create(name: String): KotlinCommonCompilation = - KotlinCommonCompilation(target, name) -} - -class KotlinJvmCompilationFactory( - val target: KotlinOnlyTarget -) : KotlinCompilationFactory { - override val itemClass: Class - get() = KotlinJvmCompilation::class.java - - override fun create(name: String): KotlinJvmCompilation = - KotlinJvmCompilation(target, name) -} - class KotlinWithJavaCompilationFactory( val project: Project, val target: KotlinWithJavaTarget @@ -48,46 +24,4 @@ class KotlinWithJavaCompilationFactory( val result = KotlinWithJavaCompilation(target, name) return result } -} - -class KotlinJvmAndroidCompilationFactory( - val project: Project, - val target: KotlinAndroidTarget -) : KotlinCompilationFactory { - - override val itemClass: Class - get() = KotlinJvmAndroidCompilation::class.java - - override fun create(name: String): KotlinJvmAndroidCompilation = - KotlinJvmAndroidCompilation(target, name) -} - -class KotlinJsCompilationFactory( - val project: Project, - val target: KotlinOnlyTarget -) : KotlinCompilationFactory { - override val itemClass: Class - get() = KotlinJsCompilation::class.java - - override fun create(name: String): KotlinJsCompilation = - KotlinJsCompilation(target, name) -} - -class KotlinNativeCompilationFactory( - val project: Project, - val target: KotlinNativeTarget -) : KotlinCompilationFactory { - - override val itemClass: Class - get() = KotlinNativeCompilation::class.java - - override fun create(name: String): KotlinNativeCompilation = - KotlinNativeCompilation(target, name).apply { - if (name == KotlinCompilation.TEST_COMPILATION_NAME) { - friendCompilationName = KotlinCompilation.MAIN_COMPILATION_NAME - isTestCompilation = true - } - buildTypes = mutableListOf(NativeBuildType.DEBUG, NativeBuildType.RELEASE) - } - } \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinWithJavaCompilationOutput.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinWithJavaCompilationOutput.kt index 4fe268181d2..b474d8f8ec3 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinWithJavaCompilationOutput.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinWithJavaCompilationOutput.kt @@ -5,31 +5,12 @@ package org.jetbrains.kotlin.gradle.plugin.mpp -import org.gradle.api.Project import org.gradle.api.file.ConfigurableFileCollection import org.gradle.api.file.FileCollection import org.jetbrains.kotlin.gradle.plugin.KotlinCompilationOutput import java.io.File import java.util.concurrent.Callable -class DefaultKotlinCompilationOutput( - private val project: Project, - override var resourcesDirProvider: Any -) : KotlinCompilationOutput, Callable { - - override val classesDirs: ConfigurableFileCollection = project.files() - - override val allOutputs = project.files().apply { - from(classesDirs) - from(Callable { resourcesDir }) - } - - override val resourcesDir: File - get() = project.file(resourcesDirProvider) - - override fun call(): FileCollection = allOutputs -} - class KotlinWithJavaCompilationOutput( internal val compilation: KotlinWithJavaCompilation<*> ) : KotlinCompilationOutput, Callable { diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinWithJavaTarget.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinWithJavaTarget.kt index f4bbb5d60f9..cdfa16e6f93 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinWithJavaTarget.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinWithJavaTarget.kt @@ -4,346 +4,12 @@ */ package org.jetbrains.kotlin.gradle.plugin.mpp -import groovy.lang.Closure -import org.gradle.api.* -import org.gradle.api.artifacts.ConfigurablePublishArtifact +import org.gradle.api.NamedDomainObjectContainer +import org.gradle.api.Project import org.gradle.api.artifacts.Dependency -import org.gradle.api.artifacts.PublishArtifact -import org.gradle.api.attributes.Attribute -import org.gradle.api.attributes.AttributeContainer -import org.gradle.api.attributes.Usage.JAVA_API -import org.gradle.api.attributes.Usage.JAVA_RUNTIME_JARS import org.gradle.api.plugins.JavaPlugin -import org.gradle.api.publish.maven.MavenPublication -import org.gradle.util.ConfigureUtil -import org.gradle.util.WrapUtil import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions -import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension -import org.jetbrains.kotlin.gradle.dsl.KotlinNativeBinaryContainer -import org.jetbrains.kotlin.gradle.dsl.kotlinExtension -import org.jetbrains.kotlin.gradle.plugin.* -import org.jetbrains.kotlin.gradle.utils.dashSeparatedName -import org.jetbrains.kotlin.gradle.utils.isGradleVersionAtLeast -import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName -import org.jetbrains.kotlin.konan.target.KonanTarget - -abstract class AbstractKotlinTarget( - final override val project: Project -) : KotlinTarget { - private val attributeContainer = HierarchyAttributeContainer(parent = null) - - override fun getAttributes(): AttributeContainer = attributeContainer - - override val defaultConfigurationName: String - get() = disambiguateName("default") - - override val apiElementsConfigurationName: String - get() = disambiguateName("apiElements") - - override val runtimeElementsConfigurationName: String - get() = disambiguateName("runtimeElements") - - override val artifactsTaskName: String - get() = disambiguateName("jar") - - override fun toString(): String = "target $name ($platformType)" - - override val publishable: Boolean - get() = true - - override val components: Set by lazy { - val mainCompilation = compilations.getByName(KotlinCompilation.MAIN_COMPILATION_NAME) - val usageContexts = createUsageContexts(mainCompilation) - setOf( - if (isGradleVersionAtLeast(4, 7)) { - val componentName = mainCompilation.target.name - createKotlinVariant(componentName, mainCompilation, usageContexts).apply { - sourcesArtifacts = setOf( - sourcesJarArtifact( - mainCompilation, componentName, - dashSeparatedName(target.name.toLowerCase(), componentName.toLowerCase()) - ) - ) - } - } else { - KotlinVariant(mainCompilation, usageContexts) - } - ).also { project.components.addAll(it) } - } - - protected fun createKotlinVariant( - componentName: String, - compilation: KotlinCompilation<*>, - usageContexts: Set - ): KotlinVariant { - - val kotlinExtension = project.kotlinExtension as? KotlinMultiplatformExtension - ?: return KotlinVariantWithCoordinates(compilation, usageContexts) - - if (targetName == KotlinMultiplatformPlugin.METADATA_TARGET_NAME) - return KotlinVariantWithCoordinates(compilation, usageContexts) - - val separateMetadataTarget = kotlinExtension.targets.getByName(KotlinMultiplatformPlugin.METADATA_TARGET_NAME) - - val result = if (kotlinExtension.isGradleMetadataAvailable) { - KotlinVariantWithMetadataVariant(compilation, usageContexts, separateMetadataTarget) - } else { - // we should only add the Kotlin metadata dependency if we publish no Gradle metadata related to Kotlin MPP; - // with metadata, such a dependency would get invalid, since a platform module should only depend on modules for that - // same platform, not Kotlin metadata modules - KotlinVariantWithMetadataDependency(compilation, usageContexts, separateMetadataTarget) - } - - result.componentName = componentName - return result - } - - private fun createUsageContexts( - producingCompilation: KotlinCompilation<*> - ): Set { - // Here, `JAVA_API` and `JAVA_RUNTIME_JARS` are used intentionally as Gradle needs this for - // ordering of the usage contexts (prioritizing the dependencies) when merging them into the POM; - // These Java usages should not be replaced with the custom Kotlin usages. - return listOfNotNull( - JAVA_API to apiElementsConfigurationName, - (JAVA_RUNTIME_JARS to runtimeElementsConfigurationName).takeIf { producingCompilation is KotlinCompilationToRunnableFiles } - ).mapTo(mutableSetOf()) { (usageName, dependenciesConfigurationName) -> - DefaultKotlinUsageContext( - producingCompilation, - project.usageByName(usageName), - dependenciesConfigurationName - ) - } - } - - protected fun sourcesJarArtifact( - producingCompilation: KotlinCompilation<*>, - componentName: String, - artifactNameAppendix: String, - classifierPrefix: String? = null - ): PublishArtifact { - val sourcesJarTask = sourcesJarTask(producingCompilation, componentName, artifactNameAppendix) - val sourceArtifactConfigurationName = producingCompilation.disambiguateName("sourceArtifacts") - return producingCompilation.target.project.run { - (configurations.findByName(sourceArtifactConfigurationName) ?: run { - val configuration = configurations.create(sourceArtifactConfigurationName) { - it.isCanBeResolved = false - it.isCanBeConsumed = false - } - artifacts.add(sourceArtifactConfigurationName, sourcesJarTask) - configuration - }).artifacts.single().apply { - this as ConfigurablePublishArtifact - classifier = dashSeparatedName(classifierPrefix, "sources") - } - } - } - - @Suppress("UNCHECKED_CAST") - internal val publicationConfigureActions = - WrapUtil.toDomainObjectSet(Action::class.java) as DomainObjectSet> - - override fun mavenPublication(action: Action) { - publicationConfigureActions.add(action) - } - - override fun mavenPublication(action: Closure) = - mavenPublication(ConfigureUtil.configureUsing(action)) - - override var preset: KotlinTargetPreset? = null - internal set -} - -internal fun KotlinTarget.disambiguateName(simpleName: String) = - lowerCamelCaseName(targetName, simpleName) - -open class KotlinAndroidTarget( - override val targetName: String, - project: Project -) : AbstractKotlinTarget(project) { - - override var disambiguationClassifier: String? = null - internal set - - override val platformType: KotlinPlatformType - get() = KotlinPlatformType.androidJvm - - private val compilationFactory = KotlinJvmAndroidCompilationFactory(project, this) - - override val compilations: NamedDomainObjectContainer = - project.container(compilationFactory.itemClass, compilationFactory) - - /** Names of the Android library variants that should be published from the target's project within the default publications which are - * set up if the `maven-publish` Gradle plugin is applied. - * - * Item examples: - * * 'release' (in case no product flavors were defined) - * * 'fooRelease' (for the release build type of a flavor 'foo') - * * 'fooBarRelease' (for the release build type multi-dimensional flavors 'foo' and 'bar'). - * - * If set to null, which can also be done with [publishAllLibraryVariants], - * all library variants will be published, but not test or application variants. */ - var publishLibraryVariants: List? = listOf() - // Workaround for Groovy GString items in a list: - set(value) { field = value?.map(Any::toString) } - - /** Add Android library variant names to [publishLibraryVariants]. */ - fun publishLibraryVariants(vararg names: String) { - publishLibraryVariants = publishLibraryVariants.orEmpty() + names - } - - /** Set up all of the Android library variants to be published from this target's project within the default publications, which are - * set up if the `maven-publish` Gradle plugin is applied. This overrides the variants chosen with [publishLibraryVariants] */ - fun publishAllLibraryVariants() { - publishLibraryVariants = null - } - - /** If true, a publication will be created per merged product flavor, with the build types used as classifiers for the artifacts - * published within each publication. If set to false, each Android variant will have a separate publication. */ - var publishLibraryVariantsGroupedByFlavor = false - - private fun checkPublishLibraryVariantsExist() { - // Capture type parameter T - fun AbstractAndroidProjectHandler.getLibraryVariantNames() = - mutableSetOf().apply { - forEachVariant(project) { - if (getLibraryOutputTask(it) != null) - add(getVariantName(it)) - } - } - - val variantNames = - KotlinAndroidPlugin.androidTargetHandler(project.getKotlinPluginVersion()!!, this) - .getLibraryVariantNames() - - val missingVariants = - publishLibraryVariants?.minus(variantNames).orEmpty() - - if (missingVariants.isNotEmpty()) - throw InvalidUserDataException( - "Kotlin target '$targetName' tried to set up publishing for Android build variants that are not library variants " + - "or do not exist:\n" + missingVariants.joinToString("\n") { "* $it" } + - "\nCheck the 'publishLibraryVariants' property, it should point to existing Android library variants. Publishing " + - "of application and test variants is not supported." - ) - } - - override val components by lazy { - checkPublishLibraryVariantsExist() - - KotlinAndroidPlugin.androidTargetHandler(project.getKotlinPluginVersion()!!, this).doCreateComponents() - .also { project.components.addAll(it) } - } - - // Capture the type parameter T for `AbstractAndroidProjectHandler` - private fun AbstractAndroidProjectHandler.doCreateComponents(): Set { - if (!isGradleVersionAtLeast(4, 7)) - return emptySet() - - val publishableVariants = mutableListOf() - .apply { forEachVariant(project) { add(it) } } - .toList() // Defensive copy against unlikely modification by the lambda that captures the list above in forEachVariant { } - .filter { getLibraryOutputTask(it) != null && publishLibraryVariants?.contains(getVariantName(it)) ?: true } - - val publishableVariantGroups = publishableVariants.groupBy { variant -> - val flavorNames = getFlavorNames(variant) - if (publishLibraryVariantsGroupedByFlavor) { - // For each flavor, we group its variants (which differ only in the build type) in a single component in order to publish - // all of the build types of the flavor as a single module with the build type as the classifier of the artifacts - flavorNames - } else { - flavorNames + getBuildTypeName(variant) - } - } - - return publishableVariantGroups.map { (flavorGroupNameParts, androidVariants) -> - val nestedVariants = androidVariants.mapTo(mutableSetOf()) { androidVariant -> - val androidVariantName = getVariantName(androidVariant) - val compilation = compilations.getByName(androidVariantName) - - val flavorNames = getFlavorNames(androidVariant) - val buildTypeName = getBuildTypeName(androidVariant) - - val artifactClassifier = buildTypeName.takeIf { it != "release" && publishLibraryVariantsGroupedByFlavor } - - val usageContexts = createAndroidUsageContexts(androidVariant, compilation, artifactClassifier) - createKotlinVariant( - lowerCamelCaseName(compilation.target.name, *flavorGroupNameParts.toTypedArray()), - compilation, - usageContexts - ).apply { - sourcesArtifacts = setOf( - sourcesJarArtifact( - compilation, compilation.disambiguateName(""), - dashSeparatedName( - compilation.target.name.toLowerCase(), - *flavorNames.map { it.toLowerCase() }.toTypedArray(), - buildTypeName.takeIf { it != "release" }?.toLowerCase() - ), - classifierPrefix = artifactClassifier - ) - ) - - if (!publishLibraryVariantsGroupedByFlavor) { - defaultArtifactIdSuffix = - dashSeparatedName( - (getFlavorNames(androidVariant) + getBuildTypeName(androidVariant).takeIf { it != "release" }) - .map { it?.toLowerCase() } - ).takeIf { it.isNotEmpty() } - } - } - } - - if (publishLibraryVariantsGroupedByFlavor) { - JointAndroidKotlinTargetComponent( - this@KotlinAndroidTarget, - nestedVariants, - flavorGroupNameParts, - nestedVariants.flatMap { it.sourcesArtifacts }.toSet() - ) - } else { - nestedVariants.single() - } as KotlinTargetComponent - }.toSet() - } - - private fun AbstractAndroidProjectHandler.createAndroidUsageContexts( - variant: T, - compilation: KotlinCompilation<*>, - artifactClassifier: String? - ): Set { - val variantName = getVariantName(variant) - val outputTask = getLibraryOutputTask(variant) ?: return emptySet() - val artifact = run { - val archivesConfigurationName = lowerCamelCaseName(targetName, variantName, "archives") - project.configurations.maybeCreate(archivesConfigurationName).apply { - isCanBeConsumed = false - isCanBeResolved = false - } - project.artifacts.add(archivesConfigurationName, outputTask) { artifact -> - artifact.classifier = artifactClassifier - } - } - - val apiElementsConfigurationName = lowerCamelCaseName(variantName, "apiElements") - val runtimeElementsConfigurationName = lowerCamelCaseName(variantName, "runtimeElements") - - // Here, `JAVA_API` and `JAVA_RUNTIME_JARS` are used intentionally as Gradle needs this for - // ordering of the usage contexts (prioritizing the dependencies) when merging them into the POM; - // These Java usages should not be replaced with the custom Kotlin usages. - return listOf( - apiElementsConfigurationName to JAVA_API, - runtimeElementsConfigurationName to JAVA_RUNTIME_JARS - ).mapTo(mutableSetOf()) { (dependencyConfigurationName, usageName) -> - DefaultKotlinUsageContext( - compilation, - project.usageByName(usageName), - dependencyConfigurationName, - overrideConfigurationArtifacts = setOf(artifact) - ) - } - } -} +import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType open class KotlinWithJavaTarget( project: Project, @@ -372,66 +38,3 @@ open class KotlinWithJavaTarget( KotlinWithJavaCompilationFactory(project, this) ) } - -open class KotlinOnlyTarget>( - project: Project, - override val platformType: KotlinPlatformType -) : AbstractKotlinTarget(project) { - - override lateinit var compilations: NamedDomainObjectContainer - internal set - - override lateinit var targetName: String - internal set - - override var disambiguationClassifier: String? = null - internal set -} - -class KotlinNativeTarget( - project: Project, - val konanTarget: KonanTarget -) : KotlinOnlyTarget(project, KotlinPlatformType.native) { - - init { - attributes.attribute(konanTargetAttribute, konanTarget.name) - } - - val binaries = if(isGradleVersionAtLeast(4, 2)) { - // Use newInstance to allow accessing binaries by their names in Groovy using the extension mechanism. - project.objects.newInstance(KotlinNativeBinaryContainer::class.java, this, WrapUtil.toDomainObjectSet(NativeBinary::class.java)) - } else { - KotlinNativeBinaryContainer(this, WrapUtil.toDomainObjectSet(NativeBinary::class.java)) - } - - fun binaries(configure: KotlinNativeBinaryContainer.() -> Unit) { - binaries.configure() - } - - fun binaries(configure: Closure<*>) { - ConfigureUtil.configure(configure, binaries) - } - - override val artifactsTaskName: String - get() = disambiguateName("binaries") - - override val publishable: Boolean - get() = konanTarget.enabledOnCurrentHost - - // User-visible constants - val DEBUG = NativeBuildType.DEBUG - val RELEASE = NativeBuildType.RELEASE - - val EXECUTABLE = NativeOutputKind.EXECUTABLE - val FRAMEWORK = NativeOutputKind.FRAMEWORK - val DYNAMIC = NativeOutputKind.DYNAMIC - val STATIC = NativeOutputKind.STATIC - - companion object { - val konanTargetAttribute = Attribute.of( - "org.jetbrains.kotlin.native.target", - String::class.java - ) - } -} - diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/kotlinCompilationOutputs.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/kotlinCompilationOutputs.kt index 4fe268181d2..d8b37f5eb68 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/kotlinCompilationOutputs.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/kotlinCompilationOutputs.kt @@ -28,29 +28,4 @@ class DefaultKotlinCompilationOutput( get() = project.file(resourcesDirProvider) override fun call(): FileCollection = allOutputs -} - -class KotlinWithJavaCompilationOutput( - internal val compilation: KotlinWithJavaCompilation<*> -) : KotlinCompilationOutput, Callable { - - private val javaSourceSetOutput - get() = compilation.javaSourceSet.output - - override val resourcesDir: File - get() = javaSourceSetOutput.resourcesDir!! - - override var resourcesDirProvider: Any - get() = javaSourceSetOutput.resourcesDir!! - set(value) { - javaSourceSetOutput.setResourcesDir(value) - } - - override val classesDirs: ConfigurableFileCollection = - javaSourceSetOutput.classesDirs as ConfigurableFileCollection - - override val allOutputs: FileCollection - get() = javaSourceSetOutput - - override fun call(): FileCollection = allOutputs -} +} \ No newline at end of file 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 1284fe446f3..10dcf6b7fe2 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 @@ -201,255 +201,6 @@ internal fun KotlinCompilation<*>.disambiguateName(simpleName: String): String { ) } -open class KotlinJvmCompilation( - target: KotlinTarget, - name: String -) : AbstractKotlinCompilationToRunnableFiles(target, name), KotlinCompilationWithResources { - override val processResourcesTaskName: String - get() = disambiguateName("processResources") - - override val compileKotlinTask: org.jetbrains.kotlin.gradle.tasks.KotlinCompile - get() = super.compileKotlinTask as org.jetbrains.kotlin.gradle.tasks.KotlinCompile -} - -class KotlinWithJavaCompilation( - target: KotlinWithJavaTarget, - name: String -) : AbstractKotlinCompilationToRunnableFiles(target, name), KotlinCompilationWithResources { - lateinit var javaSourceSet: SourceSet - - override val output: KotlinCompilationOutput by lazy { KotlinWithJavaCompilationOutput(this) } - - override val processResourcesTaskName: String - get() = javaSourceSet.processResourcesTaskName - - override var runtimeDependencyFiles: FileCollection - get() = javaSourceSet.runtimeClasspath - set(value) { - javaSourceSet.runtimeClasspath = value - } - - override val runtimeDependencyConfigurationName: String - get() = javaSourceSet.runtimeClasspathConfigurationName - - override val compileDependencyConfigurationName: String - get() = javaSourceSet.compileClasspathConfigurationName - - override val runtimeOnlyConfigurationName: String - get() = javaSourceSet.runtimeOnlyConfigurationName - - override val implementationConfigurationName: String - get() = javaSourceSet.implementationConfigurationName - - override val apiConfigurationName: String - get() = javaSourceSet.apiConfigurationName - - override val compileOnlyConfigurationName: String - get() = javaSourceSet.compileOnlyConfigurationName - - override val compileAllTaskName: String - get() = javaSourceSet.classesTaskName - - override var compileDependencyFiles: FileCollection - get() = javaSourceSet.compileClasspath - set(value) { - javaSourceSet.compileClasspath = value - } - - fun source(javaSourceSet: SourceSet) { - with(target.project) { - afterEvaluate { - (tasks.getByName(compileKotlinTaskName) as AbstractKotlinCompile<*>).source(javaSourceSet.java) - } - } - } -} - -class KotlinJvmAndroidCompilation( - target: KotlinAndroidTarget, - name: String -) : AbstractKotlinCompilationToRunnableFiles(target, name) { - override val compileKotlinTask: org.jetbrains.kotlin.gradle.tasks.KotlinCompile - get() = super.compileKotlinTask as org.jetbrains.kotlin.gradle.tasks.KotlinCompile - - override val relatedConfigurationNames: List - get() = super.relatedConfigurationNames + listOf("${name}ApiElements", "${name}RuntimeElements") -} - -class KotlinJsCompilation( - target: KotlinTarget, - name: String -) : AbstractKotlinCompilationToRunnableFiles(target, name), KotlinCompilationWithResources { - override val processResourcesTaskName: String - get() = disambiguateName("processResources") - - override val compileKotlinTask: Kotlin2JsCompile - get() = super.compileKotlinTask as Kotlin2JsCompile -} - -class KotlinCommonCompilation( - target: KotlinTarget, - name: String -) : AbstractKotlinCompilation(target, name) { - override val compileKotlinTask: KotlinCompileCommon - get() = super.compileKotlinTask as KotlinCompileCommon - - // TODO once we properly compile metadata for each source set, the default source sets will likely become just the source sets - // which are transformed to metadata - private val commonSourceSetName = when (compilationName) { - KotlinCompilation.MAIN_COMPILATION_NAME -> KotlinSourceSet.COMMON_MAIN_SOURCE_SET_NAME - else -> error("Custom metadata compilations are not supported yet") - } - - override val defaultSourceSet: KotlinSourceSet - get() = target.project.kotlinExtension.sourceSets.getByName(commonSourceSetName) -} - -class KotlinNativeCompilation( - override val target: KotlinNativeTarget, - name: String -) : AbstractKotlinCompilation(target, name), KotlinCompilationWithResources { - - override val kotlinOptions: KotlinCommonOptions - get() = compileKotlinTask.kotlinOptions - - override val compileKotlinTask: KotlinNativeCompile - get() = super.compileKotlinTask as KotlinNativeCompile - - private val project: Project - get() = target.project - - // A collection containing all source sets used by this compilation - // (taking into account dependencies between source sets). Used by both compilation - // and linking tasks. Unlike kotlinSourceSets, includes dependency source sets. - // TODO: Move into the compilation task when the linking task does klib linking instead of compilation. - internal val allSources: MutableSet = mutableSetOf() - - // TODO: Move into the compilation task when the linking task does klib linking instead of compilation. - internal val commonSources: MutableSet = mutableSetOf() - - var isTestCompilation = false - - var friendCompilationName: String? = null - - internal val friendCompilation: KotlinNativeCompilation? - get() = friendCompilationName?.let { - target.compilations.getByName(it) - } - - // Used only to support the old APIs. TODO: Remove when the old APIs are removed. - internal val binaries = mutableMapOf, NativeBinary>() - - // Native-specific DSL. - var extraOpts = mutableListOf() - - fun extraOpts(vararg values: Any) = extraOpts(values.toList()) - fun extraOpts(values: List) { - extraOpts.addAll(values.map { it.toString() }) - } - - var buildTypes = mutableListOf() - var outputKinds = mutableListOf() - - fun outputKind(kind: NativeOutputKind) = outputKinds.add(kind) - - fun outputKinds(vararg kinds: NativeOutputKind) { - outputKinds = kinds.toMutableList() - } - - fun outputKinds(vararg kinds: String) { - outputKinds = kinds.map { NativeOutputKind.valueOf(it.toUpperCase()) }.toMutableList() - } - - fun outputKinds(kinds: List) { - outputKinds = kinds.map { - when (it) { - is NativeOutputKind -> it - is String -> NativeOutputKind.valueOf(it.toUpperCase()) - else -> error("Cannot use $it as an output kind") - } - }.toMutableList() - } - - var entryPoint: String? = null - fun entryPoint(value: String) { - entryPoint = value - } - - // Interop DSL. - val cinterops = project.container(DefaultCInteropSettings::class.java) { cinteropName -> - DefaultCInteropSettings(project, cinteropName, this) - } - - var linkerOpts = mutableListOf() - - fun cinterops(action: NamedDomainObjectContainer.() -> Unit) = cinterops.action() - fun cinterops(action: Closure) = cinterops(ConfigureUtil.configureUsing(action)) - fun cinterops(action: Action>) = action.execute(cinterops) - - fun linkerOpts(vararg values: String) = linkerOpts(values.toList()) - fun linkerOpts(values: List) { - linkerOpts.addAll(values) - } - - // Task accessors. - fun findLinkTask(kind: NativeOutputKind, buildType: NativeBuildType): KotlinNativeLink? = binaries[kind to buildType]?.linkTask - - fun getLinkTask(kind: NativeOutputKind, buildType: NativeBuildType): KotlinNativeLink = - findLinkTask(kind, buildType) - ?: throw IllegalArgumentException("Cannot find a link task for the binary kind '$kind' and the build type '$buildType'") - - fun findLinkTask(kind: String, buildType: String) = - findLinkTask(NativeOutputKind.valueOf(kind.toUpperCase()), NativeBuildType.valueOf(buildType.toUpperCase())) - - fun getLinkTask(kind: String, buildType: String) = - getLinkTask(NativeOutputKind.valueOf(kind.toUpperCase()), NativeBuildType.valueOf(buildType.toUpperCase())) - - fun findBinary(kind: NativeOutputKind, buildType: NativeBuildType): File? = findLinkTask(kind, buildType)?.outputFile?.get() - - fun getBinary(kind: NativeOutputKind, buildType: NativeBuildType): File = getLinkTask(kind, buildType).outputFile.get() - - fun findBinary(kind: String, buildType: String) = - findBinary(NativeOutputKind.valueOf(kind.toUpperCase()), NativeBuildType.valueOf(buildType.toUpperCase())) - - fun getBinary(kind: String, buildType: String) = - getBinary(NativeOutputKind.valueOf(kind.toUpperCase()), NativeBuildType.valueOf(buildType.toUpperCase())) - - // Naming - override val processResourcesTaskName: String - get() = disambiguateName("processResources") - - fun linkTaskName(kind: NativeOutputKind, buildType: NativeBuildType): String = - lowerCamelCaseName( - "link", - KotlinNativeBinaryContainer.generateBinaryName(compilationName, buildType, kind.taskNameClassifier), - target.targetName - ) - - fun linkTaskName(kind: String, buildType: String) = - linkTaskName(NativeOutputKind.valueOf(kind.toUpperCase()), NativeBuildType.valueOf(buildType.toUpperCase())) - - override val compileDependencyConfigurationName: String - get() = lowerCamelCaseName( - target.disambiguationClassifier, - compilationName.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME }.orEmpty(), - "compileKlibraries" - ) - - override val compileAllTaskName: String - get() = lowerCamelCaseName(target.disambiguationClassifier, compilationName, "klibrary") - - val binariesTaskName: String - get() = lowerCamelCaseName(target.disambiguationClassifier, compilationName, "binaries") - - override fun addSourcesToCompileTask(sourceSet: KotlinSourceSet, addAsCommonSources: Boolean) { - allSources.add(sourceSet.kotlin) - if (addAsCommonSources) { - commonSources.add(sourceSet.kotlin) - } - } -} - private object CompilationSourceSetUtil { // Cache the results per project private val projectSourceSetsInMultipleCompilationsCache = WeakHashMap>() diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/kotlinTargetPresets.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/kotlinTargetPresets.kt index 921736ad861..ece5062e51d 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/kotlinTargetPresets.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/kotlinTargetPresets.kt @@ -6,25 +6,9 @@ package org.jetbrains.kotlin.gradle.plugin.mpp import org.gradle.api.Project -import org.gradle.api.artifacts.Dependency import org.gradle.api.internal.file.FileResolver -import org.gradle.api.plugins.JavaPlugin import org.gradle.internal.reflect.Instantiator -import org.jetbrains.kotlin.compilerRunner.KotlinNativeProjectProperty -import org.jetbrains.kotlin.compilerRunner.hasProperty -import org.jetbrains.kotlin.compilerRunner.konanHome -import org.jetbrains.kotlin.gradle.dsl.KotlinCompile -import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptions -import org.jetbrains.kotlin.gradle.dsl.kotlinExtension import org.jetbrains.kotlin.gradle.plugin.* -import org.jetbrains.kotlin.gradle.plugin.sources.applyLanguageSettingsToKotlinTask -import org.jetbrains.kotlin.gradle.tasks.KotlinTasksProvider -import org.jetbrains.kotlin.gradle.utils.NativeCompilerDownloader -import org.jetbrains.kotlin.konan.KonanVersion -import org.jetbrains.kotlin.konan.target.HostManager -import org.jetbrains.kotlin.konan.target.KonanTarget -import java.io.File -import java.util.* abstract class KotlinOnlyTargetPreset>( protected val project: Project, @@ -61,270 +45,4 @@ abstract class KotlinOnlyTargetPreset>( protected abstract fun createCompilationFactory(forTarget: KotlinOnlyTarget): KotlinCompilationFactory protected abstract val platformType: KotlinPlatformType internal abstract fun buildCompilationProcessor(compilation: T): KotlinSourceSetProcessor<*> -} - -class KotlinMetadataTargetPreset( - project: Project, - instantiator: Instantiator, - fileResolver: FileResolver, - kotlinPluginVersion: String -) : KotlinOnlyTargetPreset( - project, - instantiator, - fileResolver, - kotlinPluginVersion -) { - override fun getName(): String = PRESET_NAME - - override fun createCompilationFactory( - forTarget: KotlinOnlyTarget - ): KotlinCompilationFactory = - KotlinCommonCompilationFactory(forTarget) - - override val platformType: KotlinPlatformType - get() = KotlinPlatformType.common - - override fun buildCompilationProcessor(compilation: KotlinCommonCompilation): KotlinSourceSetProcessor<*> { - val tasksProvider = KotlinTasksProvider(compilation.target.targetName) - return KotlinCommonSourceSetProcessor(project, compilation, tasksProvider, kotlinPluginVersion) - } - - companion object { - const val PRESET_NAME = "metadata" - } - - override fun createKotlinTargetConfigurator(): KotlinTargetConfigurator = - KotlinTargetConfigurator(createDefaultSourceSets = false, createTestCompilation = false) - - override fun createTarget(name: String): KotlinOnlyTarget = - super.createTarget(name).apply { - val mainCompilation = compilations.getByName(KotlinCompilation.MAIN_COMPILATION_NAME) - val commonMainSourceSet = project.kotlinExtension.sourceSets.getByName(KotlinSourceSet.COMMON_MAIN_SOURCE_SET_NAME) - - mainCompilation.source(commonMainSourceSet) - - project.afterEvaluate { - // Since there's no default source set, apply language settings from commonMain: - val compileKotlinMetadata = project.tasks.getByName(mainCompilation.compileKotlinTaskName) as KotlinCompile<*> - applyLanguageSettingsToKotlinTask(commonMainSourceSet.languageSettings, compileKotlinMetadata) - } - } -} - -class KotlinJvmTargetPreset( - project: Project, - instantiator: Instantiator, - fileResolver: FileResolver, - kotlinPluginVersion: String -) : KotlinOnlyTargetPreset( - project, - instantiator, - fileResolver, - kotlinPluginVersion -) { - override fun getName(): String = PRESET_NAME - - override fun createCompilationFactory(forTarget: KotlinOnlyTarget): KotlinCompilationFactory = - KotlinJvmCompilationFactory(forTarget) - - override val platformType: KotlinPlatformType - get() = KotlinPlatformType.jvm - - override fun buildCompilationProcessor(compilation: KotlinJvmCompilation): KotlinSourceSetProcessor<*> { - val tasksProvider = KotlinTasksProvider(compilation.target.targetName) - return Kotlin2JvmSourceSetProcessor(project, tasksProvider, compilation, kotlinPluginVersion) - } - - companion object { - const val PRESET_NAME = "jvm" - } -} - -class KotlinJsTargetPreset( - project: Project, - instantiator: Instantiator, - fileResolver: FileResolver, - kotlinPluginVersion: String -) : KotlinOnlyTargetPreset( - project, - instantiator, - fileResolver, - kotlinPluginVersion -) { - override fun getName(): String = PRESET_NAME - - override fun createCompilationFactory(forTarget: KotlinOnlyTarget) = - KotlinJsCompilationFactory(project, forTarget) - - override val platformType: KotlinPlatformType - get() = KotlinPlatformType.js - - override fun buildCompilationProcessor(compilation: KotlinJsCompilation): KotlinSourceSetProcessor<*> { - val tasksProvider = KotlinTasksProvider(compilation.target.targetName) - return Kotlin2JsSourceSetProcessor(project, tasksProvider, compilation, kotlinPluginVersion) - } - - companion object { - const val PRESET_NAME = "js" - } -} - -class KotlinAndroidTargetPreset( - private val project: Project, - private val kotlinPluginVersion: String -) : KotlinTargetPreset { - - override fun getName(): String = PRESET_NAME - - override fun createTarget(name: String): KotlinAndroidTarget { - val result = KotlinAndroidTarget(name, project).apply { - disambiguationClassifier = name - preset = this@KotlinAndroidTargetPreset - } - - KotlinAndroidPlugin.applyToTarget(kotlinPluginVersion, result) - return result - } - - companion object { - const val PRESET_NAME = "android" - } -} - -class KotlinJvmWithJavaTargetPreset( - private val project: Project, - private val kotlinPluginVersion: String -) : KotlinTargetPreset> { - - override fun getName(): String = PRESET_NAME - - override fun createTarget(name: String): KotlinWithJavaTarget { - project.plugins.apply(JavaPlugin::class.java) - - val target = KotlinWithJavaTarget(project, KotlinPlatformType.jvm, name).apply { - disambiguationClassifier = name - preset = this@KotlinJvmWithJavaTargetPreset - } - - AbstractKotlinPlugin.configureTarget(target) { compilation -> - Kotlin2JvmSourceSetProcessor(project, KotlinTasksProvider(name), compilation, kotlinPluginVersion) - } - - target.compilations.getByName("test").run { - val main = target.compilations.getByName(KotlinCompilation.MAIN_COMPILATION_NAME) - - compileDependencyFiles = project.files( - main.output.allOutputs, - project.configurations.maybeCreate(compileDependencyConfigurationName) - ) - runtimeDependencyFiles = project.files( - output.allOutputs, - main.output.allOutputs, - project.configurations.maybeCreate(runtimeDependencyConfigurationName) - ) - } - - return target - } - - companion object { - const val PRESET_NAME = "jvmWithJava" - } -} - -class KotlinNativeTargetPreset( - private val name: String, - val project: Project, - val konanTarget: KonanTarget, - private val kotlinPluginVersion: String -) : KotlinTargetPreset { - - init { - // This is required to obtain Kotlin/Native home in CLion plugin: - setupNativeHomePrivateProperty() - } - - override fun getName(): String = name - - private fun setupNativeHomePrivateProperty() = with(project) { - if (!hasProperty(KOTLIN_NATIVE_HOME_PRIVATE_PROPERTY)) - extensions.extraProperties.set(KOTLIN_NATIVE_HOME_PRIVATE_PROPERTY, konanHome) - } - - private fun setupNativeCompiler() = with(project) { - if (!hasProperty(KotlinNativeProjectProperty.KONAN_HOME_OVERRIDE)) { - NativeCompilerDownloader(this).downloadIfNeeded() - logger.info("Kotlin/Native distribution: $konanHome") - } else { - logger.info("User-provided Kotlin/Native distribution: $konanHome") - } - } - - // We declare default K/N dependencies as files to avoid searching them in remote repos (see KT-28128). - private fun defaultLibs(target: KonanTarget? = null): List = with(project) { - - val relPath = if (target != null) "platform/${target.name}" else "common" - - file("$konanHome/klib/$relPath") - .listFiles { file -> file.isDirectory } - ?.sortedBy { dir -> dir.name.toLowerCase() } - ?.map { dir -> dependencies.create(files(dir)) } ?: emptyList() - } - - override fun createTarget(name: String): KotlinNativeTarget { - setupNativeCompiler() - - val result = KotlinNativeTarget(project, konanTarget).apply { - targetName = name - disambiguationClassifier = name - preset = this@KotlinNativeTargetPreset - - val compilationFactory = KotlinNativeCompilationFactory(project, this) - compilations = project.container(compilationFactory.itemClass, compilationFactory) - } - - KotlinNativeTargetConfigurator(kotlinPluginVersion).configureTarget(result) - - // Allow IDE to resolve the libraries provided by the compiler by adding them into dependencies. - result.compilations.all { compilation -> - val target = compilation.target.konanTarget - // First, put common libs: - defaultLibs().forEach { - project.dependencies.add(compilation.compileDependencyConfigurationName, it) - } - // Then, platform-specific libs: - defaultLibs(target).forEach { - project.dependencies.add(compilation.compileDependencyConfigurationName, it) - } - } - - if (!konanTarget.enabledOnCurrentHost) { - with(HostManager()) { - val supportedHosts = enabledTargetsByHost.filterValues { konanTarget in it }.keys - val supportedHostsString = - if (supportedHosts.size == 1) - "a ${supportedHosts.single()} host" else - "one of the host platforms: ${supportedHosts.joinToString(", ")}" - project.logger.warn( - "Target '$name' for platform ${konanTarget} is ignored during build on this ${HostManager.host} machine. " + - "You can build it with $supportedHostsString." - ) - } - } - - return result - } - - companion object { - private const val KOTLIN_NATIVE_HOME_PRIVATE_PROPERTY = "konanHome" - } -} - -internal val KonanTarget.isCurrentHost: Boolean - get() = this == HostManager.host - -internal val KonanTarget.enabledOnCurrentHost - get() = HostManager().isEnabled(this) - -internal val KotlinNativeCompilation.isMainCompilation: Boolean - get() = name == KotlinCompilation.MAIN_COMPILATION_NAME +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/kotlinTargets.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/kotlinTargets.kt index f4bbb5d60f9..a6de9cf8aa9 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/kotlinTargets.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/kotlinTargets.kt @@ -5,27 +5,24 @@ package org.jetbrains.kotlin.gradle.plugin.mpp import groovy.lang.Closure -import org.gradle.api.* +import org.gradle.api.Action +import org.gradle.api.DomainObjectSet +import org.gradle.api.NamedDomainObjectContainer +import org.gradle.api.Project import org.gradle.api.artifacts.ConfigurablePublishArtifact -import org.gradle.api.artifacts.Dependency import org.gradle.api.artifacts.PublishArtifact -import org.gradle.api.attributes.Attribute import org.gradle.api.attributes.AttributeContainer import org.gradle.api.attributes.Usage.JAVA_API import org.gradle.api.attributes.Usage.JAVA_RUNTIME_JARS -import org.gradle.api.plugins.JavaPlugin import org.gradle.api.publish.maven.MavenPublication import org.gradle.util.ConfigureUtil import org.gradle.util.WrapUtil -import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension -import org.jetbrains.kotlin.gradle.dsl.KotlinNativeBinaryContainer import org.jetbrains.kotlin.gradle.dsl.kotlinExtension import org.jetbrains.kotlin.gradle.plugin.* import org.jetbrains.kotlin.gradle.utils.dashSeparatedName import org.jetbrains.kotlin.gradle.utils.isGradleVersionAtLeast import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName -import org.jetbrains.kotlin.konan.target.KonanTarget abstract class AbstractKotlinTarget( final override val project: Project @@ -157,222 +154,6 @@ abstract class AbstractKotlinTarget( internal fun KotlinTarget.disambiguateName(simpleName: String) = lowerCamelCaseName(targetName, simpleName) -open class KotlinAndroidTarget( - override val targetName: String, - project: Project -) : AbstractKotlinTarget(project) { - - override var disambiguationClassifier: String? = null - internal set - - override val platformType: KotlinPlatformType - get() = KotlinPlatformType.androidJvm - - private val compilationFactory = KotlinJvmAndroidCompilationFactory(project, this) - - override val compilations: NamedDomainObjectContainer = - project.container(compilationFactory.itemClass, compilationFactory) - - /** Names of the Android library variants that should be published from the target's project within the default publications which are - * set up if the `maven-publish` Gradle plugin is applied. - * - * Item examples: - * * 'release' (in case no product flavors were defined) - * * 'fooRelease' (for the release build type of a flavor 'foo') - * * 'fooBarRelease' (for the release build type multi-dimensional flavors 'foo' and 'bar'). - * - * If set to null, which can also be done with [publishAllLibraryVariants], - * all library variants will be published, but not test or application variants. */ - var publishLibraryVariants: List? = listOf() - // Workaround for Groovy GString items in a list: - set(value) { field = value?.map(Any::toString) } - - /** Add Android library variant names to [publishLibraryVariants]. */ - fun publishLibraryVariants(vararg names: String) { - publishLibraryVariants = publishLibraryVariants.orEmpty() + names - } - - /** Set up all of the Android library variants to be published from this target's project within the default publications, which are - * set up if the `maven-publish` Gradle plugin is applied. This overrides the variants chosen with [publishLibraryVariants] */ - fun publishAllLibraryVariants() { - publishLibraryVariants = null - } - - /** If true, a publication will be created per merged product flavor, with the build types used as classifiers for the artifacts - * published within each publication. If set to false, each Android variant will have a separate publication. */ - var publishLibraryVariantsGroupedByFlavor = false - - private fun checkPublishLibraryVariantsExist() { - // Capture type parameter T - fun AbstractAndroidProjectHandler.getLibraryVariantNames() = - mutableSetOf().apply { - forEachVariant(project) { - if (getLibraryOutputTask(it) != null) - add(getVariantName(it)) - } - } - - val variantNames = - KotlinAndroidPlugin.androidTargetHandler(project.getKotlinPluginVersion()!!, this) - .getLibraryVariantNames() - - val missingVariants = - publishLibraryVariants?.minus(variantNames).orEmpty() - - if (missingVariants.isNotEmpty()) - throw InvalidUserDataException( - "Kotlin target '$targetName' tried to set up publishing for Android build variants that are not library variants " + - "or do not exist:\n" + missingVariants.joinToString("\n") { "* $it" } + - "\nCheck the 'publishLibraryVariants' property, it should point to existing Android library variants. Publishing " + - "of application and test variants is not supported." - ) - } - - override val components by lazy { - checkPublishLibraryVariantsExist() - - KotlinAndroidPlugin.androidTargetHandler(project.getKotlinPluginVersion()!!, this).doCreateComponents() - .also { project.components.addAll(it) } - } - - // Capture the type parameter T for `AbstractAndroidProjectHandler` - private fun AbstractAndroidProjectHandler.doCreateComponents(): Set { - if (!isGradleVersionAtLeast(4, 7)) - return emptySet() - - val publishableVariants = mutableListOf() - .apply { forEachVariant(project) { add(it) } } - .toList() // Defensive copy against unlikely modification by the lambda that captures the list above in forEachVariant { } - .filter { getLibraryOutputTask(it) != null && publishLibraryVariants?.contains(getVariantName(it)) ?: true } - - val publishableVariantGroups = publishableVariants.groupBy { variant -> - val flavorNames = getFlavorNames(variant) - if (publishLibraryVariantsGroupedByFlavor) { - // For each flavor, we group its variants (which differ only in the build type) in a single component in order to publish - // all of the build types of the flavor as a single module with the build type as the classifier of the artifacts - flavorNames - } else { - flavorNames + getBuildTypeName(variant) - } - } - - return publishableVariantGroups.map { (flavorGroupNameParts, androidVariants) -> - val nestedVariants = androidVariants.mapTo(mutableSetOf()) { androidVariant -> - val androidVariantName = getVariantName(androidVariant) - val compilation = compilations.getByName(androidVariantName) - - val flavorNames = getFlavorNames(androidVariant) - val buildTypeName = getBuildTypeName(androidVariant) - - val artifactClassifier = buildTypeName.takeIf { it != "release" && publishLibraryVariantsGroupedByFlavor } - - val usageContexts = createAndroidUsageContexts(androidVariant, compilation, artifactClassifier) - createKotlinVariant( - lowerCamelCaseName(compilation.target.name, *flavorGroupNameParts.toTypedArray()), - compilation, - usageContexts - ).apply { - sourcesArtifacts = setOf( - sourcesJarArtifact( - compilation, compilation.disambiguateName(""), - dashSeparatedName( - compilation.target.name.toLowerCase(), - *flavorNames.map { it.toLowerCase() }.toTypedArray(), - buildTypeName.takeIf { it != "release" }?.toLowerCase() - ), - classifierPrefix = artifactClassifier - ) - ) - - if (!publishLibraryVariantsGroupedByFlavor) { - defaultArtifactIdSuffix = - dashSeparatedName( - (getFlavorNames(androidVariant) + getBuildTypeName(androidVariant).takeIf { it != "release" }) - .map { it?.toLowerCase() } - ).takeIf { it.isNotEmpty() } - } - } - } - - if (publishLibraryVariantsGroupedByFlavor) { - JointAndroidKotlinTargetComponent( - this@KotlinAndroidTarget, - nestedVariants, - flavorGroupNameParts, - nestedVariants.flatMap { it.sourcesArtifacts }.toSet() - ) - } else { - nestedVariants.single() - } as KotlinTargetComponent - }.toSet() - } - - private fun AbstractAndroidProjectHandler.createAndroidUsageContexts( - variant: T, - compilation: KotlinCompilation<*>, - artifactClassifier: String? - ): Set { - val variantName = getVariantName(variant) - val outputTask = getLibraryOutputTask(variant) ?: return emptySet() - val artifact = run { - val archivesConfigurationName = lowerCamelCaseName(targetName, variantName, "archives") - project.configurations.maybeCreate(archivesConfigurationName).apply { - isCanBeConsumed = false - isCanBeResolved = false - } - project.artifacts.add(archivesConfigurationName, outputTask) { artifact -> - artifact.classifier = artifactClassifier - } - } - - val apiElementsConfigurationName = lowerCamelCaseName(variantName, "apiElements") - val runtimeElementsConfigurationName = lowerCamelCaseName(variantName, "runtimeElements") - - // Here, `JAVA_API` and `JAVA_RUNTIME_JARS` are used intentionally as Gradle needs this for - // ordering of the usage contexts (prioritizing the dependencies) when merging them into the POM; - // These Java usages should not be replaced with the custom Kotlin usages. - return listOf( - apiElementsConfigurationName to JAVA_API, - runtimeElementsConfigurationName to JAVA_RUNTIME_JARS - ).mapTo(mutableSetOf()) { (dependencyConfigurationName, usageName) -> - DefaultKotlinUsageContext( - compilation, - project.usageByName(usageName), - dependencyConfigurationName, - overrideConfigurationArtifacts = setOf(artifact) - ) - } - } -} - -open class KotlinWithJavaTarget( - project: Project, - override val platformType: KotlinPlatformType, - override val targetName: String -) : AbstractKotlinTarget(project) { - override var disambiguationClassifier: String? = null - internal set - - override val defaultConfigurationName: String - get() = Dependency.DEFAULT_CONFIGURATION - - override val apiElementsConfigurationName: String - get() = JavaPlugin.API_ELEMENTS_CONFIGURATION_NAME - - override val runtimeElementsConfigurationName: String - get() = JavaPlugin.RUNTIME_ELEMENTS_CONFIGURATION_NAME - - override val artifactsTaskName: String - get() = JavaPlugin.JAR_TASK_NAME - - override val compilations: NamedDomainObjectContainer> = - @Suppress("UNCHECKED_CAST") - project.container( - KotlinWithJavaCompilation::class.java as Class>, - KotlinWithJavaCompilationFactory(project, this) - ) -} - open class KotlinOnlyTarget>( project: Project, override val platformType: KotlinPlatformType @@ -388,50 +169,3 @@ open class KotlinOnlyTarget>( internal set } -class KotlinNativeTarget( - project: Project, - val konanTarget: KonanTarget -) : KotlinOnlyTarget(project, KotlinPlatformType.native) { - - init { - attributes.attribute(konanTargetAttribute, konanTarget.name) - } - - val binaries = if(isGradleVersionAtLeast(4, 2)) { - // Use newInstance to allow accessing binaries by their names in Groovy using the extension mechanism. - project.objects.newInstance(KotlinNativeBinaryContainer::class.java, this, WrapUtil.toDomainObjectSet(NativeBinary::class.java)) - } else { - KotlinNativeBinaryContainer(this, WrapUtil.toDomainObjectSet(NativeBinary::class.java)) - } - - fun binaries(configure: KotlinNativeBinaryContainer.() -> Unit) { - binaries.configure() - } - - fun binaries(configure: Closure<*>) { - ConfigureUtil.configure(configure, binaries) - } - - override val artifactsTaskName: String - get() = disambiguateName("binaries") - - override val publishable: Boolean - get() = konanTarget.enabledOnCurrentHost - - // User-visible constants - val DEBUG = NativeBuildType.DEBUG - val RELEASE = NativeBuildType.RELEASE - - val EXECUTABLE = NativeOutputKind.EXECUTABLE - val FRAMEWORK = NativeOutputKind.FRAMEWORK - val DYNAMIC = NativeOutputKind.DYNAMIC - val STATIC = NativeOutputKind.STATIC - - companion object { - val konanTargetAttribute = Attribute.of( - "org.jetbrains.kotlin.native.target", - String::class.java - ) - } -} -