Add kotlin artifacts config and object collections for extensibility.

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
    }
}
This commit is contained in:
konstantin.tskhovrebov
2022-04-07 19:30:35 +02:00
committed by Space
parent 9430f0bafb
commit 5f0303698e
6 changed files with 232 additions and 81 deletions
@@ -6,8 +6,10 @@
package org.jetbrains.kotlin.gradle.targets.native.tasks.artifact package org.jetbrains.kotlin.gradle.targets.native.tasks.artifact
import org.gradle.api.Action import org.gradle.api.Action
import org.gradle.api.Named
import org.gradle.api.Project import org.gradle.api.Project
import org.gradle.api.attributes.Usage import org.gradle.api.attributes.Usage
import org.gradle.api.plugins.ExtensionAware
import org.jetbrains.kotlin.gradle.dsl.KotlinCommonToolOptions import org.jetbrains.kotlin.gradle.dsl.KotlinCommonToolOptions
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget 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.KonanTarget
import org.jetbrains.kotlin.konan.target.presetName import org.jetbrains.kotlin.konan.target.presetName
abstract class KotlinArtifact( abstract class KotlinArtifactConfig(
val project: Project,
val artifactName: String val artifactName: String
) { ) {
internal abstract val taskName: String
internal val modules = mutableSetOf<Any>() internal val modules = mutableSetOf<Any>()
fun setModules(vararg project: Any) { fun setModules(vararg project: Any) {
modules.clear() modules.clear()
@@ -33,18 +32,30 @@ abstract class KotlinArtifact(
modules.add(project) modules.add(project)
} }
internal abstract fun validate() abstract fun createArtifact(project: Project, extensions: ExtensionAware): KotlinArtifact
internal abstract fun registerAssembleTask()
} }
abstract class KotlinNativeArtifact(project: Project, artifactName: String) : KotlinArtifact(project, artifactName) { interface KotlinArtifact : Named, ExtensionAware {
val project: Project
val artifactName: String
val modules: Set<Any>
val taskName: String get() = lowerCamelCaseName("assemble", name)
fun validate()
fun registerAssembleTask()
}
abstract class KotlinNativeArtifactConfig(artifactName: String) : KotlinArtifactConfig(artifactName) {
var modes: Set<NativeBuildType> = NativeBuildType.DEFAULT_BUILD_TYPES var modes: Set<NativeBuildType> = NativeBuildType.DEFAULT_BUILD_TYPES
fun modes(vararg modes: NativeBuildType) { fun modes(vararg modes: NativeBuildType) {
this.modes = modes.toSet() this.modes = modes.toSet()
} }
@JvmField var isStatic: Boolean = false @JvmField
@JvmField var linkerOptions: List<String> = emptyList() var isStatic: Boolean = false
@JvmField
var linkerOptions: List<String> = emptyList()
internal var kotlinOptionsFn: KotlinCommonToolOptions.() -> Unit = {} internal var kotlinOptionsFn: KotlinCommonToolOptions.() -> Unit = {}
fun kotlinOptions(fn: Action<KotlinCommonToolOptions>) { fun kotlinOptions(fn: Action<KotlinCommonToolOptions>) {
@@ -55,6 +66,14 @@ abstract class KotlinNativeArtifact(project: Project, artifactName: String) : Ko
fun binaryOption(name: String, value: String) { fun binaryOption(name: String, value: String) {
binaryOptions[name] = value binaryOptions[name] = value
} }
}
interface KotlinNativeArtifact : KotlinArtifact {
val modes: Set<NativeBuildType>
val isStatic: Boolean
val linkerOptions: List<String>
val kotlinOptionsFn: KotlinCommonToolOptions.() -> Unit
val binaryOptions: Map<String, String>
override fun validate() { override fun validate() {
check(modules.isNotEmpty()) { 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" "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<Any>): String { internal fun Project.registerLibsDependencies(target: KonanTarget, artifactName: String, deps: Set<Any>): String {
val librariesConfigurationName = lowerCamelCaseName(target.presetName, artifactName, "linkLibrary") val librariesConfigurationName = lowerCamelCaseName(target.presetName, artifactName, "linkLibrary")
configurations.maybeCreate(librariesConfigurationName).apply { configurations.maybeCreate(librariesConfigurationName).apply {
isVisible = false isVisible = false
isCanBeConsumed = false isCanBeConsumed = false
isCanBeResolved = true isCanBeResolved = true
isTransitive = true isTransitive = true
attributes.attribute(KotlinPlatformType.attribute, KotlinPlatformType.native) attributes.attribute(KotlinPlatformType.attribute, KotlinPlatformType.native)
attributes.attribute(KotlinNativeTarget.konanTargetAttribute, target.name) attributes.attribute(KotlinNativeTarget.konanTargetAttribute, target.name)
attributes.attribute(Usage.USAGE_ATTRIBUTE, project.objects.named(Usage::class.java, KotlinUsages.KOTLIN_API)) attributes.attribute(Usage.USAGE_ATTRIBUTE, project.objects.named(Usage::class.java, KotlinUsages.KOTLIN_API))
}
deps.forEach { dependencies.add(librariesConfigurationName, it) }
return librariesConfigurationName
} }
deps.forEach { dependencies.add(librariesConfigurationName, it) }
return librariesConfigurationName
}
protected fun Project.registerExportDependencies(target: KonanTarget, artifactName: String, deps: Set<Any>): String { internal fun Project.registerExportDependencies(target: KonanTarget, artifactName: String, deps: Set<Any>): String {
val exportConfigurationName = lowerCamelCaseName(target.presetName, artifactName, "linkExport") val exportConfigurationName = lowerCamelCaseName(target.presetName, artifactName, "linkExport")
configurations.maybeCreate(exportConfigurationName).apply { configurations.maybeCreate(exportConfigurationName).apply {
isVisible = false isVisible = false
isCanBeConsumed = false isCanBeConsumed = false
isCanBeResolved = true isCanBeResolved = true
isTransitive = false isTransitive = false
attributes.attribute(KotlinPlatformType.attribute, KotlinPlatformType.native) attributes.attribute(KotlinPlatformType.attribute, KotlinPlatformType.native)
attributes.attribute(KotlinNativeTarget.konanTargetAttribute, target.name) attributes.attribute(KotlinNativeTarget.konanTargetAttribute, target.name)
attributes.attribute(Usage.USAGE_ATTRIBUTE, project.objects.named(Usage::class.java, KotlinUsages.KOTLIN_API)) attributes.attribute(Usage.USAGE_ATTRIBUTE, project.objects.named(Usage::class.java, KotlinUsages.KOTLIN_API))
}
deps.forEach { dependencies.add(exportConfigurationName, it) }
return exportConfigurationName
} }
deps.forEach { dependencies.add(exportConfigurationName, it) }
return exportConfigurationName
} }
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.gradle.targets.native.tasks.artifact
import org.gradle.api.Action import org.gradle.api.Action
import org.gradle.api.Project import org.gradle.api.Project
import org.gradle.api.plugins.ExtensionAware
import org.jetbrains.kotlin.gradle.plugin.mpp.NativeBuildType import org.jetbrains.kotlin.gradle.plugin.mpp.NativeBuildType
import org.jetbrains.kotlin.gradle.utils.castIsolatedKotlinPluginClassLoaderAware import org.jetbrains.kotlin.gradle.utils.castIsolatedKotlinPluginClassLoaderAware
import org.jetbrains.kotlin.konan.target.KonanTarget import org.jetbrains.kotlin.konan.target.KonanTarget
@@ -27,74 +28,96 @@ abstract class NativeArtifacts @Inject constructor(private val project: Project)
annotation class ExperimentalArtifactDsl annotation class ExperimentalArtifactDsl
@ExperimentalArtifactDsl @ExperimentalArtifactDsl
fun Library(name: String, configure: Action<KotlinNativeLibrary>) { fun Library(name: String, configure: Action<KotlinNativeLibraryConfig>) {
addKotlinArtifact(name, configure) addKotlinArtifact(name, configure)
} }
@ExperimentalArtifactDsl @ExperimentalArtifactDsl
fun Library(configure: Action<KotlinNativeLibrary>) { fun Library(configure: Action<KotlinNativeLibraryConfig>) {
addKotlinArtifact(configure) addKotlinArtifact(configure)
} }
@ExperimentalArtifactDsl @ExperimentalArtifactDsl
fun Framework(name: String, configure: Action<KotlinNativeFramework>) { fun Framework(name: String, configure: Action<KotlinNativeFrameworkConfig>) {
addKotlinArtifact(name, configure) addKotlinArtifact(name, configure)
} }
@ExperimentalArtifactDsl @ExperimentalArtifactDsl
fun Framework(configure: Action<KotlinNativeFramework>) { fun Framework(configure: Action<KotlinNativeFrameworkConfig>) {
addKotlinArtifact(configure) addKotlinArtifact(configure)
} }
@ExperimentalArtifactDsl @ExperimentalArtifactDsl
fun FatFramework(name: String, configure: Action<KotlinNativeFatFramework>) { fun FatFramework(name: String, configure: Action<KotlinNativeFatFrameworkConfig>) {
addKotlinArtifact(name, configure) addKotlinArtifact(name, configure)
} }
@ExperimentalArtifactDsl @ExperimentalArtifactDsl
fun FatFramework(configure: Action<KotlinNativeFatFramework>) { fun FatFramework(configure: Action<KotlinNativeFatFrameworkConfig>) {
addKotlinArtifact(configure) addKotlinArtifact(configure)
} }
@ExperimentalArtifactDsl @ExperimentalArtifactDsl
fun XCFramework(name: String, configure: Action<KotlinNativeXCFramework>) { fun XCFramework(name: String, configure: Action<KotlinNativeXCFrameworkConfig>) {
addKotlinArtifact(name, configure) addKotlinArtifact(name, configure)
} }
@ExperimentalArtifactDsl @ExperimentalArtifactDsl
fun XCFramework(configure: Action<KotlinNativeXCFramework>) { fun XCFramework(configure: Action<KotlinNativeXCFrameworkConfig>) {
addKotlinArtifact(configure) addKotlinArtifact(configure)
} }
private inline fun <reified T : KotlinArtifact> addKotlinArtifact(configure: Action<T>) { private inline fun <reified T : KotlinArtifactConfig> addKotlinArtifact(configure: Action<T>) {
addKotlinArtifact(project.name.replace(UNSAFE_NAME_SYMBOLS, "_"), configure) addKotlinArtifact(project.name.replace(UNSAFE_NAME_SYMBOLS, "_"), configure)
} }
private inline fun <reified T : KotlinArtifact> addKotlinArtifact(name: String, configure: Action<T>) { private inline fun <reified T : KotlinArtifactConfig> addKotlinArtifact(name: String, configure: Action<T>) {
//create via newInstance for extensibility //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 //current project is added by default
//because other plugins can add extensions for artifacts which will be used in configuration block config.addModule(project)
project.kotlinArtifactsExtension.artifacts.add(artifact)
artifact.addModule(project) //apply user configuration
configure.execute(artifact) configure.execute(config)
artifact.registerAssembleTask() //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 //Groovy script DSL
private const val KOTLIN_ARTIFACTS_EXTENSION_NAME = "kotlinArtifacts" private const val KOTLIN_ARTIFACTS_EXTENSION_NAME = "kotlinArtifacts"
internal fun Project.registerKotlinArtifactsExtension() { 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 internal val Project.kotlinArtifactsExtension: KotlinArtifactsExtension
get() = extensions.getByName(KOTLIN_ARTIFACTS_EXTENSION_NAME).castIsolatedKotlinPluginClassLoaderAware() get() = extensions.getByName(KOTLIN_ARTIFACTS_EXTENSION_NAME).castIsolatedKotlinPluginClassLoaderAware()
abstract class KotlinArtifactsExtension @Inject constructor(project: Project) { 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 DEBUG = NativeBuildType.DEBUG
val RELEASE = NativeBuildType.RELEASE val RELEASE = NativeBuildType.RELEASE
@@ -7,8 +7,11 @@ package org.jetbrains.kotlin.gradle.targets.native.tasks.artifact
import org.gradle.api.Project import org.gradle.api.Project
import org.gradle.api.Task import org.gradle.api.Task
import org.gradle.api.plugins.ExtensionAware
import org.gradle.language.base.plugins.LifecycleBasePlugin 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.BitcodeEmbeddingMode
import org.jetbrains.kotlin.gradle.plugin.mpp.NativeBuildType
import org.jetbrains.kotlin.gradle.plugin.mpp.NativeOutputKind import org.jetbrains.kotlin.gradle.plugin.mpp.NativeOutputKind
import org.jetbrains.kotlin.gradle.tasks.FatFrameworkTask import org.jetbrains.kotlin.gradle.tasks.FatFrameworkTask
import org.jetbrains.kotlin.gradle.tasks.FrameworkDescriptor 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 org.jetbrains.kotlin.konan.util.visibleName
import javax.inject.Inject import javax.inject.Inject
open class KotlinNativeFatFramework @Inject constructor( abstract class KotlinNativeFatFrameworkConfig @Inject constructor(
project: Project,
artifactName: String artifactName: String
) : KotlinNativeArtifact(project, artifactName) { ) : KotlinNativeArtifactConfig(artifactName) {
override val taskName get() = lowerCamelCaseName("assemble", artifactName, "FatFramework")
var targets: Set<KonanTarget> = emptySet() var targets: Set<KonanTarget> = emptySet()
fun targets(vararg targets: KonanTarget) { fun targets(vararg targets: KonanTarget) {
this.targets = targets.toSet() this.targets = targets.toSet()
@@ -32,7 +32,36 @@ open class KotlinNativeFatFramework @Inject constructor(
var embedBitcode: BitcodeEmbeddingMode? = null 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<Any>,
override val modes: Set<NativeBuildType>,
override val isStatic: Boolean,
override val linkerOptions: List<String>,
override val kotlinOptionsFn: KotlinCommonToolOptions.() -> Unit,
override val binaryOptions: Map<String, String>,
val targets: Set<KonanTarget>,
val embedBitcode: BitcodeEmbeddingMode?,
extensions: ExtensionAware
) : KotlinNativeArtifact, ExtensionAware by extensions {
private val kind = NativeOutputKind.FRAMEWORK private val kind = NativeOutputKind.FRAMEWORK
override fun getName() = lowerCamelCaseName(artifactName, "FatFramework")
override fun validate() { override fun validate() {
super.validate() super.validate()
@@ -8,8 +8,10 @@ package org.jetbrains.kotlin.gradle.targets.native.tasks.artifact
import org.gradle.api.Project import org.gradle.api.Project
import org.gradle.api.Task import org.gradle.api.Task
import org.gradle.api.plugins.BasePlugin import org.gradle.api.plugins.BasePlugin
import org.gradle.api.plugins.ExtensionAware
import org.gradle.api.tasks.TaskProvider import org.gradle.api.tasks.TaskProvider
import org.gradle.language.base.plugins.LifecycleBasePlugin 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.BitcodeEmbeddingMode
import org.jetbrains.kotlin.gradle.plugin.mpp.NativeBuildType import org.jetbrains.kotlin.gradle.plugin.mpp.NativeBuildType
import org.jetbrains.kotlin.gradle.plugin.mpp.NativeOutputKind 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 org.jetbrains.kotlin.konan.util.visibleName
import javax.inject.Inject import javax.inject.Inject
open class KotlinNativeFramework @Inject constructor(project: Project, artifactName: String) : KotlinNativeArtifact(project, artifactName) { abstract class KotlinNativeFrameworkConfig @Inject constructor(
lateinit var target: KonanTarget artifactName: String
) : KotlinNativeArtifactConfig(artifactName) {
abstract var target: KonanTarget
var embedBitcode: BitcodeEmbeddingMode? = null 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<Any>,
override val modes: Set<NativeBuildType>,
override val isStatic: Boolean,
override val linkerOptions: List<String>,
override val kotlinOptionsFn: KotlinCommonToolOptions.() -> Unit,
override val binaryOptions: Map<String, String>,
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() { override fun validate() {
super.validate() super.validate()
check(this::target.isInitialized) {
"Native artifact '$artifactName' wasn't configured because it requires target"
}
check(kind.availableFor(target)) { check(kind.availableFor(target)) {
"Native artifact '$artifactName' wasn't configured because ${kind.description} is not available for ${target.visibleName}" "Native artifact '$artifactName' wasn't configured because ${kind.description} is not available for ${target.visibleName}"
} }
@@ -8,7 +8,10 @@ package org.jetbrains.kotlin.gradle.targets.native.tasks.artifact
import org.gradle.api.Project import org.gradle.api.Project
import org.gradle.api.Task import org.gradle.api.Task
import org.gradle.api.plugins.BasePlugin import org.gradle.api.plugins.BasePlugin
import org.gradle.api.plugins.ExtensionAware
import org.gradle.language.base.plugins.LifecycleBasePlugin 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.NativeOutputKind
import org.jetbrains.kotlin.gradle.plugin.mpp.enabledOnCurrentHost import org.jetbrains.kotlin.gradle.plugin.mpp.enabledOnCurrentHost
import org.jetbrains.kotlin.gradle.tasks.dependsOn 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 org.jetbrains.kotlin.konan.util.visibleName
import javax.inject.Inject import javax.inject.Inject
open class KotlinNativeLibrary @Inject constructor( abstract class KotlinNativeLibraryConfig @Inject constructor(
project: Project,
artifactName: String artifactName: String
) : KotlinNativeArtifact(project, artifactName) { ) : KotlinNativeArtifactConfig(artifactName) {
lateinit var target: KonanTarget abstract var target: KonanTarget
private val kind: NativeOutputKind override fun createArtifact(project: Project, extensions: ExtensionAware) = KotlinNativeLibrary(
get() = if (isStatic) NativeOutputKind.STATIC else NativeOutputKind.DYNAMIC 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<Any>,
override val modes: Set<NativeBuildType>,
override val isStatic: Boolean,
override val linkerOptions: List<String>,
override val kotlinOptionsFn: KotlinCommonToolOptions.() -> Unit,
override val binaryOptions: Map<String, String>,
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() { override fun validate() {
super.validate() super.validate()
check(this::target.isInitialized) {
"Native artifact '$artifactName' wasn't configured because it requires target"
}
check(kind.availableFor(target)) { check(kind.availableFor(target)) {
"Native artifact '$artifactName' wasn't configured because ${kind.description} is not available for ${target.visibleName}" "Native artifact '$artifactName' wasn't configured because ${kind.description} is not available for ${target.visibleName}"
} }
@@ -7,8 +7,11 @@ package org.jetbrains.kotlin.gradle.targets.native.tasks.artifact
import org.gradle.api.Project import org.gradle.api.Project
import org.gradle.api.Task import org.gradle.api.Task
import org.gradle.api.plugins.ExtensionAware
import org.gradle.language.base.plugins.LifecycleBasePlugin 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.BitcodeEmbeddingMode
import org.jetbrains.kotlin.gradle.plugin.mpp.NativeBuildType
import org.jetbrains.kotlin.gradle.plugin.mpp.NativeOutputKind 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.AppleTarget
import org.jetbrains.kotlin.gradle.plugin.mpp.apple.XCFrameworkTaskHolder 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 org.jetbrains.kotlin.konan.target.KonanTarget
import javax.inject.Inject import javax.inject.Inject
open class KotlinNativeXCFramework @Inject constructor( abstract class KotlinNativeXCFrameworkConfig @Inject constructor(
project: Project,
artifactName: String artifactName: String
) : KotlinNativeArtifact(project, artifactName) { ) : KotlinNativeArtifactConfig(artifactName) {
override val taskName get() = lowerCamelCaseName("assemble", artifactName, "XCFramework")
var targets: Set<KonanTarget> = emptySet() var targets: Set<KonanTarget> = emptySet()
fun targets(vararg targets: KonanTarget) { fun targets(vararg targets: KonanTarget) {
this.targets = targets.toSet() this.targets = targets.toSet()
@@ -32,7 +32,36 @@ open class KotlinNativeXCFramework @Inject constructor(
var embedBitcode: BitcodeEmbeddingMode? = null 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<Any>,
override val modes: Set<NativeBuildType>,
override val isStatic: Boolean,
override val linkerOptions: List<String>,
override val kotlinOptionsFn: KotlinCommonToolOptions.() -> Unit,
override val binaryOptions: Map<String, String>,
val targets: Set<KonanTarget>,
val embedBitcode: BitcodeEmbeddingMode?,
extensions: ExtensionAware
) : KotlinNativeArtifact, ExtensionAware by extensions {
private val kind = NativeOutputKind.FRAMEWORK private val kind = NativeOutputKind.FRAMEWORK
override fun getName() = lowerCamelCaseName(artifactName, "XCFramework")
override fun validate() { override fun validate() {
super.validate() super.validate()