[gradle-plugin] Support different targets for different artifacts

This commit is contained in:
Ilya Matveev
2017-12-29 17:50:00 +07:00
committed by ilmat192
parent 0fdca87a0b
commit 6d4b15867b
5 changed files with 212 additions and 93 deletions
+1 -2
View File
@@ -101,9 +101,8 @@ targetList.each { target ->
def libName = defFileToLibName(target, df.name) def libName = defFileToLibName(target, df.name)
def installTaskName = defFileToInstallTaskName(target, df.name) def installTaskName = defFileToInstallTaskName(target, df.name)
konan.targets = [target] // TODO: Support custom targets in gradle plugin.
konanArtifacts { konanArtifacts {
interop(libName) { interop (libName, targets: [target]) {
defFile df.file defFile df.file
artifactName df.name artifactName df.name
noDefaultLibs true noDefaultLibs true
@@ -18,11 +18,12 @@ package org.jetbrains.kotlin.gradle.plugin
import groovy.lang.Closure import groovy.lang.Closure
import org.gradle.api.Action import org.gradle.api.Action
import org.gradle.api.NamedDomainObjectFactory
import org.gradle.api.internal.DefaultPolymorphicDomainObjectContainer import org.gradle.api.internal.DefaultPolymorphicDomainObjectContainer
import org.gradle.api.internal.project.ProjectInternal import org.gradle.api.internal.project.ProjectInternal
import org.gradle.internal.reflect.Instantiator import org.gradle.internal.reflect.Instantiator
import org.gradle.util.ConfigureUtil import org.gradle.util.ConfigureUtil
import kotlin.reflect.KClass
open class KonanArtifactContainer(val project: ProjectInternal) open class KonanArtifactContainer(val project: ProjectInternal)
: DefaultPolymorphicDomainObjectContainer<KonanBuildingConfig<*>>( : DefaultPolymorphicDomainObjectContainer<KonanBuildingConfig<*>>(
@@ -30,78 +31,141 @@ open class KonanArtifactContainer(val project: ProjectInternal)
project.services.get(Instantiator::class.java) project.services.get(Instantiator::class.java)
) { ) {
init { private inner class KonanBuildingConfigFactory<T: KonanBuildingConfig<*>>(val configClass: KClass<T>)
registerFactory(KonanProgram::class.java) { name -> : NamedDomainObjectFactory<T> {
instantiator.newInstance(KonanProgram::class.java, name, project, instantiator)
} var targets: Iterable<String> = emptyList()
registerFactory(KonanDynamic::class.java) { name ->
instantiator.newInstance(KonanDynamic::class.java, name, project, instantiator) override fun create(name: String?): T =
} instantiator.newInstance(configClass.java, name, project, instantiator, targets)
registerFactory(KonanFramework::class.java) { name ->
instantiator.newInstance(KonanFramework::class.java, name, project, instantiator)
}
registerFactory(KonanLibrary::class.java) { name ->
instantiator.newInstance(KonanLibrary::class.java, name, project, instantiator)
}
registerFactory(KonanBitcode::class.java) { name ->
instantiator.newInstance(KonanBitcode::class.java, name, project, instantiator)
}
registerFactory(KonanInteropLibrary::class.java) { name ->
instantiator.newInstance(KonanInteropLibrary::class.java, name, project, instantiator)
}
} }
// TODO: Investigate if we can support the same DSL as project.task: private val factories = mutableMapOf<KClass<out KonanBuildingConfig<*>>, KonanBuildingConfigFactory<*>>()
// program foo(targets: [target1, target2, target3]) {
// ...
// }
fun program(name: String) = create(name, KonanProgram::class.java) private fun <T: KonanBuildingConfig<*>> createFactory(configClass: KClass<T>) {
fun program(name: String, configureAction: Action<KonanProgram>) = val factory = KonanBuildingConfigFactory(configClass)
create(name, KonanProgram::class.java, configureAction) super.registerFactory(configClass.java, factory)
fun program(name: String, configureAction: KonanProgram.() -> Unit) = factories.put(configClass, factory)
create(name, KonanProgram::class.java, configureAction) }
fun program(name: String, configureAction: Closure<*>) =
program(name, ConfigureUtil.configureUsing(configureAction))
fun dynamic(name: String) = create(name, KonanDynamic::class.java) init {
fun dynamic(name: String, configureAction: Action<KonanDynamic>) = createFactory(KonanProgram::class)
create(name, KonanDynamic::class.java, configureAction) createFactory(KonanDynamic::class)
fun dynamic(name: String, configureAction: KonanDynamic.() -> Unit) = createFactory(KonanFramework::class)
create(name, KonanDynamic::class.java, configureAction) createFactory(KonanLibrary::class)
fun dynamic(name: String, configureAction: Closure<*>) = createFactory(KonanBitcode::class)
dynamic(name, ConfigureUtil.configureUsing(configureAction)) createFactory(KonanInteropLibrary::class)
}
fun framework(name: String) = create(name, KonanFramework::class.java) private fun determineTargets(configClass: KClass<out KonanBuildingConfig<*>>, args: Map<String, Any?>) {
fun framework(name: String, configureAction: Action<KonanFramework>) = val targetsArg = args["targets"]
create(name, KonanFramework::class.java, configureAction) val targets = when {
fun framework(name: String, configureAction: KonanFramework.() -> Unit) = targetsArg == null -> project.konanExtension.targets
create(name, KonanFramework::class.java, configureAction) targetsArg is Iterable<*> -> targetsArg.map { it.toString() }
fun framework(name: String, configureAction: Closure<*>) = else -> listOf(targetsArg.toString())
framework(name, ConfigureUtil.configureUsing(configureAction)) }
factories[configClass]?.targets = targets
}
fun library(name: String) = create(name, KonanLibrary::class.java) private fun <T: KonanBuildingConfig<*>> create(name: String,
fun library(name: String, configureAction: Action<KonanLibrary>) = configClass: KClass<T>,
create(name, KonanLibrary::class.java, configureAction) args: Map<String, Any?>,
fun library(name: String, configureAction: KonanLibrary.() -> Unit) = configureAction: Action<T>) {
create(name, KonanLibrary::class.java, configureAction) determineTargets(configClass, args)
fun library(name: String, configureAction: Closure<*>) = super.create(name, configClass.java, configureAction)
library(name, ConfigureUtil.configureUsing(configureAction)) }
fun bitcode(name: String) = create(name, KonanBitcode::class.java) private fun <T: KonanBuildingConfig<*>> create(name: String,
fun bitcode(name: String, configureAction: Action<KonanBitcode>) = configClass: KClass<T>,
create(name, KonanBitcode::class.java, configureAction) args: Map<String, Any?>,
fun bitcode(name: String, configureAction: KonanBitcode.() -> Unit) = configureAction: T.() -> Unit) {
create(name, KonanBitcode::class.java, configureAction) determineTargets(configClass, args)
fun bitcode(name: String, configureAction: Closure<*>) = super.create(name, configClass.java, configureAction)
bitcode(name, ConfigureUtil.configureUsing(configureAction)) }
fun interop(name: String) = create(name, KonanInteropLibrary::class.java) private fun <T: KonanBuildingConfig<*>> create(name: String,
fun interop(name: String, configureAction: Action<KonanInteropLibrary>) = configClass: KClass<T>,
create(name, KonanInteropLibrary::class.java, configureAction) args: Map<String, Any?>) {
fun interop(name: String, configureAction: KonanInteropLibrary.() -> Unit) = determineTargets(configClass, args)
create(name, KonanInteropLibrary::class.java, configureAction) super.create(name, configClass.java)
fun interop(name: String, configureAction: Closure<*>) = }
interop(name, ConfigureUtil.configureUsing(configureAction))
fun program(args: Map<String, Any?>, name: String) = create(name, KonanProgram::class, args)
fun program(args: Map<String, Any?>, name: String, configureAction: Action<KonanProgram>) =
create(name, KonanProgram::class, args, configureAction)
fun program(args: Map<String, Any?>, name: String, configureAction: KonanProgram.() -> Unit) =
create(name, KonanProgram::class, args, configureAction)
fun program(args: Map<String, Any?>, name: String, configureAction: Closure<*>) =
program(args, name, ConfigureUtil.configureUsing(configureAction))
fun dynamic(args: Map<String, Any?>, name: String) = create(name, KonanDynamic::class, args)
fun dynamic(args: Map<String, Any?>, name: String, configureAction: Action<KonanDynamic>) =
create(name, KonanDynamic::class, args, configureAction)
fun dynamic(args: Map<String, Any?>, name: String, configureAction: KonanDynamic.() -> Unit) =
create(name, KonanDynamic::class, args, configureAction)
fun dynamic(args: Map<String, Any?>, name: String, configureAction: Closure<*>) =
dynamic(args, name, ConfigureUtil.configureUsing(configureAction))
fun framework(args: Map<String, Any?>, name: String) = create(name, KonanFramework::class, args)
fun framework(args: Map<String, Any?>, name: String, configureAction: Action<KonanFramework>) =
create(name, KonanFramework::class, args, configureAction)
fun framework(args: Map<String, Any?>, name: String, configureAction: KonanFramework.() -> Unit) =
create(name, KonanFramework::class, args, configureAction)
fun framework(args: Map<String, Any?>, name: String, configureAction: Closure<*>) =
framework(args, name, ConfigureUtil.configureUsing(configureAction))
fun library(args: Map<String, Any?>, name: String) = create(name, KonanLibrary::class, args)
fun library(args: Map<String, Any?>, name: String, configureAction: Action<KonanLibrary>) =
create(name, KonanLibrary::class, args, configureAction)
fun library(args: Map<String, Any?>, name: String, configureAction: KonanLibrary.() -> Unit) =
create(name, KonanLibrary::class, args, configureAction)
fun library(args: Map<String, Any?>, name: String, configureAction: Closure<*>) =
library(args, name, ConfigureUtil.configureUsing(configureAction))
fun bitcode(args: Map<String, Any?>, name: String) = create(name, KonanBitcode::class, args)
fun bitcode(args: Map<String, Any?>, name: String, configureAction: Action<KonanBitcode>) =
create(name, KonanBitcode::class, args, configureAction)
fun bitcode(args: Map<String, Any?>, name: String, configureAction: KonanBitcode.() -> Unit) =
create(name, KonanBitcode::class, args, configureAction)
fun bitcode(args: Map<String, Any?>, name: String, configureAction: Closure<*>) =
bitcode(args, name, ConfigureUtil.configureUsing(configureAction))
fun interop(args: Map<String, Any?>, name: String) = create(name, KonanInteropLibrary::class, args)
fun interop(args: Map<String, Any?>, name: String, configureAction: Action<KonanInteropLibrary>) =
create(name, KonanInteropLibrary::class, args, configureAction)
fun interop(args: Map<String, Any?>, name: String, configureAction: KonanInteropLibrary.() -> Unit) =
create(name, KonanInteropLibrary::class, args, configureAction)
fun interop(args: Map<String, Any?>, name: String, configureAction: Closure<*>) =
interop(args, name, ConfigureUtil.configureUsing(configureAction))
fun program(name: String) = program(emptyMap(), name)
fun program(name: String, configureAction: Action<KonanProgram>) = program(emptyMap(), name, configureAction)
fun program(name: String, configureAction: KonanProgram.() -> Unit) = program(emptyMap(), name, configureAction)
fun program(name: String, configureAction: Closure<*>) = program(emptyMap(), name, configureAction)
fun dynamic(name: String) = dynamic(emptyMap(), name)
fun dynamic(name: String, configureAction: Action<KonanDynamic>) = dynamic(emptyMap(), name, configureAction)
fun dynamic(name: String, configureAction: KonanDynamic.() -> Unit) = dynamic(emptyMap(), name, configureAction)
fun dynamic(name: String, configureAction: Closure<*>) = dynamic(emptyMap(), name, configureAction)
fun framework(name: String) = framework(emptyMap(), name)
fun framework(name: String, configureAction: Action<KonanFramework>) = framework(emptyMap(), name, configureAction)
fun framework(name: String, configureAction: KonanFramework.() -> Unit) = framework(emptyMap(), name, configureAction)
fun framework(name: String, configureAction: Closure<*>) = framework(emptyMap(), name, configureAction)
fun library(name: String) = library(emptyMap(), name)
fun library(name: String, configureAction: Action<KonanLibrary>) = library(emptyMap(), name, configureAction)
fun library(name: String, configureAction: KonanLibrary.() -> Unit) = library(emptyMap(), name, configureAction)
fun library(name: String, configureAction: Closure<*>) = library(emptyMap(), name, configureAction)
fun bitcode(name: String) = bitcode(emptyMap(), name)
fun bitcode(name: String, configureAction: Action<KonanBitcode>) = bitcode(emptyMap(), name, configureAction)
fun bitcode(name: String, configureAction: KonanBitcode.() -> Unit) = bitcode(emptyMap(), name, configureAction)
fun bitcode(name: String, configureAction: Closure<*>) = bitcode(emptyMap(), name, configureAction)
fun interop(name: String) = interop(emptyMap(), name)
fun interop(name: String, configureAction: Action<KonanInteropLibrary>) = interop(emptyMap(), name, configureAction)
fun interop(name: String, configureAction: KonanInteropLibrary.() -> Unit) = interop(emptyMap(), name, configureAction)
fun interop(name: String, configureAction: Closure<*>) = interop(emptyMap(), name, configureAction)
} }
@@ -36,7 +36,8 @@ import java.io.File
abstract class KonanBuildingConfig<T: KonanBuildingTask>(private val name_: String, abstract class KonanBuildingConfig<T: KonanBuildingTask>(private val name_: String,
type: Class<T>, type: Class<T>,
val project: ProjectInternal, val project: ProjectInternal,
instantiator: Instantiator) instantiator: Instantiator,
val targets: Iterable<String>)
: KonanBuildingSpec, Named, DefaultNamedDomainObjectSet<T>(type, instantiator, { it.konanTarget.visibleName }) { : KonanBuildingSpec, Named, DefaultNamedDomainObjectSet<T>(type, instantiator, { it.konanTarget.visibleName }) {
override fun getName() = name_ override fun getName() = name_
@@ -45,15 +46,20 @@ abstract class KonanBuildingConfig<T: KonanBuildingTask>(private val name_: Stri
internal val aggregateBuildTask: Task internal val aggregateBuildTask: Task
val declaredTargets: Iterable<KonanTarget> = project.konanTargets private val konanTargets: Iterable<KonanTarget>
get() = targets.map { TargetManager(it).target }.distinct()
init { init {
declaredTargets.forEach { for (target in konanTargets) {
if (it.enabled) { if (!target.enabled) {
super.add(createTask(it)) project.logger.warn("The target is not enabled on the current host: ${target.visibleName}")
} else { continue
project.logger.warn("The target is not enabled on the current host: ${it.visibleName}")
} }
if (!targetIsSupported(target)) {
project.logger.warn("The target ${target.visibleName} is not supported by the artifact $name")
continue
}
super.add(createTask(target))
} }
aggregateBuildTask = createAggregateTask() aggregateBuildTask = createAggregateTask()
createHostTaskIfDeclared() createHostTaskIfDeclared()
@@ -74,6 +80,8 @@ abstract class KonanBuildingConfig<T: KonanBuildingTask>(private val name_: Stri
protected abstract val defaultBaseDir: File protected abstract val defaultBaseDir: File
protected open fun targetIsSupported(target: KonanTarget): Boolean = true
override fun didAdd(toAdd: T) { override fun didAdd(toAdd: T) {
super.didAdd(toAdd) super.didAdd(toAdd)
@@ -22,13 +22,15 @@ import org.gradle.api.internal.project.ProjectInternal
import org.gradle.internal.reflect.Instantiator import org.gradle.internal.reflect.Instantiator
import org.jetbrains.kotlin.gradle.plugin.tasks.* import org.jetbrains.kotlin.gradle.plugin.tasks.*
import org.jetbrains.kotlin.konan.target.KonanTarget import org.jetbrains.kotlin.konan.target.KonanTarget
import org.jetbrains.kotlin.konan.target.KonanTarget.*
import java.io.File import java.io.File
abstract class KonanCompileConfig<T: KonanCompileTask>(name: String, abstract class KonanCompileConfig<T: KonanCompileTask>(name: String,
type: Class<T>, type: Class<T>,
project: ProjectInternal, project: ProjectInternal,
instantiator: Instantiator) instantiator: Instantiator,
: KonanBuildingConfig<T>(name, type, project, instantiator), KonanCompileSpec { targets: Iterable<String>)
: KonanBuildingConfig<T>(name, type, project, instantiator, targets), KonanCompileSpec {
protected abstract val typeForDescription: String protected abstract val typeForDescription: String
@@ -63,9 +65,16 @@ abstract class KonanCompileConfig<T: KonanCompileTask>(name: String,
override fun measureTime(flag: Boolean) = forEach { it.measureTime(flag) } override fun measureTime(flag: Boolean) = forEach { it.measureTime(flag) }
} }
open class KonanProgram(name: String, project: ProjectInternal, instantiator: Instantiator) open class KonanProgram(name: String,
: KonanCompileConfig<KonanCompileProgramTask>(name, KonanCompileProgramTask::class.java, project, instantiator) { project: ProjectInternal,
instantiator: Instantiator,
targets: Iterable<String> = project.konanExtension.targets
) : KonanCompileConfig<KonanCompileProgramTask>(name,
KonanCompileProgramTask::class.java,
project,
instantiator,
targets
) {
override val typeForDescription: String override val typeForDescription: String
get() = "executable" get() = "executable"
@@ -73,29 +82,55 @@ open class KonanProgram(name: String, project: ProjectInternal, instantiator: In
get() = project.konanBinBaseDir get() = project.konanBinBaseDir
} }
open class KonanDynamic(name: String, project: ProjectInternal, instantiator: Instantiator) open class KonanDynamic(name: String,
: KonanCompileConfig<KonanCompileDynamicTask>(name, KonanCompileDynamicTask::class.java, project, instantiator) { project: ProjectInternal,
instantiator: Instantiator,
targets: Iterable<String> = project.konanExtension.targets)
: KonanCompileConfig<KonanCompileDynamicTask>(name,
KonanCompileDynamicTask::class.java,
project,
instantiator,
targets
) {
override val typeForDescription: String override val typeForDescription: String
get() = "dynamic library" get() = "dynamic library"
override val defaultBaseDir: File override val defaultBaseDir: File
get() = project.konanBinBaseDir get() = project.konanBinBaseDir
override fun targetIsSupported(target: KonanTarget): Boolean = target != WASM32
} }
open class KonanFramework(name: String, project: ProjectInternal, instantiator: Instantiator) open class KonanFramework(name: String,
: KonanCompileConfig<KonanCompileFrameworkTask>(name, KonanCompileFrameworkTask::class.java, project, instantiator) { project: ProjectInternal,
instantiator: Instantiator,
targets: Iterable<String> = project.konanExtension.targets)
: KonanCompileConfig<KonanCompileFrameworkTask>(name,
KonanCompileFrameworkTask::class.java,
project,
instantiator,
targets
) {
override val typeForDescription: String override val typeForDescription: String
get() = "framework" get() = "framework"
override val defaultBaseDir: File override val defaultBaseDir: File
get() = project.konanBinBaseDir get() = project.konanBinBaseDir
override fun targetIsSupported(target: KonanTarget): Boolean =
target == MACBOOK || target == IPHONE_SIM || target == IPHONE_SIM
} }
open class KonanLibrary(name: String, project: ProjectInternal, instantiator: Instantiator) open class KonanLibrary(name: String,
: KonanCompileConfig<KonanCompileLibraryTask>(name, KonanCompileLibraryTask::class.java, project, instantiator) { project: ProjectInternal,
instantiator: Instantiator,
targets: Iterable<String> = project.konanExtension.targets)
: KonanCompileConfig<KonanCompileLibraryTask>(name,
KonanCompileLibraryTask::class.java,
project,
instantiator,
targets
) {
override val typeForDescription: String override val typeForDescription: String
get() = "library" get() = "library"
@@ -103,8 +138,16 @@ open class KonanLibrary(name: String, project: ProjectInternal, instantiator: In
get() = project.konanLibsBaseDir get() = project.konanLibsBaseDir
} }
open class KonanBitcode(name: String, project: ProjectInternal, instantiator: Instantiator) open class KonanBitcode(name: String,
: KonanCompileConfig<KonanCompileBitcodeTask>(name, KonanCompileBitcodeTask::class.java, project, instantiator) { project: ProjectInternal,
instantiator: Instantiator,
targets: Iterable<String> = project.konanExtension.targets)
: KonanCompileConfig<KonanCompileBitcodeTask>(name,
KonanCompileBitcodeTask::class.java,
project,
instantiator,
targets
) {
override val typeForDescription: String override val typeForDescription: String
get() = "bitcode" get() = "bitcode"
@@ -28,8 +28,13 @@ import org.jetbrains.kotlin.gradle.plugin.KonanInteropSpec.IncludeDirectoriesSpe
import org.jetbrains.kotlin.konan.target.KonanTarget import org.jetbrains.kotlin.konan.target.KonanTarget
import java.io.File import java.io.File
open class KonanInteropLibrary(name: String, project: ProjectInternal, instantiator: Instantiator) open class KonanInteropLibrary(name: String,
: KonanBuildingConfig<KonanInteropTask>(name, KonanInteropTask::class.java, project, instantiator), KonanInteropSpec { project: ProjectInternal,
instantiator: Instantiator,
targets: Iterable<String> = project.konanExtension.targets
) : KonanBuildingConfig<KonanInteropTask>(name, KonanInteropTask::class.java, project, instantiator, targets),
KonanInteropSpec
{
override fun generateTaskDescription(task: KonanInteropTask) = override fun generateTaskDescription(task: KonanInteropTask) =
"Build the Kotlin/Native interop library '${task.name}' for target '${task.konanTarget}'" "Build the Kotlin/Native interop library '${task.name}' for target '${task.konanTarget}'"