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 d56104c02d9..b269451b17e 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 @@ -6,8 +6,10 @@ package org.jetbrains.kotlin.gradle.targets.native.tasks.artifact import org.gradle.api.Action +import org.gradle.api.Named import org.gradle.api.Project import org.gradle.api.attributes.Usage +import org.gradle.api.plugins.ExtensionAware import org.jetbrains.kotlin.gradle.dsl.KotlinCommonToolOptions import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget @@ -17,12 +19,9 @@ import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName import org.jetbrains.kotlin.konan.target.KonanTarget import org.jetbrains.kotlin.konan.target.presetName -abstract class KotlinArtifact( - val project: Project, +abstract class KotlinArtifactConfig( val artifactName: String ) { - internal abstract val taskName: String - internal val modules = mutableSetOf() fun setModules(vararg project: Any) { modules.clear() @@ -33,18 +32,30 @@ abstract class KotlinArtifact( modules.add(project) } - internal abstract fun validate() - internal abstract fun registerAssembleTask() + abstract fun createArtifact(project: Project, extensions: ExtensionAware): KotlinArtifact } -abstract class KotlinNativeArtifact(project: Project, artifactName: String) : KotlinArtifact(project, artifactName) { +interface KotlinArtifact : Named, ExtensionAware { + val project: Project + val artifactName: String + val modules: Set + val taskName: String get() = lowerCamelCaseName("assemble", name) + + fun validate() + fun registerAssembleTask() +} + +abstract class KotlinNativeArtifactConfig(artifactName: String) : KotlinArtifactConfig(artifactName) { var modes: Set = NativeBuildType.DEFAULT_BUILD_TYPES fun modes(vararg modes: NativeBuildType) { this.modes = modes.toSet() } - @JvmField var isStatic: Boolean = false - @JvmField var linkerOptions: List = emptyList() + @JvmField + var isStatic: Boolean = false + + @JvmField + var linkerOptions: List = emptyList() internal var kotlinOptionsFn: KotlinCommonToolOptions.() -> Unit = {} fun kotlinOptions(fn: Action) { @@ -55,6 +66,14 @@ abstract class KotlinNativeArtifact(project: Project, artifactName: String) : Ko fun binaryOption(name: String, value: String) { binaryOptions[name] = value } +} + +interface KotlinNativeArtifact : KotlinArtifact { + val modes: Set + val isStatic: Boolean + val linkerOptions: List + val kotlinOptionsFn: KotlinCommonToolOptions.() -> Unit + val binaryOptions: Map override fun validate() { check(modules.isNotEmpty()) { @@ -64,34 +83,34 @@ abstract class KotlinNativeArtifact(project: Project, artifactName: String) : Ko "Native artifact '$artifactName' wasn't configured because it requires at least one build type in modes" } } +} - protected fun Project.registerLibsDependencies(target: KonanTarget, artifactName: String, deps: Set): String { - val librariesConfigurationName = lowerCamelCaseName(target.presetName, artifactName, "linkLibrary") - configurations.maybeCreate(librariesConfigurationName).apply { - isVisible = false - isCanBeConsumed = false - isCanBeResolved = true - isTransitive = true - attributes.attribute(KotlinPlatformType.attribute, KotlinPlatformType.native) - attributes.attribute(KotlinNativeTarget.konanTargetAttribute, target.name) - attributes.attribute(Usage.USAGE_ATTRIBUTE, project.objects.named(Usage::class.java, KotlinUsages.KOTLIN_API)) - } - deps.forEach { dependencies.add(librariesConfigurationName, it) } - return librariesConfigurationName +internal fun Project.registerLibsDependencies(target: KonanTarget, artifactName: String, deps: Set): String { + val librariesConfigurationName = lowerCamelCaseName(target.presetName, artifactName, "linkLibrary") + configurations.maybeCreate(librariesConfigurationName).apply { + isVisible = false + isCanBeConsumed = false + isCanBeResolved = true + isTransitive = true + attributes.attribute(KotlinPlatformType.attribute, KotlinPlatformType.native) + attributes.attribute(KotlinNativeTarget.konanTargetAttribute, target.name) + attributes.attribute(Usage.USAGE_ATTRIBUTE, project.objects.named(Usage::class.java, KotlinUsages.KOTLIN_API)) } + deps.forEach { dependencies.add(librariesConfigurationName, it) } + return librariesConfigurationName +} - protected fun Project.registerExportDependencies(target: KonanTarget, artifactName: String, deps: Set): String { - val exportConfigurationName = lowerCamelCaseName(target.presetName, artifactName, "linkExport") - configurations.maybeCreate(exportConfigurationName).apply { - isVisible = false - isCanBeConsumed = false - isCanBeResolved = true - isTransitive = false - attributes.attribute(KotlinPlatformType.attribute, KotlinPlatformType.native) - attributes.attribute(KotlinNativeTarget.konanTargetAttribute, target.name) - attributes.attribute(Usage.USAGE_ATTRIBUTE, project.objects.named(Usage::class.java, KotlinUsages.KOTLIN_API)) - } - deps.forEach { dependencies.add(exportConfigurationName, it) } - return exportConfigurationName +internal fun Project.registerExportDependencies(target: KonanTarget, artifactName: String, deps: Set): String { + val exportConfigurationName = lowerCamelCaseName(target.presetName, artifactName, "linkExport") + configurations.maybeCreate(exportConfigurationName).apply { + isVisible = false + isCanBeConsumed = false + isCanBeResolved = true + isTransitive = false + attributes.attribute(KotlinPlatformType.attribute, KotlinPlatformType.native) + attributes.attribute(KotlinNativeTarget.konanTargetAttribute, target.name) + attributes.attribute(Usage.USAGE_ATTRIBUTE, project.objects.named(Usage::class.java, KotlinUsages.KOTLIN_API)) } + deps.forEach { dependencies.add(exportConfigurationName, it) } + return exportConfigurationName } \ No newline at end of file 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 882f1eb4ed7..929f7192950 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 @@ -7,6 +7,7 @@ package org.jetbrains.kotlin.gradle.targets.native.tasks.artifact import org.gradle.api.Action import org.gradle.api.Project +import org.gradle.api.plugins.ExtensionAware import org.jetbrains.kotlin.gradle.plugin.mpp.NativeBuildType import org.jetbrains.kotlin.gradle.utils.castIsolatedKotlinPluginClassLoaderAware import org.jetbrains.kotlin.konan.target.KonanTarget @@ -27,74 +28,96 @@ abstract class NativeArtifacts @Inject constructor(private val project: Project) annotation class ExperimentalArtifactDsl @ExperimentalArtifactDsl - fun Library(name: String, configure: Action) { + fun Library(name: String, configure: Action) { addKotlinArtifact(name, configure) } @ExperimentalArtifactDsl - fun Library(configure: Action) { + fun Library(configure: Action) { addKotlinArtifact(configure) } @ExperimentalArtifactDsl - fun Framework(name: String, configure: Action) { + fun Framework(name: String, configure: Action) { addKotlinArtifact(name, configure) } @ExperimentalArtifactDsl - fun Framework(configure: Action) { + fun Framework(configure: Action) { addKotlinArtifact(configure) } @ExperimentalArtifactDsl - fun FatFramework(name: String, configure: Action) { + fun FatFramework(name: String, configure: Action) { addKotlinArtifact(name, configure) } @ExperimentalArtifactDsl - fun FatFramework(configure: Action) { + fun FatFramework(configure: Action) { addKotlinArtifact(configure) } @ExperimentalArtifactDsl - fun XCFramework(name: String, configure: Action) { + fun XCFramework(name: String, configure: Action) { addKotlinArtifact(name, configure) } @ExperimentalArtifactDsl - fun XCFramework(configure: Action) { + fun XCFramework(configure: Action) { addKotlinArtifact(configure) } - private inline fun addKotlinArtifact(configure: Action) { + private inline fun addKotlinArtifact(configure: Action) { addKotlinArtifact(project.name.replace(UNSAFE_NAME_SYMBOLS, "_"), configure) } - private inline fun addKotlinArtifact(name: String, configure: Action) { + private inline fun addKotlinArtifact(name: String, configure: Action) { //create via newInstance for extensibility - val artifact = project.objects.newInstance(T::class.java, project, name) + val config: T = project.objects.newInstance(T::class.java, name) + project.kotlinArtifactsExtension.artifactConfigs.add(config) - //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) + //current project is added by default + config.addModule(project) - artifact.addModule(project) - configure.execute(artifact) - artifact.registerAssembleTask() + //apply user configuration + configure.execute(config) + //create immutable artifact object + val artifact = config.createArtifact(project, config as ExtensionAware) + + val isAdded = project.kotlinArtifactsExtension.artifacts.add(artifact) + if (!isAdded) { + error("Kotlin artifact with name '${artifact.name}' is already exists! Change the name, please!") + } } } //Groovy script DSL private const val KOTLIN_ARTIFACTS_EXTENSION_NAME = "kotlinArtifacts" internal fun Project.registerKotlinArtifactsExtension() { - extensions.create(KOTLIN_ARTIFACTS_EXTENSION_NAME, KotlinArtifactsExtension::class.java, this) + val kotlinArtifactsExt = objects.newInstance(KotlinArtifactsExtension::class.java, this) + extensions.add(KOTLIN_ARTIFACTS_EXTENSION_NAME, kotlinArtifactsExt) + kotlinArtifactsExt.artifacts.all { it.registerAssembleTask() } } 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) + //Extending by external plugins: + // + //project.kotlinArtifactsExtension.apply { + // artifactConfigs.all { + // //add custom extension to artifact config DSL + // (it as ExtensionAware).extensions.create("myConfig", Config::class.java) + // } + // artifacts.all { + // val config = it.extensions.findByName("myConfig") as Config + // //configure additional tasks, etc + // //here we can use artifact parameters + // } + //} + val artifactConfigs = project.objects.domainObjectSet(KotlinArtifactConfig::class.java) + val artifacts = project.objects.namedDomainObjectSet(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 8df0e66852a..a105f6320db 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 @@ -7,8 +7,11 @@ package org.jetbrains.kotlin.gradle.targets.native.tasks.artifact import org.gradle.api.Project import org.gradle.api.Task +import org.gradle.api.plugins.ExtensionAware import org.gradle.language.base.plugins.LifecycleBasePlugin +import org.jetbrains.kotlin.gradle.dsl.KotlinCommonToolOptions import org.jetbrains.kotlin.gradle.plugin.mpp.BitcodeEmbeddingMode +import org.jetbrains.kotlin.gradle.plugin.mpp.NativeBuildType import org.jetbrains.kotlin.gradle.plugin.mpp.NativeOutputKind import org.jetbrains.kotlin.gradle.tasks.FatFrameworkTask import org.jetbrains.kotlin.gradle.tasks.FrameworkDescriptor @@ -19,12 +22,9 @@ 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, +abstract class KotlinNativeFatFrameworkConfig @Inject constructor( artifactName: String -) : KotlinNativeArtifact(project, artifactName) { - override val taskName get() = lowerCamelCaseName("assemble", artifactName, "FatFramework") - +) : KotlinNativeArtifactConfig(artifactName) { var targets: Set = emptySet() fun targets(vararg targets: KonanTarget) { this.targets = targets.toSet() @@ -32,7 +32,36 @@ open class KotlinNativeFatFramework @Inject constructor( var embedBitcode: BitcodeEmbeddingMode? = null + override fun createArtifact(project: Project, extensions: ExtensionAware) = KotlinNativeFatFramework( + project, + artifactName, + modules, + modes, + isStatic, + linkerOptions, + kotlinOptionsFn, + binaryOptions, + targets, + embedBitcode, + extensions + ) +} + +class KotlinNativeFatFramework( + override val project: Project, + override val artifactName: String, + override val modules: Set, + override val modes: Set, + override val isStatic: Boolean, + override val linkerOptions: List, + override val kotlinOptionsFn: KotlinCommonToolOptions.() -> Unit, + override val binaryOptions: Map, + val targets: Set, + val embedBitcode: BitcodeEmbeddingMode?, + extensions: ExtensionAware +) : KotlinNativeArtifact, ExtensionAware by extensions { private val kind = NativeOutputKind.FRAMEWORK + override fun getName() = lowerCamelCaseName(artifactName, "FatFramework") override fun validate() { super.validate() 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 943112d9542..42bf90b8155 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 @@ -8,8 +8,10 @@ package org.jetbrains.kotlin.gradle.targets.native.tasks.artifact import org.gradle.api.Project import org.gradle.api.Task import org.gradle.api.plugins.BasePlugin +import org.gradle.api.plugins.ExtensionAware import org.gradle.api.tasks.TaskProvider import org.gradle.language.base.plugins.LifecycleBasePlugin +import org.jetbrains.kotlin.gradle.dsl.KotlinCommonToolOptions import org.jetbrains.kotlin.gradle.plugin.mpp.BitcodeEmbeddingMode import org.jetbrains.kotlin.gradle.plugin.mpp.NativeBuildType import org.jetbrains.kotlin.gradle.plugin.mpp.NativeOutputKind @@ -22,19 +24,45 @@ import org.jetbrains.kotlin.konan.target.presetName import org.jetbrains.kotlin.konan.util.visibleName import javax.inject.Inject -open class KotlinNativeFramework @Inject constructor(project: Project, artifactName: String) : KotlinNativeArtifact(project, artifactName) { - lateinit var target: KonanTarget +abstract class KotlinNativeFrameworkConfig @Inject constructor( + artifactName: String +) : KotlinNativeArtifactConfig(artifactName) { + abstract var target: KonanTarget var embedBitcode: BitcodeEmbeddingMode? = null - private val kind = NativeOutputKind.FRAMEWORK + override fun createArtifact(project: Project, extensions: ExtensionAware) = KotlinNativeFramework( + project, + artifactName, + modules, + modes, + isStatic, + linkerOptions, + kotlinOptionsFn, + binaryOptions, + target, + embedBitcode, + extensions + ) +} - override val taskName get() = lowerCamelCaseName("assemble", artifactName, kind.taskNameClassifier, target.presetName) +class KotlinNativeFramework( + override val project: Project, + override val artifactName: String, + override val modules: Set, + override val modes: Set, + override val isStatic: Boolean, + override val linkerOptions: List, + override val kotlinOptionsFn: KotlinCommonToolOptions.() -> Unit, + override val binaryOptions: Map, + val target: KonanTarget, + val embedBitcode: BitcodeEmbeddingMode?, + extensions: ExtensionAware +) : KotlinNativeArtifact, ExtensionAware by extensions { + private val kind = NativeOutputKind.FRAMEWORK + override fun getName() = lowerCamelCaseName(artifactName, kind.taskNameClassifier, target.presetName) 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}" } 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 603b28828f2..78fcc93dbe0 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 @@ -8,7 +8,10 @@ package org.jetbrains.kotlin.gradle.targets.native.tasks.artifact import org.gradle.api.Project import org.gradle.api.Task import org.gradle.api.plugins.BasePlugin +import org.gradle.api.plugins.ExtensionAware import org.gradle.language.base.plugins.LifecycleBasePlugin +import org.jetbrains.kotlin.gradle.dsl.KotlinCommonToolOptions +import org.jetbrains.kotlin.gradle.plugin.mpp.NativeBuildType import org.jetbrains.kotlin.gradle.plugin.mpp.NativeOutputKind import org.jetbrains.kotlin.gradle.plugin.mpp.enabledOnCurrentHost import org.jetbrains.kotlin.gradle.tasks.dependsOn @@ -19,22 +22,42 @@ import org.jetbrains.kotlin.konan.target.presetName import org.jetbrains.kotlin.konan.util.visibleName import javax.inject.Inject -open class KotlinNativeLibrary @Inject constructor( - project: Project, +abstract class KotlinNativeLibraryConfig @Inject constructor( artifactName: String -) : KotlinNativeArtifact(project, artifactName) { - lateinit var target: KonanTarget +) : KotlinNativeArtifactConfig(artifactName) { + abstract var target: KonanTarget - private val kind: NativeOutputKind - get() = if (isStatic) NativeOutputKind.STATIC else NativeOutputKind.DYNAMIC + override fun createArtifact(project: Project, extensions: ExtensionAware) = KotlinNativeLibrary( + project, + artifactName, + modules, + modes, + isStatic, + linkerOptions, + kotlinOptionsFn, + binaryOptions, + target, + extensions + ) +} - override val taskName get() = lowerCamelCaseName("assemble", artifactName, kind.taskNameClassifier, "Library", target.presetName) +class KotlinNativeLibrary( + override val project: Project, + override val artifactName: String, + override val modules: Set, + override val modes: Set, + override val isStatic: Boolean, + override val linkerOptions: List, + override val kotlinOptionsFn: KotlinCommonToolOptions.() -> Unit, + override val binaryOptions: Map, + val target: KonanTarget, + extensions: ExtensionAware +) : KotlinNativeArtifact, ExtensionAware by extensions { + private val kind = if (isStatic) NativeOutputKind.STATIC else NativeOutputKind.DYNAMIC + override fun getName() = lowerCamelCaseName(artifactName, kind.taskNameClassifier, "Library", target.presetName) 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}" } 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 8bfd1ead36a..4491c2c2e91 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 @@ -7,8 +7,11 @@ package org.jetbrains.kotlin.gradle.targets.native.tasks.artifact import org.gradle.api.Project import org.gradle.api.Task +import org.gradle.api.plugins.ExtensionAware import org.gradle.language.base.plugins.LifecycleBasePlugin +import org.jetbrains.kotlin.gradle.dsl.KotlinCommonToolOptions import org.jetbrains.kotlin.gradle.plugin.mpp.BitcodeEmbeddingMode +import org.jetbrains.kotlin.gradle.plugin.mpp.NativeBuildType import org.jetbrains.kotlin.gradle.plugin.mpp.NativeOutputKind import org.jetbrains.kotlin.gradle.plugin.mpp.apple.AppleTarget import org.jetbrains.kotlin.gradle.plugin.mpp.apple.XCFrameworkTaskHolder @@ -19,12 +22,9 @@ 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, +abstract class KotlinNativeXCFrameworkConfig @Inject constructor( artifactName: String -) : KotlinNativeArtifact(project, artifactName) { - override val taskName get() = lowerCamelCaseName("assemble", artifactName, "XCFramework") - +) : KotlinNativeArtifactConfig(artifactName) { var targets: Set = emptySet() fun targets(vararg targets: KonanTarget) { this.targets = targets.toSet() @@ -32,7 +32,36 @@ open class KotlinNativeXCFramework @Inject constructor( var embedBitcode: BitcodeEmbeddingMode? = null + override fun createArtifact(project: Project, extensions: ExtensionAware) = KotlinNativeXCFramework( + project, + artifactName, + modules, + modes, + isStatic, + linkerOptions, + kotlinOptionsFn, + binaryOptions, + targets, + embedBitcode, + extensions + ) +} + +class KotlinNativeXCFramework( + override val project: Project, + override val artifactName: String, + override val modules: Set, + override val modes: Set, + override val isStatic: Boolean, + override val linkerOptions: List, + override val kotlinOptionsFn: KotlinCommonToolOptions.() -> Unit, + override val binaryOptions: Map, + val targets: Set, + val embedBitcode: BitcodeEmbeddingMode?, + extensions: ExtensionAware +) : KotlinNativeArtifact, ExtensionAware by extensions { private val kind = NativeOutputKind.FRAMEWORK + override fun getName() = lowerCamelCaseName(artifactName, "XCFramework") override fun validate() { super.validate()