diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/native/NativeLibraryDslIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/native/NativeLibraryDslIT.kt index cc5e3631fed..cd7cca395ce 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/native/NativeLibraryDslIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/native/NativeLibraryDslIT.kt @@ -8,6 +8,7 @@ package org.jetbrains.kotlin.gradle.native import org.jetbrains.kotlin.gradle.BaseGradleIT import org.jetbrains.kotlin.gradle.GradleVersionRequired import org.jetbrains.kotlin.gradle.native.GeneralNativeIT.Companion.withNativeCommandLineArguments +import org.jetbrains.kotlin.gradle.transformProjectWithPluginsDsl import org.jetbrains.kotlin.konan.target.HostManager import org.junit.Assume import org.junit.jupiter.api.Assertions.assertFalse @@ -19,14 +20,14 @@ class NativeLibraryDslIT : BaseGradleIT() { @Test fun `check registered gradle tasks`() { - with(Project("new-kn-library-dsl")) { + with(transformProjectWithPluginsDsl("new-kn-library-dsl")) { build(":shared:tasks") { assertSuccessful() assertTasksRegistered( ":shared:assembleMyfatframeFatFramework", - ":shared:assembleMyframeFramework", - ":shared:assembleMylibSharedLibrary", - ":shared:assembleMyslibSharedLibrary", + ":shared:assembleMyframeFrameworkIosArm64", + ":shared:assembleMylibSharedLibraryLinuxX64", + ":shared:assembleMyslibSharedLibraryLinuxX64", ":shared:assembleSharedXCFramework" ) assertTasksNotRegistered( @@ -37,8 +38,8 @@ class NativeLibraryDslIT : BaseGradleIT() { assertSuccessful() assertTasksRegistered( ":lib:assembleGroofatframeFatFramework", - ":lib:assembleGrooframeFramework", - ":lib:assembleGroolibSharedLibrary", + ":lib:assembleGrooframeFrameworkIosArm64", + ":lib:assembleGroolibSharedLibraryIosX64", ":lib:assembleLibXCFramework" ) } @@ -47,7 +48,7 @@ class NativeLibraryDslIT : BaseGradleIT() { @Test fun `link shared library from two gradle modules`() { - with(Project("new-kn-library-dsl")) { + with(transformProjectWithPluginsDsl("new-kn-library-dsl")) { build(":shared:assembleMyslibDebugSharedLibraryLinuxX64") { assertSuccessful() assertTasksExecuted( @@ -63,7 +64,7 @@ class NativeLibraryDslIT : BaseGradleIT() { @Test fun `link shared library from single gradle module`() { - with(Project("new-kn-library-dsl")) { + with(transformProjectWithPluginsDsl("new-kn-library-dsl")) { build(":shared:assembleMylibDebugSharedLibraryLinuxX64") { assertSuccessful() assertTasksExecuted( @@ -86,8 +87,7 @@ class NativeLibraryDslIT : BaseGradleIT() { @Test fun `link shared library from single gradle module with additional link args`() { - with(Project("new-kn-library-dsl")) { - setupWorkingDir() + with(transformProjectWithPluginsDsl("new-kn-library-dsl")) { gradleProperties().appendText("\nkotlin.native.linkArgs=-Xfoo=bar -Xbaz=qux") build(":shared:assembleMylibDebugSharedLibraryLinuxX64") { assertSuccessful() @@ -112,7 +112,7 @@ class NativeLibraryDslIT : BaseGradleIT() { @Test fun `link release XCFramework from two gradle modules`() { Assume.assumeTrue(HostManager.hostIsMac) - with(Project("new-kn-library-dsl")) { + with(transformProjectWithPluginsDsl("new-kn-library-dsl")) { build(":shared:assembleSharedReleaseXCFramework") { assertSuccessful() assertTasksExecuted( diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/new-kn-library-dsl/build.gradle.kts b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/new-kn-library-dsl/build.gradle.kts index 085d555643f..f556befce79 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/new-kn-library-dsl/build.gradle.kts +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/new-kn-library-dsl/build.gradle.kts @@ -1,3 +1,7 @@ +plugins { + kotlin("multiplatform").apply(false) +} + allprojects { repositories { mavenLocal() diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/artifact/KotlinArtifact.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/artifact/KotlinArtifact.kt index 0bc74308a03..d56104c02d9 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/artifact/KotlinArtifact.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/artifact/KotlinArtifact.kt @@ -5,7 +5,6 @@ package org.jetbrains.kotlin.gradle.targets.native.tasks.artifact -import groovy.lang.Closure import org.gradle.api.Action import org.gradle.api.Project import org.gradle.api.attributes.Usage @@ -18,7 +17,12 @@ import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName import org.jetbrains.kotlin.konan.target.KonanTarget import org.jetbrains.kotlin.konan.target.presetName -abstract class KotlinArtifact { +abstract class KotlinArtifact( + val project: Project, + val artifactName: String +) { + internal abstract val taskName: String + internal val modules = mutableSetOf() fun setModules(vararg project: Any) { modules.clear() @@ -29,11 +33,11 @@ abstract class KotlinArtifact { modules.add(project) } - internal abstract fun validate(project: Project, name: String): Boolean - internal abstract fun registerAssembleTask(project: Project, name: String) + internal abstract fun validate() + internal abstract fun registerAssembleTask() } -abstract class KotlinNativeArtifact : KotlinArtifact() { +abstract class KotlinNativeArtifact(project: Project, artifactName: String) : KotlinArtifact(project, artifactName) { var modes: Set = NativeBuildType.DEFAULT_BUILD_TYPES fun modes(vararg modes: NativeBuildType) { this.modes = modes.toSet() @@ -52,22 +56,16 @@ abstract class KotlinNativeArtifact : KotlinArtifact() { binaryOptions[name] = value } - override fun validate(project: Project, name: String): Boolean { - val logger = project.logger - if (modules.isEmpty()) { - logger.error("Native library '${name}' wasn't configured because it requires at least one module for linking") - return false + override fun validate() { + check(modules.isNotEmpty()) { + "Native artifact '$artifactName' wasn't configured because it requires at least one module for linking" } - - if (modes.isEmpty()) { - logger.error("Native library '${name}' wasn't configured because it requires at least one build type in modes") - return false + check(modes.isNotEmpty()) { + "Native artifact '$artifactName' wasn't configured because it requires at least one build type in modes" } - - return true } - fun Project.registerLibsDependencies(target: KonanTarget, artifactName: String, deps: Set): String { + protected fun Project.registerLibsDependencies(target: KonanTarget, artifactName: String, deps: Set): String { val librariesConfigurationName = lowerCamelCaseName(target.presetName, artifactName, "linkLibrary") configurations.maybeCreate(librariesConfigurationName).apply { isVisible = false @@ -82,7 +80,7 @@ abstract class KotlinNativeArtifact : KotlinArtifact() { return librariesConfigurationName } - fun Project.registerExportDependencies(target: KonanTarget, artifactName: String, deps: Set): String { + protected fun Project.registerExportDependencies(target: KonanTarget, artifactName: String, deps: Set): String { val exportConfigurationName = lowerCamelCaseName(target.presetName, artifactName, "linkExport") configurations.maybeCreate(exportConfigurationName).apply { isVisible = false diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/artifact/KotlinArtifactDSL.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/artifact/KotlinArtifactDSL.kt index 93d1e5dd382..882f1eb4ed7 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/artifact/KotlinArtifactDSL.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/artifact/KotlinArtifactDSL.kt @@ -8,25 +8,16 @@ package org.jetbrains.kotlin.gradle.targets.native.tasks.artifact import org.gradle.api.Action import org.gradle.api.Project import org.jetbrains.kotlin.gradle.plugin.mpp.NativeBuildType +import org.jetbrains.kotlin.gradle.utils.castIsolatedKotlinPluginClassLoaderAware import org.jetbrains.kotlin.konan.target.KonanTarget import javax.inject.Inject -private val SAFE_NAME_PATTERN = """\W""".toRegex() -private inline fun Project.kotlinArtifact(configure: Action) { - kotlinArtifact(name.replace(SAFE_NAME_PATTERN, "_"), configure) -} - -private inline fun Project.kotlinArtifact(name: String, configure: Action) { - val artifact = objects.newInstance(T::class.java) - artifact.addModule(this) - configure.execute(artifact) - if (artifact.validate(this, name)) { - artifact.registerAssembleTask(this, name) - } -} - //Groovy script DSL abstract class NativeArtifacts @Inject constructor(private val project: Project) { + companion object { + private val UNSAFE_NAME_SYMBOLS = """\W""".toRegex() + } + @RequiresOptIn( message = "This API is experimental. It may be changed in the future.", level = RequiresOptIn.Level.WARNING @@ -37,51 +28,74 @@ abstract class NativeArtifacts @Inject constructor(private val project: Project) @ExperimentalArtifactDsl fun Library(name: String, configure: Action) { - project.kotlinArtifact(name, configure) + addKotlinArtifact(name, configure) } @ExperimentalArtifactDsl fun Library(configure: Action) { - project.kotlinArtifact(configure) + addKotlinArtifact(configure) } @ExperimentalArtifactDsl fun Framework(name: String, configure: Action) { - project.kotlinArtifact(name, configure) + addKotlinArtifact(name, configure) } @ExperimentalArtifactDsl fun Framework(configure: Action) { - project.kotlinArtifact(configure) + addKotlinArtifact(configure) } @ExperimentalArtifactDsl fun FatFramework(name: String, configure: Action) { - project.kotlinArtifact(name, configure) + addKotlinArtifact(name, configure) } @ExperimentalArtifactDsl fun FatFramework(configure: Action) { - project.kotlinArtifact(configure) + addKotlinArtifact(configure) } @ExperimentalArtifactDsl fun XCFramework(name: String, configure: Action) { - project.kotlinArtifact(name, configure) + addKotlinArtifact(name, configure) } @ExperimentalArtifactDsl fun XCFramework(configure: Action) { - project.kotlinArtifact(configure) + addKotlinArtifact(configure) + } + + private inline fun addKotlinArtifact(configure: Action) { + addKotlinArtifact(project.name.replace(UNSAFE_NAME_SYMBOLS, "_"), configure) + } + + private inline fun addKotlinArtifact(name: String, configure: Action) { + //create via newInstance for extensibility + val artifact = project.objects.newInstance(T::class.java, project, name) + + //we should add artifact to collection BEFORE configuration + //because other plugins can add extensions for artifacts which will be used in configuration block + project.kotlinArtifactsExtension.artifacts.add(artifact) + + artifact.addModule(project) + configure.execute(artifact) + artifact.registerAssembleTask() } } //Groovy script DSL +private const val KOTLIN_ARTIFACTS_EXTENSION_NAME = "kotlinArtifacts" internal fun Project.registerKotlinArtifactsExtension() { - extensions.create("kotlinArtifacts", KotlinArtifactsExtension::class.java, this) + extensions.create(KOTLIN_ARTIFACTS_EXTENSION_NAME, KotlinArtifactsExtension::class.java, this) } +internal val Project.kotlinArtifactsExtension: KotlinArtifactsExtension + get() = extensions.getByName(KOTLIN_ARTIFACTS_EXTENSION_NAME).castIsolatedKotlinPluginClassLoaderAware() + abstract class KotlinArtifactsExtension @Inject constructor(project: Project) { + val artifacts = project.objects.domainObjectSet(KotlinArtifact::class.java) + val DEBUG = NativeBuildType.DEBUG val RELEASE = NativeBuildType.RELEASE diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/artifact/KotlinNativeFatFramework.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/artifact/KotlinNativeFatFramework.kt index a7ea3a1cfa6..8df0e66852a 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/artifact/KotlinNativeFatFramework.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/artifact/KotlinNativeFatFramework.kt @@ -17,8 +17,14 @@ import org.jetbrains.kotlin.gradle.tasks.registerTask import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName import org.jetbrains.kotlin.konan.target.KonanTarget import org.jetbrains.kotlin.konan.util.visibleName +import javax.inject.Inject + +open class KotlinNativeFatFramework @Inject constructor( + project: Project, + artifactName: String +) : KotlinNativeArtifact(project, artifactName) { + override val taskName get() = lowerCamelCaseName("assemble", artifactName, "FatFramework") -open class KotlinNativeFatFramework : KotlinNativeArtifact() { var targets: Set = emptySet() fun targets(vararg targets: KonanTarget) { this.targets = targets.toSet() @@ -28,50 +34,47 @@ open class KotlinNativeFatFramework : KotlinNativeArtifact() { private val kind = NativeOutputKind.FRAMEWORK - override fun validate(project: Project, name: String): Boolean { - val logger = project.logger - if (!super.validate(project, name)) return false - if (targets.isEmpty()) { - logger.error("Native library '${name}' wasn't configured because it requires at least one target") - return false + override fun validate() { + super.validate() + check(targets.isNotEmpty()) { + "Native artifact '$artifactName' wasn't configured because it requires at least one target" } - targets.firstOrNull { !kind.availableFor(it) }?.let { target -> - logger.error("Native library '${name}' wasn't configured because ${kind.description} is not available for ${target.visibleName}") - return false + val wrongTarget = targets.firstOrNull { !kind.availableFor(it) } + check(wrongTarget == null) { + "Native artifact '$artifactName' wasn't configured because ${kind.description} is not available for ${wrongTarget!!.visibleName}" } - - return true } - override fun registerAssembleTask(project: Project, name: String) { - val parentTask = project.registerTask(lowerCamelCaseName("assemble", name, "FatFramework")) { + override fun registerAssembleTask() { + validate() + val parentTask = project.registerTask(taskName) { it.group = "build" - it.description = "Assemble all types of registered '$name' FatFramework" + it.description = "Assemble all types of registered '$artifactName' FatFramework" } project.tasks.named(LifecycleBasePlugin.ASSEMBLE_TASK_NAME).dependsOn(parentTask) modes.forEach { buildType -> val fatTask = project.registerTask( - lowerCamelCaseName("assemble", name, buildType.visibleName, "FatFramework") + lowerCamelCaseName("assemble", artifactName, buildType.visibleName, "FatFramework") ) { - it.baseName = name + it.baseName = artifactName it.destinationDir = project.buildDir.resolve("out/fatframework/${buildType.getName()}") } parentTask.dependsOn(fatTask) val nameSuffix = "ForFat" val frameworkDescriptors: List = targets.map { target -> - val librariesConfigurationName = project.registerLibsDependencies(target, name + nameSuffix, modules) - val exportConfigurationName = project.registerExportDependencies(target, name + nameSuffix, modules) + val librariesConfigurationName = project.registerLibsDependencies(target, artifactName + nameSuffix, modules) + val exportConfigurationName = project.registerExportDependencies(target, artifactName + nameSuffix, modules) val targetTask = registerLinkFrameworkTask( project, - name, + artifactName, target, buildType, librariesConfigurationName, exportConfigurationName, embedBitcode, - "${name}FatFrameworkTemp", + "${artifactName}FatFrameworkTemp", nameSuffix ) fatTask.dependsOn(targetTask) diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/artifact/KotlinNativeFramework.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/artifact/KotlinNativeFramework.kt index c58fa41d5e2..943112d9542 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/artifact/KotlinNativeFramework.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/artifact/KotlinNativeFramework.kt @@ -20,41 +20,40 @@ import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName import org.jetbrains.kotlin.konan.target.KonanTarget import org.jetbrains.kotlin.konan.target.presetName import org.jetbrains.kotlin.konan.util.visibleName +import javax.inject.Inject -open class KotlinNativeFramework : KotlinNativeArtifact() { +open class KotlinNativeFramework @Inject constructor(project: Project, artifactName: String) : KotlinNativeArtifact(project, artifactName) { lateinit var target: KonanTarget var embedBitcode: BitcodeEmbeddingMode? = null private val kind = NativeOutputKind.FRAMEWORK - override fun validate(project: Project, name: String): Boolean { - val logger = project.logger - if (!super.validate(project, name)) return false - if (!this::target.isInitialized) { - logger.error("Native library '${name}' wasn't configured because it requires target") - return false - } - if (!kind.availableFor(target)) { - logger.error("Native library '${name}' wasn't configured because ${kind.description} is not available for ${target.visibleName}") - return false - } + override val taskName get() = lowerCamelCaseName("assemble", artifactName, kind.taskNameClassifier, target.presetName) - return true + override fun validate() { + super.validate() + check(this::target.isInitialized) { + "Native artifact '$artifactName' wasn't configured because it requires target" + } + check(kind.availableFor(target)) { + "Native artifact '$artifactName' wasn't configured because ${kind.description} is not available for ${target.visibleName}" + } } - override fun registerAssembleTask(project: Project, name: String) { - val resultTask = project.registerTask(lowerCamelCaseName("assemble", name, kind.taskNameClassifier)) { task -> + override fun registerAssembleTask() { + validate() + val resultTask = project.registerTask(taskName) { task -> task.group = BasePlugin.BUILD_GROUP - task.description = "Assemble ${kind.description} '$name'." + task.description = "Assemble ${kind.description} '$artifactName' for ${target.visibleName}." task.enabled = target.enabledOnCurrentHost } - val librariesConfigurationName = project.registerLibsDependencies(target, name, modules) - val exportConfigurationName = project.registerExportDependencies(target, name, modules) + val librariesConfigurationName = project.registerLibsDependencies(target, artifactName, modules) + val exportConfigurationName = project.registerExportDependencies(target, artifactName, modules) modes.forEach { buildType -> val targetTask = registerLinkFrameworkTask( project, - name, + artifactName, target, buildType, librariesConfigurationName, diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/artifact/KotlinNativeLibrary.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/artifact/KotlinNativeLibrary.kt index f045b762826..603b28828f2 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/artifact/KotlinNativeLibrary.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/artifact/KotlinNativeLibrary.kt @@ -17,49 +17,48 @@ import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName import org.jetbrains.kotlin.konan.target.KonanTarget import org.jetbrains.kotlin.konan.target.presetName import org.jetbrains.kotlin.konan.util.visibleName +import javax.inject.Inject -open class KotlinNativeLibrary : KotlinNativeArtifact() { +open class KotlinNativeLibrary @Inject constructor( + project: Project, + artifactName: String +) : KotlinNativeArtifact(project, artifactName) { lateinit var target: KonanTarget private val kind: NativeOutputKind get() = if (isStatic) NativeOutputKind.STATIC else NativeOutputKind.DYNAMIC - override fun validate(project: Project, name: String): Boolean { - val logger = project.logger - if (!super.validate(project, name)) return false - if (!this::target.isInitialized) { - logger.error("Native library '${name}' wasn't configured because it requires target") - return false - } - if (!kind.availableFor(target)) { - logger.error("Native library '${name}' wasn't configured because ${kind.description} is not available for ${target.visibleName}") - return false - } + override val taskName get() = lowerCamelCaseName("assemble", artifactName, kind.taskNameClassifier, "Library", target.presetName) - return true + override fun validate() { + super.validate() + check(this::target.isInitialized) { + "Native artifact '$artifactName' wasn't configured because it requires target" + } + check(kind.availableFor(target)) { + "Native artifact '$artifactName' wasn't configured because ${kind.description} is not available for ${target.visibleName}" + } } - override fun registerAssembleTask(project: Project, name: String) { - - val resultTask = project.registerTask( - lowerCamelCaseName("assemble", name, kind.taskNameClassifier, "Library") - ) { task -> + override fun registerAssembleTask() { + validate() + val resultTask = project.registerTask(taskName) { task -> task.group = BasePlugin.BUILD_GROUP - task.description = "Assemble all types of registered '$name' ${kind.description}." + task.description = "Assemble all types of registered '$artifactName' ${kind.description} for ${target.visibleName}." task.enabled = target.enabledOnCurrentHost } project.tasks.named(LifecycleBasePlugin.ASSEMBLE_TASK_NAME).dependsOn(resultTask) - val librariesConfigurationName = project.registerLibsDependencies(target, name, modules) - val exportConfigurationName = project.registerExportDependencies(target, name, modules) + val librariesConfigurationName = project.registerLibsDependencies(target, artifactName, modules) + val exportConfigurationName = project.registerExportDependencies(target, artifactName, modules) modes.forEach { buildType -> val targetTask = project.registerTask( - lowerCamelCaseName("assemble", name, buildType.visibleName, kind.taskNameClassifier, "Library", target.presetName), + lowerCamelCaseName("assemble", artifactName, buildType.visibleName, kind.taskNameClassifier, "Library", target.presetName), listOf(target, kind.compilerOutputKind) ) { task -> - task.description = "Assemble ${kind.description} '$name' for a target '${target.name}'." + task.description = "Assemble ${kind.description} '$artifactName' for a target '${target.name}'." task.enabled = target.enabledOnCurrentHost - task.baseName = name + task.baseName = artifactName task.optimized = buildType.optimized task.debuggable = buildType.debuggable task.linkerOptions = linkerOptions diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/artifact/KotlinNativeXCFramework.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/artifact/KotlinNativeXCFramework.kt index 673b01e1154..8bfd1ead36a 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/artifact/KotlinNativeXCFramework.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/artifact/KotlinNativeXCFramework.kt @@ -17,8 +17,14 @@ import org.jetbrains.kotlin.gradle.tasks.dependsOn import org.jetbrains.kotlin.gradle.tasks.registerTask import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName import org.jetbrains.kotlin.konan.target.KonanTarget +import javax.inject.Inject + +open class KotlinNativeXCFramework @Inject constructor( + project: Project, + artifactName: String +) : KotlinNativeArtifact(project, artifactName) { + override val taskName get() = lowerCamelCaseName("assemble", artifactName, "XCFramework") -open class KotlinNativeXCFramework : KotlinNativeArtifact() { var targets: Set = emptySet() fun targets(vararg targets: KonanTarget) { this.targets = targets.toSet() @@ -28,46 +34,43 @@ open class KotlinNativeXCFramework : KotlinNativeArtifact() { private val kind = NativeOutputKind.FRAMEWORK - override fun validate(project: Project, name: String): Boolean { - val logger = project.logger - if (!super.validate(project, name)) return false - if (targets.isEmpty()) { - logger.error("Native library '${name}' wasn't configured because it requires at least one target") - return false + override fun validate() { + super.validate() + check(targets.isNotEmpty()) { + "Native artifact '$artifactName' wasn't configured because it requires at least one target" } - targets.firstOrNull { !kind.availableFor(it) }?.let { target -> - logger.error("Native library '${name}' wasn't configured because ${kind.description} is not available for ${target.visibleName}") - return false + val wrongTarget = targets.firstOrNull { !kind.availableFor(it) } + check(wrongTarget == null) { + "Native artifact '$artifactName' wasn't configured because ${kind.description} is not available for ${wrongTarget!!.visibleName}" } - - return true } - override fun registerAssembleTask(project: Project, name: String) { - val parentTask = project.registerTask(lowerCamelCaseName("assemble", name, "XCFramework")) { + override fun registerAssembleTask() { + validate() + val parentTask = project.registerTask(taskName) { it.group = "build" - it.description = "Assemble all types of registered '$name' XCFramework" + it.description = "Assemble all types of registered '$artifactName' XCFramework" } project.tasks.named(LifecycleBasePlugin.ASSEMBLE_TASK_NAME).dependsOn(parentTask) modes.forEach { buildType -> - val holder = XCFrameworkTaskHolder.create(project, name, buildType).also { + val holder = XCFrameworkTaskHolder.create(project, artifactName, buildType).also { parentTask.dependsOn(it.task) } val nameSuffix = "ForXCF" val frameworkDescriptors: List = targets.map { target -> - val librariesConfigurationName = project.registerLibsDependencies(target, name + nameSuffix, modules) - val exportConfigurationName = project.registerExportDependencies(target, name + nameSuffix, modules) + val librariesConfigurationName = project.registerLibsDependencies(target, artifactName + nameSuffix, modules) + val exportConfigurationName = project.registerExportDependencies(target, artifactName + nameSuffix, modules) val targetTask = registerLinkFrameworkTask( project, - name, + artifactName, target, buildType, librariesConfigurationName, exportConfigurationName, embedBitcode, - "${name}XCFrameworkTemp", + "${artifactName}XCFrameworkTemp", nameSuffix ) holder.task.dependsOn(targetTask) @@ -76,7 +79,7 @@ open class KotlinNativeXCFramework : KotlinNativeArtifact() { val group = AppleTarget.values().firstOrNull { it.targets.contains(target) } holder.fatTasks[group]?.configure { fatTask -> - fatTask.baseName = name + fatTask.baseName = artifactName fatTask.fromFrameworkDescriptors(listOf(descriptor)) fatTask.dependsOn(targetTask) }