diff --git a/platformLibs/build.gradle b/platformLibs/build.gradle index 1818b64e645..6c7ad5904a5 100644 --- a/platformLibs/build.gradle +++ b/platformLibs/build.gradle @@ -101,9 +101,8 @@ targetList.each { target -> def libName = defFileToLibName(target, df.name) def installTaskName = defFileToInstallTaskName(target, df.name) - konan.targets = [target] // TODO: Support custom targets in gradle plugin. konanArtifacts { - interop(libName) { + interop (libName, targets: [target]) { defFile df.file artifactName df.name noDefaultLibs true diff --git a/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanArtifactContainer.kt b/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanArtifactContainer.kt index ef1b1a856e2..24a1230cd19 100644 --- a/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanArtifactContainer.kt +++ b/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanArtifactContainer.kt @@ -18,11 +18,12 @@ package org.jetbrains.kotlin.gradle.plugin import groovy.lang.Closure import org.gradle.api.Action +import org.gradle.api.NamedDomainObjectFactory import org.gradle.api.internal.DefaultPolymorphicDomainObjectContainer import org.gradle.api.internal.project.ProjectInternal import org.gradle.internal.reflect.Instantiator import org.gradle.util.ConfigureUtil - +import kotlin.reflect.KClass open class KonanArtifactContainer(val project: ProjectInternal) : DefaultPolymorphicDomainObjectContainer>( @@ -30,78 +31,141 @@ open class KonanArtifactContainer(val project: ProjectInternal) project.services.get(Instantiator::class.java) ) { - init { - registerFactory(KonanProgram::class.java) { name -> - instantiator.newInstance(KonanProgram::class.java, name, project, instantiator) - } - registerFactory(KonanDynamic::class.java) { name -> - instantiator.newInstance(KonanDynamic::class.java, name, project, instantiator) - } - 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) - } + private inner class KonanBuildingConfigFactory>(val configClass: KClass) + : NamedDomainObjectFactory { + + var targets: Iterable = emptyList() + + override fun create(name: String?): T = + instantiator.newInstance(configClass.java, name, project, instantiator, targets) } - // TODO: Investigate if we can support the same DSL as project.task: - // program foo(targets: [target1, target2, target3]) { - // ... - // } + private val factories = mutableMapOf>, KonanBuildingConfigFactory<*>>() - fun program(name: String) = create(name, KonanProgram::class.java) - fun program(name: String, configureAction: Action) = - create(name, KonanProgram::class.java, configureAction) - fun program(name: String, configureAction: KonanProgram.() -> Unit) = - create(name, KonanProgram::class.java, configureAction) - fun program(name: String, configureAction: Closure<*>) = - program(name, ConfigureUtil.configureUsing(configureAction)) + private fun > createFactory(configClass: KClass) { + val factory = KonanBuildingConfigFactory(configClass) + super.registerFactory(configClass.java, factory) + factories.put(configClass, factory) + } - fun dynamic(name: String) = create(name, KonanDynamic::class.java) - fun dynamic(name: String, configureAction: Action) = - create(name, KonanDynamic::class.java, configureAction) - fun dynamic(name: String, configureAction: KonanDynamic.() -> Unit) = - create(name, KonanDynamic::class.java, configureAction) - fun dynamic(name: String, configureAction: Closure<*>) = - dynamic(name, ConfigureUtil.configureUsing(configureAction)) + init { + createFactory(KonanProgram::class) + createFactory(KonanDynamic::class) + createFactory(KonanFramework::class) + createFactory(KonanLibrary::class) + createFactory(KonanBitcode::class) + createFactory(KonanInteropLibrary::class) + } - fun framework(name: String) = create(name, KonanFramework::class.java) - fun framework(name: String, configureAction: Action) = - create(name, KonanFramework::class.java, configureAction) - fun framework(name: String, configureAction: KonanFramework.() -> Unit) = - create(name, KonanFramework::class.java, configureAction) - fun framework(name: String, configureAction: Closure<*>) = - framework(name, ConfigureUtil.configureUsing(configureAction)) + private fun determineTargets(configClass: KClass>, args: Map) { + val targetsArg = args["targets"] + val targets = when { + targetsArg == null -> project.konanExtension.targets + targetsArg is Iterable<*> -> targetsArg.map { it.toString() } + else -> listOf(targetsArg.toString()) + } + factories[configClass]?.targets = targets + } - fun library(name: String) = create(name, KonanLibrary::class.java) - fun library(name: String, configureAction: Action) = - create(name, KonanLibrary::class.java, configureAction) - fun library(name: String, configureAction: KonanLibrary.() -> Unit) = - create(name, KonanLibrary::class.java, configureAction) - fun library(name: String, configureAction: Closure<*>) = - library(name, ConfigureUtil.configureUsing(configureAction)) + private fun > create(name: String, + configClass: KClass, + args: Map, + configureAction: Action) { + determineTargets(configClass, args) + super.create(name, configClass.java, configureAction) + } - fun bitcode(name: String) = create(name, KonanBitcode::class.java) - fun bitcode(name: String, configureAction: Action) = - create(name, KonanBitcode::class.java, configureAction) - fun bitcode(name: String, configureAction: KonanBitcode.() -> Unit) = - create(name, KonanBitcode::class.java, configureAction) - fun bitcode(name: String, configureAction: Closure<*>) = - bitcode(name, ConfigureUtil.configureUsing(configureAction)) + private fun > create(name: String, + configClass: KClass, + args: Map, + configureAction: T.() -> Unit) { + determineTargets(configClass, args) + super.create(name, configClass.java, configureAction) + } - fun interop(name: String) = create(name, KonanInteropLibrary::class.java) - fun interop(name: String, configureAction: Action) = - create(name, KonanInteropLibrary::class.java, configureAction) - fun interop(name: String, configureAction: KonanInteropLibrary.() -> Unit) = - create(name, KonanInteropLibrary::class.java, configureAction) - fun interop(name: String, configureAction: Closure<*>) = - interop(name, ConfigureUtil.configureUsing(configureAction)) + private fun > create(name: String, + configClass: KClass, + args: Map) { + determineTargets(configClass, args) + super.create(name, configClass.java) + } + + fun program(args: Map, name: String) = create(name, KonanProgram::class, args) + fun program(args: Map, name: String, configureAction: Action) = + create(name, KonanProgram::class, args, configureAction) + fun program(args: Map, name: String, configureAction: KonanProgram.() -> Unit) = + create(name, KonanProgram::class, args, configureAction) + fun program(args: Map, name: String, configureAction: Closure<*>) = + program(args, name, ConfigureUtil.configureUsing(configureAction)) + + fun dynamic(args: Map, name: String) = create(name, KonanDynamic::class, args) + fun dynamic(args: Map, name: String, configureAction: Action) = + create(name, KonanDynamic::class, args, configureAction) + fun dynamic(args: Map, name: String, configureAction: KonanDynamic.() -> Unit) = + create(name, KonanDynamic::class, args, configureAction) + fun dynamic(args: Map, name: String, configureAction: Closure<*>) = + dynamic(args, name, ConfigureUtil.configureUsing(configureAction)) + + fun framework(args: Map, name: String) = create(name, KonanFramework::class, args) + fun framework(args: Map, name: String, configureAction: Action) = + create(name, KonanFramework::class, args, configureAction) + fun framework(args: Map, name: String, configureAction: KonanFramework.() -> Unit) = + create(name, KonanFramework::class, args, configureAction) + fun framework(args: Map, name: String, configureAction: Closure<*>) = + framework(args, name, ConfigureUtil.configureUsing(configureAction)) + + fun library(args: Map, name: String) = create(name, KonanLibrary::class, args) + fun library(args: Map, name: String, configureAction: Action) = + create(name, KonanLibrary::class, args, configureAction) + fun library(args: Map, name: String, configureAction: KonanLibrary.() -> Unit) = + create(name, KonanLibrary::class, args, configureAction) + fun library(args: Map, name: String, configureAction: Closure<*>) = + library(args, name, ConfigureUtil.configureUsing(configureAction)) + + fun bitcode(args: Map, name: String) = create(name, KonanBitcode::class, args) + fun bitcode(args: Map, name: String, configureAction: Action) = + create(name, KonanBitcode::class, args, configureAction) + fun bitcode(args: Map, name: String, configureAction: KonanBitcode.() -> Unit) = + create(name, KonanBitcode::class, args, configureAction) + fun bitcode(args: Map, name: String, configureAction: Closure<*>) = + bitcode(args, name, ConfigureUtil.configureUsing(configureAction)) + + fun interop(args: Map, name: String) = create(name, KonanInteropLibrary::class, args) + fun interop(args: Map, name: String, configureAction: Action) = + create(name, KonanInteropLibrary::class, args, configureAction) + fun interop(args: Map, name: String, configureAction: KonanInteropLibrary.() -> Unit) = + create(name, KonanInteropLibrary::class, args, configureAction) + fun interop(args: Map, name: String, configureAction: Closure<*>) = + interop(args, name, ConfigureUtil.configureUsing(configureAction)) + + fun program(name: String) = program(emptyMap(), name) + fun program(name: String, configureAction: Action) = 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) = 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) = 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) = 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) = 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) = 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) } diff --git a/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanBuildingConfig.kt b/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanBuildingConfig.kt index 50681cfa87b..53c73d1680f 100644 --- a/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanBuildingConfig.kt +++ b/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanBuildingConfig.kt @@ -36,7 +36,8 @@ import java.io.File abstract class KonanBuildingConfig(private val name_: String, type: Class, val project: ProjectInternal, - instantiator: Instantiator) + instantiator: Instantiator, + val targets: Iterable) : KonanBuildingSpec, Named, DefaultNamedDomainObjectSet(type, instantiator, { it.konanTarget.visibleName }) { override fun getName() = name_ @@ -45,15 +46,20 @@ abstract class KonanBuildingConfig(private val name_: Stri internal val aggregateBuildTask: Task - val declaredTargets: Iterable = project.konanTargets + private val konanTargets: Iterable + get() = targets.map { TargetManager(it).target }.distinct() init { - declaredTargets.forEach { - if (it.enabled) { - super.add(createTask(it)) - } else { - project.logger.warn("The target is not enabled on the current host: ${it.visibleName}") + for (target in konanTargets) { + if (!target.enabled) { + project.logger.warn("The target is not enabled on the current host: ${target.visibleName}") + continue } + if (!targetIsSupported(target)) { + project.logger.warn("The target ${target.visibleName} is not supported by the artifact $name") + continue + } + super.add(createTask(target)) } aggregateBuildTask = createAggregateTask() createHostTaskIfDeclared() @@ -74,6 +80,8 @@ abstract class KonanBuildingConfig(private val name_: Stri protected abstract val defaultBaseDir: File + protected open fun targetIsSupported(target: KonanTarget): Boolean = true + override fun didAdd(toAdd: T) { super.didAdd(toAdd) diff --git a/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanCompileConfig.kt b/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanCompileConfig.kt index f23617c284f..bb123f9a30e 100644 --- a/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanCompileConfig.kt +++ b/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanCompileConfig.kt @@ -22,13 +22,15 @@ import org.gradle.api.internal.project.ProjectInternal import org.gradle.internal.reflect.Instantiator import org.jetbrains.kotlin.gradle.plugin.tasks.* import org.jetbrains.kotlin.konan.target.KonanTarget +import org.jetbrains.kotlin.konan.target.KonanTarget.* import java.io.File abstract class KonanCompileConfig(name: String, type: Class, project: ProjectInternal, - instantiator: Instantiator) - : KonanBuildingConfig(name, type, project, instantiator), KonanCompileSpec { + instantiator: Instantiator, + targets: Iterable) + : KonanBuildingConfig(name, type, project, instantiator, targets), KonanCompileSpec { protected abstract val typeForDescription: String @@ -63,9 +65,16 @@ abstract class KonanCompileConfig(name: String, override fun measureTime(flag: Boolean) = forEach { it.measureTime(flag) } } -open class KonanProgram(name: String, project: ProjectInternal, instantiator: Instantiator) - : KonanCompileConfig(name, KonanCompileProgramTask::class.java, project, instantiator) { - +open class KonanProgram(name: String, + project: ProjectInternal, + instantiator: Instantiator, + targets: Iterable = project.konanExtension.targets +) : KonanCompileConfig(name, + KonanCompileProgramTask::class.java, + project, + instantiator, + targets +) { override val typeForDescription: String get() = "executable" @@ -73,29 +82,55 @@ open class KonanProgram(name: String, project: ProjectInternal, instantiator: In get() = project.konanBinBaseDir } -open class KonanDynamic(name: String, project: ProjectInternal, instantiator: Instantiator) - : KonanCompileConfig(name, KonanCompileDynamicTask::class.java, project, instantiator) { - +open class KonanDynamic(name: String, + project: ProjectInternal, + instantiator: Instantiator, + targets: Iterable = project.konanExtension.targets) + : KonanCompileConfig(name, + KonanCompileDynamicTask::class.java, + project, + instantiator, + targets +) { override val typeForDescription: String get() = "dynamic library" override val defaultBaseDir: File get() = project.konanBinBaseDir + + override fun targetIsSupported(target: KonanTarget): Boolean = target != WASM32 } -open class KonanFramework(name: String, project: ProjectInternal, instantiator: Instantiator) - : KonanCompileConfig(name, KonanCompileFrameworkTask::class.java, project, instantiator) { - +open class KonanFramework(name: String, + project: ProjectInternal, + instantiator: Instantiator, + targets: Iterable = project.konanExtension.targets) + : KonanCompileConfig(name, + KonanCompileFrameworkTask::class.java, + project, + instantiator, + targets +) { override val typeForDescription: String get() = "framework" override val defaultBaseDir: File 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) - : KonanCompileConfig(name, KonanCompileLibraryTask::class.java, project, instantiator) { - +open class KonanLibrary(name: String, + project: ProjectInternal, + instantiator: Instantiator, + targets: Iterable = project.konanExtension.targets) + : KonanCompileConfig(name, + KonanCompileLibraryTask::class.java, + project, + instantiator, + targets +) { override val typeForDescription: String get() = "library" @@ -103,8 +138,16 @@ open class KonanLibrary(name: String, project: ProjectInternal, instantiator: In get() = project.konanLibsBaseDir } -open class KonanBitcode(name: String, project: ProjectInternal, instantiator: Instantiator) - : KonanCompileConfig(name, KonanCompileBitcodeTask::class.java, project, instantiator) { +open class KonanBitcode(name: String, + project: ProjectInternal, + instantiator: Instantiator, + targets: Iterable = project.konanExtension.targets) + : KonanCompileConfig(name, + KonanCompileBitcodeTask::class.java, + project, + instantiator, + targets +) { override val typeForDescription: String get() = "bitcode" diff --git a/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanInteropLibrary.kt b/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanInteropLibrary.kt index 6e2ac5a0f23..b09559c1074 100644 --- a/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanInteropLibrary.kt +++ b/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanInteropLibrary.kt @@ -28,8 +28,13 @@ import org.jetbrains.kotlin.gradle.plugin.KonanInteropSpec.IncludeDirectoriesSpe import org.jetbrains.kotlin.konan.target.KonanTarget import java.io.File -open class KonanInteropLibrary(name: String, project: ProjectInternal, instantiator: Instantiator) - : KonanBuildingConfig(name, KonanInteropTask::class.java, project, instantiator), KonanInteropSpec { +open class KonanInteropLibrary(name: String, + project: ProjectInternal, + instantiator: Instantiator, + targets: Iterable = project.konanExtension.targets +) : KonanBuildingConfig(name, KonanInteropTask::class.java, project, instantiator, targets), + KonanInteropSpec +{ override fun generateTaskDescription(task: KonanInteropTask) = "Build the Kotlin/Native interop library '${task.name}' for target '${task.konanTarget}'"