[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
|
||||
|
||||
import groovy.lang.Closure
|
||||
import org.gradle.api.Task
|
||||
import org.gradle.api.file.FileCollection
|
||||
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 measureTime(flag: Boolean) = forEach { it.measureTime(flag) }
|
||||
|
||||
override fun dependencies(closure: Closure<Unit>) = forEach { it.dependencies(closure) }
|
||||
}
|
||||
|
||||
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(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
|
||||
|
||||
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.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.plugins.AppliedPlugin
|
||||
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.jetbrains.kotlin.gradle.plugin.KonanPlugin.Companion.COMPILE_ALL_TASK_NAME
|
||||
import org.jetbrains.kotlin.gradle.plugin.tasks.*
|
||||
@@ -242,6 +256,18 @@ open class KonanExtension {
|
||||
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)
|
||||
: 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_GENERATE_CMAKE_TASK_NAME = "generateCMake"
|
||||
internal const val COMPILE_ALL_TASK_NAME = "compileKonan"
|
||||
internal const val KONAN_MAIN_VARIANT = "konan_main_variant"
|
||||
|
||||
internal const val KONAN_EXTENSION_NAME = "konan"
|
||||
|
||||
@@ -272,15 +299,20 @@ class KonanPlugin @Inject constructor(private val registry: ToolingModelBuilderR
|
||||
project.delete(it.artifact)
|
||||
}
|
||||
|
||||
|
||||
|
||||
override fun apply(project: ProjectInternal?) {
|
||||
if (project == null) { return }
|
||||
if (project == null) {
|
||||
return
|
||||
}
|
||||
registry.register(KonanToolingModelBuilder)
|
||||
project.plugins.apply("base")
|
||||
// Create necessary tasks and extensions.
|
||||
project.tasks.create(KONAN_DOWNLOAD_TASK_NAME, KonanCompilerDownloadTask::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(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.
|
||||
if (!project.hasProperty(ProjectProperty.KONAN_HOME)) {
|
||||
@@ -306,7 +338,7 @@ class KonanPlugin @Inject constructor(private val registry: ToolingModelBuilderR
|
||||
doLast {
|
||||
for (task in project.tasks
|
||||
.withType(KonanCompileProgramTask::class.java)
|
||||
.matching { !it.isCrossCompile}) {
|
||||
.matching { !it.isCrossCompile }) {
|
||||
project.exec {
|
||||
with(it) {
|
||||
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
|
||||
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 noDefaultLibs(flag: Boolean)
|
||||
fun dependencies(closure: Closure<Unit>)
|
||||
}
|
||||
|
||||
interface KonanBuildingSpec: KonanArtifactWithLibrariesSpec {
|
||||
|
||||
+44
-8
@@ -20,18 +20,21 @@ import groovy.lang.Closure
|
||||
import org.gradle.api.Action
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.tasks.Input
|
||||
import org.gradle.api.tasks.Internal
|
||||
import org.gradle.api.tasks.Nested
|
||||
import org.gradle.api.tasks.OutputFile
|
||||
import org.gradle.api.artifacts.Configuration
|
||||
import org.gradle.api.artifacts.PublishArtifact
|
||||
import org.gradle.api.attributes.Attribute
|
||||
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.jetbrains.kotlin.gradle.plugin.KonanArtifactSpec
|
||||
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.gradle.plugin.*
|
||||
import org.jetbrains.kotlin.konan.target.HostManager
|
||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||
import java.io.File
|
||||
import java.util.*
|
||||
|
||||
internal val Project.host
|
||||
get() = HostManager.host.visibleName
|
||||
@@ -63,6 +66,8 @@ abstract class KonanArtifactTask: KonanTargetableTask(), KonanArtifactSpec {
|
||||
|
||||
@Internal lateinit var destinationDir: File
|
||||
@Internal lateinit var artifactName: String
|
||||
@Internal lateinit var platformConfiguration: Configuration
|
||||
@Internal lateinit var configuration: Configuration
|
||||
|
||||
protected val artifactFullName: String
|
||||
@Internal get() = "$artifactPrefix$artifactName$artifactSuffix"
|
||||
@@ -80,8 +85,39 @@ abstract class KonanArtifactTask: KonanTargetableTask(), KonanArtifactSpec {
|
||||
super.init(target)
|
||||
this.destinationDir = destinationDir
|
||||
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.
|
||||
|
||||
override fun artifactName(name: String) {
|
||||
|
||||
+7
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.gradle.plugin.tasks
|
||||
|
||||
import org.gradle.api.artifacts.FileCollectionDependency
|
||||
import org.gradle.api.file.FileCollection
|
||||
import org.gradle.api.tasks.*
|
||||
import org.jetbrains.kotlin.gradle.plugin.*
|
||||
@@ -98,6 +99,12 @@ abstract class KonanCompileTask: KonanBuildingTask(), KonanCompileSpec {
|
||||
|
||||
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)
|
||||
addArgs("-library", libraries.namedKlibs)
|
||||
addArgs("-library", libraries.artifacts.map { it.artifact.canonicalPath })
|
||||
|
||||
Reference in New Issue
Block a user