[gradle][plugin][konan] deployment of kotlin-native artifacts via maven machinery
This commit is contained in:
committed by
Vasily Levchenko
parent
ddcbe68a5b
commit
5185a17c24
+3
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.gradle.plugin
|
package org.jetbrains.kotlin.gradle.plugin
|
||||||
|
|
||||||
|
import groovy.lang.Closure
|
||||||
import org.gradle.api.Task
|
import org.gradle.api.Task
|
||||||
import org.gradle.api.file.FileCollection
|
import org.gradle.api.file.FileCollection
|
||||||
import org.gradle.api.internal.project.ProjectInternal
|
import org.gradle.api.internal.project.ProjectInternal
|
||||||
@@ -68,6 +69,8 @@ abstract class KonanCompileConfig<T: KonanCompileTask>(name: String,
|
|||||||
override fun entryPoint(entryPoint: String) = forEach { it.entryPoint(entryPoint) }
|
override fun entryPoint(entryPoint: String) = forEach { it.entryPoint(entryPoint) }
|
||||||
|
|
||||||
override fun measureTime(flag: Boolean) = forEach { it.measureTime(flag) }
|
override fun measureTime(flag: Boolean) = forEach { it.measureTime(flag) }
|
||||||
|
|
||||||
|
override fun dependencies(closure: Closure<Unit>) = forEach { it.dependencies(closure) }
|
||||||
}
|
}
|
||||||
|
|
||||||
open class KonanProgram(name: String,
|
open class KonanProgram(name: String,
|
||||||
|
|||||||
+1
@@ -84,5 +84,6 @@ open class KonanInteropLibrary(name: String,
|
|||||||
|
|
||||||
override fun link(vararg files: Any) = forEach { it.link(*files) }
|
override fun link(vararg files: Any) = forEach { it.link(*files) }
|
||||||
override fun link(files: FileCollection) = forEach { it.link(files) }
|
override fun link(files: FileCollection) = forEach { it.link(files) }
|
||||||
|
override fun dependencies(closure: Closure<Unit>) = forEach { it.dependencies(closure) }
|
||||||
|
|
||||||
}
|
}
|
||||||
+66
-4
@@ -17,9 +17,23 @@
|
|||||||
package org.jetbrains.kotlin.gradle.plugin
|
package org.jetbrains.kotlin.gradle.plugin
|
||||||
|
|
||||||
import org.gradle.api.*
|
import org.gradle.api.*
|
||||||
|
import org.gradle.api.artifacts.PublishArtifact
|
||||||
|
import org.gradle.api.attributes.Usage
|
||||||
|
import org.gradle.api.component.ComponentWithVariants
|
||||||
|
import org.gradle.api.component.SoftwareComponent
|
||||||
import org.gradle.api.file.FileCollection
|
import org.gradle.api.file.FileCollection
|
||||||
|
import org.gradle.api.internal.FeaturePreviews
|
||||||
|
import org.gradle.api.internal.component.SoftwareComponentInternal
|
||||||
|
import org.gradle.api.internal.component.UsageContext
|
||||||
import org.gradle.api.internal.project.ProjectInternal
|
import org.gradle.api.internal.project.ProjectInternal
|
||||||
|
import org.gradle.api.plugins.AppliedPlugin
|
||||||
import org.gradle.api.plugins.BasePlugin
|
import org.gradle.api.plugins.BasePlugin
|
||||||
|
import org.gradle.api.publish.PublishingExtension
|
||||||
|
import org.gradle.api.publish.internal.PublicationInternal
|
||||||
|
import org.gradle.api.publish.maven.MavenPublication
|
||||||
|
import org.gradle.api.publish.maven.internal.publication.MavenPublicationInternal
|
||||||
|
import org.gradle.language.cpp.internal.NativeVariant
|
||||||
|
import org.gradle.language.nativeplatform.internal.Names
|
||||||
import org.gradle.tooling.provider.model.ToolingModelBuilderRegistry
|
import org.gradle.tooling.provider.model.ToolingModelBuilderRegistry
|
||||||
import org.jetbrains.kotlin.gradle.plugin.KonanPlugin.Companion.COMPILE_ALL_TASK_NAME
|
import org.jetbrains.kotlin.gradle.plugin.KonanPlugin.Companion.COMPILE_ALL_TASK_NAME
|
||||||
import org.jetbrains.kotlin.gradle.plugin.tasks.*
|
import org.jetbrains.kotlin.gradle.plugin.tasks.*
|
||||||
@@ -242,6 +256,18 @@ open class KonanExtension {
|
|||||||
var jvmArgs = mutableListOf<String>()
|
var jvmArgs = mutableListOf<String>()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
open class KonanSoftwareComponent(val project: ProjectInternal?): SoftwareComponentInternal, ComponentWithVariants {
|
||||||
|
private val usages = mutableSetOf<UsageContext>()
|
||||||
|
override fun getUsages(): MutableSet<out UsageContext> = usages
|
||||||
|
|
||||||
|
private val variants = mutableSetOf<SoftwareComponent>()
|
||||||
|
override fun getName() = "main"
|
||||||
|
|
||||||
|
override fun getVariants(): Set<out SoftwareComponent> = variants
|
||||||
|
|
||||||
|
fun addVariant(component: SoftwareComponent) = variants.add(component)
|
||||||
|
}
|
||||||
|
|
||||||
class KonanPlugin @Inject constructor(private val registry: ToolingModelBuilderRegistry)
|
class KonanPlugin @Inject constructor(private val registry: ToolingModelBuilderRegistry)
|
||||||
: Plugin<ProjectInternal> {
|
: Plugin<ProjectInternal> {
|
||||||
|
|
||||||
@@ -259,6 +285,7 @@ class KonanPlugin @Inject constructor(private val registry: ToolingModelBuilderR
|
|||||||
internal const val KONAN_DOWNLOAD_TASK_NAME = "checkKonanCompiler"
|
internal const val KONAN_DOWNLOAD_TASK_NAME = "checkKonanCompiler"
|
||||||
internal const val KONAN_GENERATE_CMAKE_TASK_NAME = "generateCMake"
|
internal const val KONAN_GENERATE_CMAKE_TASK_NAME = "generateCMake"
|
||||||
internal const val COMPILE_ALL_TASK_NAME = "compileKonan"
|
internal const val COMPILE_ALL_TASK_NAME = "compileKonan"
|
||||||
|
internal const val KONAN_MAIN_VARIANT = "konan_main_variant"
|
||||||
|
|
||||||
internal const val KONAN_EXTENSION_NAME = "konan"
|
internal const val KONAN_EXTENSION_NAME = "konan"
|
||||||
|
|
||||||
@@ -272,15 +299,20 @@ class KonanPlugin @Inject constructor(private val registry: ToolingModelBuilderR
|
|||||||
project.delete(it.artifact)
|
project.delete(it.artifact)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
override fun apply(project: ProjectInternal?) {
|
override fun apply(project: ProjectInternal?) {
|
||||||
if (project == null) { return }
|
if (project == null) {
|
||||||
|
return
|
||||||
|
}
|
||||||
registry.register(KonanToolingModelBuilder)
|
registry.register(KonanToolingModelBuilder)
|
||||||
project.plugins.apply("base")
|
project.plugins.apply("base")
|
||||||
// Create necessary tasks and extensions.
|
// Create necessary tasks and extensions.
|
||||||
project.tasks.create(KONAN_DOWNLOAD_TASK_NAME, KonanCompilerDownloadTask::class.java)
|
project.tasks.create(KONAN_DOWNLOAD_TASK_NAME, KonanCompilerDownloadTask::class.java)
|
||||||
project.tasks.create(KONAN_GENERATE_CMAKE_TASK_NAME, KonanGenerateCMakeTask::class.java)
|
project.tasks.create(KONAN_GENERATE_CMAKE_TASK_NAME, KonanGenerateCMakeTask::class.java)
|
||||||
project.extensions.create(KONAN_EXTENSION_NAME, KonanExtension::class.java)
|
project.extensions.create(KONAN_EXTENSION_NAME, KonanExtension::class.java)
|
||||||
project.extensions.create(KonanArtifactContainer::class.java, ARTIFACTS_CONTAINER_NAME, KonanArtifactContainer::class.java, project)
|
val mainVariant = project.extensions.create(ComponentWithVariants::class.java, KONAN_MAIN_VARIANT, KonanSoftwareComponent::class.java, project)
|
||||||
|
val container = project.extensions.create(KonanArtifactContainer::class.java, ARTIFACTS_CONTAINER_NAME, KonanArtifactContainer::class.java, project)
|
||||||
|
|
||||||
// Set additional project properties like konan.home, konan.build.targets etc.
|
// Set additional project properties like konan.home, konan.build.targets etc.
|
||||||
if (!project.hasProperty(ProjectProperty.KONAN_HOME)) {
|
if (!project.hasProperty(ProjectProperty.KONAN_HOME)) {
|
||||||
@@ -306,7 +338,7 @@ class KonanPlugin @Inject constructor(private val registry: ToolingModelBuilderR
|
|||||||
doLast {
|
doLast {
|
||||||
for (task in project.tasks
|
for (task in project.tasks
|
||||||
.withType(KonanCompileProgramTask::class.java)
|
.withType(KonanCompileProgramTask::class.java)
|
||||||
.matching { !it.isCrossCompile}) {
|
.matching { !it.isCrossCompile }) {
|
||||||
project.exec {
|
project.exec {
|
||||||
with(it) {
|
with(it) {
|
||||||
commandLine(task.artifact.canonicalPath)
|
commandLine(task.artifact.canonicalPath)
|
||||||
@@ -318,8 +350,38 @@ class KonanPlugin @Inject constructor(private val registry: ToolingModelBuilderR
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//project.gradle.experimentalFeatures.enable()
|
||||||
|
project.gradle.services.get(FeaturePreviews::class.java).enableFeature(FeaturePreviews.Feature.GRADLE_METADATA)
|
||||||
// Enable multiplatform support
|
// Enable multiplatform support
|
||||||
project.pluginManager.apply(KotlinNativePlatformPlugin::class.java)
|
project.pluginManager.apply(KotlinNativePlatformPlugin::class.java)
|
||||||
|
project.afterEvaluate {
|
||||||
|
val konanSoftwareComponent = mainVariant as KonanSoftwareComponent
|
||||||
|
project.pluginManager.withPlugin("maven-publish") {
|
||||||
|
container.all {
|
||||||
|
val buildingConfig = it
|
||||||
|
val artifactId = buildingConfig.name
|
||||||
|
project.extensions.configure(PublishingExtension::class.java) {
|
||||||
|
val publishing = it
|
||||||
|
it.publications.create(artifactId, MavenPublication::class.java) {
|
||||||
|
it.artifactId = artifactId
|
||||||
|
it.groupId = project.group.toString()
|
||||||
|
it.from(konanSoftwareComponent)
|
||||||
|
(it as MavenPublicationInternal).publishWithOriginalFileName()
|
||||||
|
}
|
||||||
|
for (v in konanSoftwareComponent.variants) {
|
||||||
|
// TODO: with gradle 4.7 don't forget to change to SoftwareComponentsWithCoordinates
|
||||||
|
val name = "${v.name}/$artifactId"
|
||||||
|
publishing.publications.create(name, MavenPublication::class.java) {
|
||||||
|
it.artifactId = "${artifactId}-${v.name}"
|
||||||
|
it.groupId = project.group.toString()
|
||||||
|
it.version = project.version.toString()
|
||||||
|
it.from(v)
|
||||||
|
(it as MavenPublicationInternal).publishWithOriginalFileName()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
@@ -31,6 +31,7 @@ interface KonanArtifactWithLibrariesSpec: KonanArtifactSpec {
|
|||||||
fun libraries(configure: KonanLibrariesSpec.() -> Unit)
|
fun libraries(configure: KonanLibrariesSpec.() -> Unit)
|
||||||
|
|
||||||
fun noDefaultLibs(flag: Boolean)
|
fun noDefaultLibs(flag: Boolean)
|
||||||
|
fun dependencies(closure: Closure<Unit>)
|
||||||
}
|
}
|
||||||
|
|
||||||
interface KonanBuildingSpec: KonanArtifactWithLibrariesSpec {
|
interface KonanBuildingSpec: KonanArtifactWithLibrariesSpec {
|
||||||
|
|||||||
+44
-8
@@ -20,18 +20,21 @@ import groovy.lang.Closure
|
|||||||
import org.gradle.api.Action
|
import org.gradle.api.Action
|
||||||
import org.gradle.api.DefaultTask
|
import org.gradle.api.DefaultTask
|
||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
import org.gradle.api.tasks.Input
|
import org.gradle.api.artifacts.Configuration
|
||||||
import org.gradle.api.tasks.Internal
|
import org.gradle.api.artifacts.PublishArtifact
|
||||||
import org.gradle.api.tasks.Nested
|
import org.gradle.api.attributes.Attribute
|
||||||
import org.gradle.api.tasks.OutputFile
|
import org.gradle.api.attributes.Usage
|
||||||
|
import org.gradle.api.tasks.*
|
||||||
|
import org.gradle.language.cpp.CppBinary
|
||||||
|
import org.gradle.language.cpp.internal.NativeVariant
|
||||||
|
import org.gradle.language.nativeplatform.internal.Names
|
||||||
|
import org.gradle.nativeplatform.Linkage
|
||||||
import org.gradle.util.ConfigureUtil
|
import org.gradle.util.ConfigureUtil
|
||||||
import org.jetbrains.kotlin.gradle.plugin.KonanArtifactSpec
|
import org.jetbrains.kotlin.gradle.plugin.*
|
||||||
import org.jetbrains.kotlin.gradle.plugin.KonanArtifactWithLibrariesSpec
|
|
||||||
import org.jetbrains.kotlin.gradle.plugin.KonanLibrariesSpec
|
|
||||||
import org.jetbrains.kotlin.gradle.plugin.konanTargets
|
|
||||||
import org.jetbrains.kotlin.konan.target.HostManager
|
import org.jetbrains.kotlin.konan.target.HostManager
|
||||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
internal val Project.host
|
internal val Project.host
|
||||||
get() = HostManager.host.visibleName
|
get() = HostManager.host.visibleName
|
||||||
@@ -63,6 +66,8 @@ abstract class KonanArtifactTask: KonanTargetableTask(), KonanArtifactSpec {
|
|||||||
|
|
||||||
@Internal lateinit var destinationDir: File
|
@Internal lateinit var destinationDir: File
|
||||||
@Internal lateinit var artifactName: String
|
@Internal lateinit var artifactName: String
|
||||||
|
@Internal lateinit var platformConfiguration: Configuration
|
||||||
|
@Internal lateinit var configuration: Configuration
|
||||||
|
|
||||||
protected val artifactFullName: String
|
protected val artifactFullName: String
|
||||||
@Internal get() = "$artifactPrefix$artifactName$artifactSuffix"
|
@Internal get() = "$artifactPrefix$artifactName$artifactSuffix"
|
||||||
@@ -80,8 +85,39 @@ abstract class KonanArtifactTask: KonanTargetableTask(), KonanArtifactSpec {
|
|||||||
super.init(target)
|
super.init(target)
|
||||||
this.destinationDir = destinationDir
|
this.destinationDir = destinationDir
|
||||||
this.artifactName = artifactName
|
this.artifactName = artifactName
|
||||||
|
configuration = project.configurations.maybeCreate("artifact$artifactName")
|
||||||
|
platformConfiguration = project.configurations.create("artifact${artifactName}_${target.name}")
|
||||||
|
platformConfiguration.extendsFrom(configuration)
|
||||||
|
platformConfiguration.attributes{
|
||||||
|
it.attribute(Usage.USAGE_ATTRIBUTE, project.objects.named(Usage::class.java, Usage.NATIVE_LINK))
|
||||||
|
it.attribute(CppBinary.LINKAGE_ATTRIBUTE, Linkage.STATIC)
|
||||||
|
it.attribute(CppBinary.OPTIMIZED_ATTRIBUTE, false)
|
||||||
|
it.attribute(CppBinary.DEBUGGABLE_ATTRIBUTE, false)
|
||||||
|
it.attribute(Attribute.of("org.gradle.native.kotlin.platform", String::class.java), target.name)
|
||||||
|
}
|
||||||
|
|
||||||
|
project.pluginManager.withPlugin("maven-publish") {
|
||||||
|
platformConfiguration.artifacts.add(object: PublishArtifact {
|
||||||
|
override fun getName() = "${artifact.name}/${target.name}"
|
||||||
|
override fun getExtension() = if (artifactSuffix.startsWith('.')) artifactSuffix.substring(1) else artifactSuffix
|
||||||
|
override fun getType() = artifactSuffix
|
||||||
|
override fun getClassifier():String? = target.name
|
||||||
|
override fun getFile() = artifact
|
||||||
|
override fun getDate() = Date(artifact.lastModified())
|
||||||
|
override fun getBuildDependencies(): TaskDependency = this@KonanArtifactTask.taskDependencies
|
||||||
|
})
|
||||||
|
val objectFactory = project.objects
|
||||||
|
val linkUsage = objectFactory.named(Usage::class.java, Usage.NATIVE_LINK)
|
||||||
|
val runtimeUsage = objectFactory.named(Usage::class.java, Usage.NATIVE_RUNTIME)
|
||||||
|
val konanSoftwareComponent = project.extensions.getByName(KonanPlugin.KONAN_MAIN_VARIANT) as KonanSoftwareComponent
|
||||||
|
konanSoftwareComponent.addVariant(NativeVariant(Names.of(target.name), linkUsage, null, linkUsage, platformConfiguration))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun dependencies(closure: Closure<Unit>) {
|
||||||
|
if (konanTarget in project.konanTargets)
|
||||||
|
project.dependencies(closure)
|
||||||
|
}
|
||||||
// DSL.
|
// DSL.
|
||||||
|
|
||||||
override fun artifactName(name: String) {
|
override fun artifactName(name: String) {
|
||||||
|
|||||||
+7
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.gradle.plugin.tasks
|
package org.jetbrains.kotlin.gradle.plugin.tasks
|
||||||
|
|
||||||
|
import org.gradle.api.artifacts.FileCollectionDependency
|
||||||
import org.gradle.api.file.FileCollection
|
import org.gradle.api.file.FileCollection
|
||||||
import org.gradle.api.tasks.*
|
import org.gradle.api.tasks.*
|
||||||
import org.jetbrains.kotlin.gradle.plugin.*
|
import org.jetbrains.kotlin.gradle.plugin.*
|
||||||
@@ -98,6 +99,12 @@ abstract class KonanCompileTask: KonanBuildingTask(), KonanCompileSpec {
|
|||||||
|
|
||||||
addArgs("-repo", libraries.repos.map { it.canonicalPath })
|
addArgs("-repo", libraries.repos.map { it.canonicalPath })
|
||||||
|
|
||||||
|
if (platformConfiguration.files.isNotEmpty()) {
|
||||||
|
platformConfiguration.files.filter { it.name.endsWith(".klib") }.forEach {
|
||||||
|
addFileArgs("-library", project.files(it.absolutePath))
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
addFileArgs("-library", libraries.files)
|
addFileArgs("-library", libraries.files)
|
||||||
addArgs("-library", libraries.namedKlibs)
|
addArgs("-library", libraries.namedKlibs)
|
||||||
addArgs("-library", libraries.artifacts.map { it.artifact.canonicalPath })
|
addArgs("-library", libraries.artifacts.map { it.artifact.canonicalPath })
|
||||||
|
|||||||
Reference in New Issue
Block a user