Rework Gradle plugin (#1666)
* [gradle-plugin] Basic implementation for the new plugin
* [gradle-plugin] Use one component for both libraries and executables
* [gradle-plugin] Support library compilation and publishing
* [gradle-plugin] Support compilation for different targets
* [gradle-plugin] Use different output paths for libs and kexe
* [gradle-plugin] Implement ProductionComponent
* [gradle-plugin] Add smoke tests for the new Gradle plugin
* [gradle-plugin] Backport to Gradle 4.7 and rename plugin package
* [gradle-plugin] Implement our own BuildType
* Remove the 'publish-release.sh' script
* [gradle-plugin] Support tests in new plugin
* [gradle-plugin] Refactor the new plugin
* Rename sourceSets.main.common -> sourceSets.main.kotlin.
* Generate dummy tasks for unsupported test targets.
* Add identities in publication for unsupported on the current
host targets.
* Provide a component DSL method for setting targets.
* [gradle-plugin] Codestyle fixes
* [gradle-plugin] Add checks for Gradle version and metadata
* [gradle-plugin] Support compiler downloading in the new plugin
* [gradle-plugin] Support MPP in the new Gradle plugin
* [gradle-plugin] Fix tests after removing implicit GRADLE_METADATA
This commit is contained in:
committed by
Vasily Levchenko
parent
3b8cb2a542
commit
67279c4148
@@ -166,5 +166,21 @@ gradlePlugin {
|
||||
id = 'konan'
|
||||
implementationClass = 'org.jetbrains.kotlin.gradle.plugin.KonanPlugin'
|
||||
}
|
||||
create("kotlin-native") {
|
||||
id = 'kotlin-native'
|
||||
implementationClass = 'org.jetbrains.kotlin.gradle.plugin.experimental.plugins.KotlinNativePlugin'
|
||||
}
|
||||
create("kotlin-platform-native") {
|
||||
id = 'kotlin-platform-native'
|
||||
implementationClass = 'org.jetbrains.kotlin.gradle.plugin.experimental.plugins.KotlinPlatformNativePlugin'
|
||||
}
|
||||
create("org.jetbrains.kotlin.native"){
|
||||
id = 'org.jetbrains.kotlin.native'
|
||||
implementationClass = 'org.jetbrains.kotlin.gradle.plugin.experimental.plugins.KotlinNativePlugin'
|
||||
}
|
||||
create("org.jetbrains.kotlin.platform.native") {
|
||||
id = 'org.jetbrains.kotlin.platform.native'
|
||||
implementationClass = 'org.jetbrains.kotlin.gradle.plugin.experimental.plugins.KotlinPlatformNativePlugin'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+15
-7
@@ -34,7 +34,12 @@ internal interface KonanToolRunner: Named {
|
||||
fun run(vararg args: String) = run(args.toList())
|
||||
}
|
||||
|
||||
internal abstract class KonanCliRunner(val toolName: String, val fullName: String, val project: Project): KonanToolRunner {
|
||||
internal abstract class KonanCliRunner(
|
||||
val toolName: String,
|
||||
val fullName: String,
|
||||
val project: Project,
|
||||
private val additionalJvmArgs: List<String>
|
||||
): KonanToolRunner {
|
||||
override val mainClass = "org.jetbrains.kotlin.cli.utilities.MainKt"
|
||||
|
||||
override fun getName() = toolName
|
||||
@@ -51,11 +56,11 @@ internal abstract class KonanCliRunner(val toolName: String, val fullName: Strin
|
||||
.apply { include("*.jar") }
|
||||
|
||||
override val jvmArgs = mutableListOf("-ea").apply {
|
||||
if (project.konanExtension.jvmArgs.none { it.startsWith("-Xmx") } &&
|
||||
if (additionalJvmArgs.none { it.startsWith("-Xmx") } &&
|
||||
project.jvmArgs.none { it.startsWith("-Xmx") }) {
|
||||
add("-Xmx3G")
|
||||
}
|
||||
addAll(project.konanExtension.jvmArgs)
|
||||
addAll(additionalJvmArgs)
|
||||
addAll(project.jvmArgs)
|
||||
}
|
||||
|
||||
@@ -87,8 +92,8 @@ internal abstract class KonanCliRunner(val toolName: String, val fullName: Strin
|
||||
}
|
||||
}
|
||||
|
||||
internal class KonanInteropRunner(project: Project)
|
||||
: KonanCliRunner("cinterop", "Kotlin/Native cinterop tool", project)
|
||||
internal class KonanInteropRunner(project: Project, additionalJvmArgs: List<String> = emptyList())
|
||||
: KonanCliRunner("cinterop", "Kotlin/Native cinterop tool", project, additionalJvmArgs)
|
||||
{
|
||||
init {
|
||||
if (HostManager.host == KonanTarget.MINGW_X64) {
|
||||
@@ -100,5 +105,8 @@ internal class KonanInteropRunner(project: Project)
|
||||
}
|
||||
}
|
||||
|
||||
internal class KonanCompilerRunner(project: Project) : KonanCliRunner("konanc", "Kotlin/Native compiler", project)
|
||||
internal class KonanKlibRunner(project: Project) : KonanCliRunner("klib", "Klib management tool", project)
|
||||
internal class KonanCompilerRunner(project: Project, additionalJvmArgs: List<String> = emptyList())
|
||||
: KonanCliRunner("konanc", "Kotlin/Native compiler", project, additionalJvmArgs)
|
||||
|
||||
internal class KonanKlibRunner(project: Project, additionalJvmArgs: List<String> = emptyList())
|
||||
: KonanCliRunner("klib", "Klib management tool", project, additionalJvmArgs)
|
||||
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
package org.jetbrains.kotlin.gradle.plugin.experimental
|
||||
|
||||
import org.gradle.api.component.SoftwareComponent
|
||||
import org.gradle.api.provider.Provider
|
||||
|
||||
interface ComponentWithBaseName: SoftwareComponent {
|
||||
fun getBaseName(): Provider<String>
|
||||
}
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
package org.jetbrains.kotlin.gradle.plugin.experimental
|
||||
|
||||
import org.gradle.api.attributes.Attribute
|
||||
import org.gradle.api.component.BuildableComponent
|
||||
import org.gradle.api.component.PublishableComponent
|
||||
import org.gradle.api.file.FileCollection
|
||||
import org.gradle.api.provider.Provider
|
||||
import org.gradle.language.ComponentWithDependencies
|
||||
import org.gradle.language.ComponentWithOutputs
|
||||
import org.gradle.language.nativeplatform.internal.ConfigurableComponentWithLinkUsage
|
||||
import org.gradle.language.nativeplatform.internal.ConfigurableComponentWithRuntimeUsage
|
||||
import org.gradle.nativeplatform.test.TestComponent
|
||||
import org.jetbrains.kotlin.gradle.plugin.experimental.internal.KotlinNativePlatform
|
||||
import org.jetbrains.kotlin.gradle.plugin.experimental.tasks.KotlinNativeCompile
|
||||
import org.jetbrains.kotlin.konan.target.CompilerOutputKind
|
||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||
|
||||
// TODO: implement ComponentWithObjectFiles when we build klibs as objects
|
||||
interface KotlinNativeBinary: ComponentWithDependencies, BuildableComponent {
|
||||
|
||||
/** Returns the source files of this binary. */
|
||||
val sources: FileCollection
|
||||
|
||||
/**
|
||||
* Konan target the library is built for
|
||||
*/
|
||||
val konanTarget: KonanTarget
|
||||
|
||||
/**
|
||||
* Gradle NativePlatform object the binary is built for.
|
||||
*/
|
||||
fun getTargetPlatform(): KotlinNativePlatform
|
||||
|
||||
/** Compile task for this library */
|
||||
val compileTask: Provider<KotlinNativeCompile>
|
||||
|
||||
// TODO: Support native link and runtime libraries here.
|
||||
// Looks like we need at least 3 file collections here: for klibs, for linktime native libraries and for runtime native libraries.
|
||||
/**
|
||||
* The link libraries (klibs only!) used to link this binary.
|
||||
* Includes the link libraries of the component's dependencies.
|
||||
*/
|
||||
val klibraries: FileCollection
|
||||
|
||||
/**
|
||||
* Binary kind in terms of the KN compiler (program, library, dynamic etc).
|
||||
*/
|
||||
val kind: CompilerOutputKind
|
||||
|
||||
/**
|
||||
* Additinal command line options passed to the compiler when this binary is compiled.
|
||||
*/
|
||||
val additionalCompilerOptions: MutableCollection<String>
|
||||
|
||||
companion object {
|
||||
val KONAN_TARGET_ATTRIBUTE = Attribute.of("org.gradle.native.kotlin.platform", String::class.java)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents Kotlin/Native executable.
|
||||
*/
|
||||
// TODO: Consider implementing ComponentWithExecutable and ComponentWithInstallation.
|
||||
interface KotlinNativeExecutable : KotlinNativeBinary,
|
||||
ComponentWithOutputs,
|
||||
PublishableComponent,
|
||||
ConfigurableComponentWithRuntimeUsage
|
||||
|
||||
/**
|
||||
* A component representing a klibrary.
|
||||
*/
|
||||
// TODO: Consider implementing ComponentWithLinkFile.
|
||||
interface KotlinNativeKLibrary : KotlinNativeBinary,
|
||||
ComponentWithOutputs,
|
||||
PublishableComponent,
|
||||
ConfigurableComponentWithLinkUsage
|
||||
|
||||
/**
|
||||
* Represents a test executable.
|
||||
*/
|
||||
// TODO: Consider implementing ComponentWithExecutable and ComponentWithInstallation.
|
||||
interface KotlinNativeTestExecutable : KotlinNativeBinary,
|
||||
ComponentWithOutputs,
|
||||
TestComponent
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
package org.jetbrains.kotlin.gradle.plugin.experimental
|
||||
|
||||
import org.gradle.api.artifacts.Configuration
|
||||
import org.gradle.api.provider.Provider
|
||||
import org.gradle.api.provider.SetProperty
|
||||
import org.gradle.language.BinaryCollection
|
||||
import org.gradle.language.ComponentWithBinaries
|
||||
import org.gradle.language.ComponentWithDependencies
|
||||
import org.gradle.nativeplatform.test.TestSuiteComponent
|
||||
import org.jetbrains.kotlin.gradle.plugin.experimental.sourcesets.KotlinNativeSourceSet
|
||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||
|
||||
/**
|
||||
* Class representing a Kotlin/Native component: application or library (both klib and dynamic)
|
||||
* built for different targets.
|
||||
*/
|
||||
interface KotlinNativeComponent: ComponentWithBinaries, ComponentWithDependencies {
|
||||
|
||||
/**
|
||||
* Defines the source files or directories of this component. You can add files or directories to this collection.
|
||||
* When a directory is added, all source files are included for compilation. When this collection is empty,
|
||||
* the directory src/main/kotlin is used by default.
|
||||
*/
|
||||
val sources: KotlinNativeSourceSet
|
||||
|
||||
/** Specifies Kotlin/Native targets used to build this component. */
|
||||
val konanTargets: SetProperty<KonanTarget>
|
||||
|
||||
/** Returns the binaries for this library. */
|
||||
override fun getBinaries(): BinaryCollection<out KotlinNativeBinary>
|
||||
|
||||
/** Returns the implementation dependencies of this component. */
|
||||
fun getImplementationDependencies(): Configuration
|
||||
|
||||
// region DSL
|
||||
|
||||
/** Set native targets for this component. */
|
||||
fun target(vararg targets: String)
|
||||
|
||||
// endregion
|
||||
}
|
||||
|
||||
/**
|
||||
* Class representing a test suite for Kotlin/Native
|
||||
*/
|
||||
interface KotlinNativeTestComponent : KotlinNativeComponent, TestSuiteComponent {
|
||||
val testedComponent: KotlinNativeComponent
|
||||
|
||||
override fun getTestBinary(): Provider<KotlinNativeTestExecutable>
|
||||
}
|
||||
+117
@@ -0,0 +1,117 @@
|
||||
package org.jetbrains.kotlin.gradle.plugin.experimental.internal
|
||||
|
||||
import org.gradle.api.artifacts.Configuration
|
||||
import org.gradle.api.artifacts.ConfigurationContainer
|
||||
import org.gradle.api.attributes.Usage
|
||||
import org.gradle.api.file.ConfigurableFileCollection
|
||||
import org.gradle.api.file.FileCollection
|
||||
import org.gradle.api.file.ProjectLayout
|
||||
import org.gradle.api.internal.file.FileOperations
|
||||
import org.gradle.api.model.ObjectFactory
|
||||
import org.gradle.api.provider.Property
|
||||
import org.gradle.api.provider.Provider
|
||||
import org.gradle.language.ComponentDependencies
|
||||
import org.gradle.language.ComponentWithDependencies
|
||||
import org.gradle.language.ComponentWithOutputs
|
||||
import org.gradle.language.cpp.CppBinary
|
||||
import org.gradle.language.internal.DefaultComponentDependencies
|
||||
import org.gradle.language.nativeplatform.internal.ComponentWithNames
|
||||
import org.gradle.language.nativeplatform.internal.Names
|
||||
import org.gradle.nativeplatform.OperatingSystemFamily
|
||||
import org.gradle.nativeplatform.toolchain.NativeToolChain
|
||||
import org.jetbrains.kotlin.gradle.plugin.experimental.ComponentWithBaseName
|
||||
import org.jetbrains.kotlin.gradle.plugin.experimental.KotlinNativeBinary
|
||||
import org.jetbrains.kotlin.gradle.plugin.experimental.sourcesets.KotlinNativeSourceSet
|
||||
import org.jetbrains.kotlin.gradle.plugin.experimental.tasks.KotlinNativeCompile
|
||||
import org.jetbrains.kotlin.konan.target.CompilerOutputKind
|
||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||
|
||||
/*
|
||||
* We use the same configuration hierarchy as Gradle native:
|
||||
*
|
||||
* componentImplementation (dependencies for the whole component ( = sourceSet): something like 'foo:bar:1.0')
|
||||
* ^
|
||||
* |
|
||||
* binaryImplementation (dependnecies of a particular target/flavor) (= getDependencies.implementationDependencies)
|
||||
* ^ ^ ^
|
||||
* | | |
|
||||
* linkLibraries runtimeLibraries klibs (dependencies by type: klib, static lib, shared lib etc)
|
||||
*
|
||||
*/
|
||||
abstract class AbstractKotlinNativeBinary(
|
||||
private val name: String,
|
||||
private val baseName: Provider<String>,
|
||||
val sourceSet: KotlinNativeSourceSet,
|
||||
val identity: KotlinNativeVariantIdentity,
|
||||
val projectLayout: ProjectLayout,
|
||||
override val kind: CompilerOutputKind,
|
||||
objects: ObjectFactory,
|
||||
componentImplementation: Configuration,
|
||||
configurations: ConfigurationContainer,
|
||||
val fileOperations: FileOperations
|
||||
) : KotlinNativeBinary,
|
||||
ComponentWithNames,
|
||||
ComponentWithDependencies,
|
||||
ComponentWithBaseName,
|
||||
ComponentWithOutputs
|
||||
{
|
||||
|
||||
private val names = Names.of(name)
|
||||
override fun getNames(): Names = names
|
||||
|
||||
override fun getName(): String = name
|
||||
|
||||
override val konanTarget: KonanTarget
|
||||
get() = identity.konanTarget
|
||||
|
||||
override fun getTargetPlatform(): KotlinNativePlatform = identity.targetPlatform
|
||||
|
||||
open val debuggable: Boolean get() = identity.isDebuggable
|
||||
open val optimized: Boolean get() = identity.isOptimized
|
||||
|
||||
override val sources: FileCollection
|
||||
get() = sourceSet.getAllSources(konanTarget)
|
||||
|
||||
private val dependencies = objects.newInstance<DefaultComponentDependencies>(
|
||||
DefaultComponentDependencies::class.java,
|
||||
name + "Implementation"
|
||||
).apply {
|
||||
implementationDependencies.extendsFrom(componentImplementation)
|
||||
}
|
||||
|
||||
override fun getDependencies(): ComponentDependencies = dependencies
|
||||
fun getImplementationDependencies(): Configuration = dependencies.implementationDependencies
|
||||
|
||||
// A configuration containing klibraries
|
||||
override val klibraries = configurations.create(names.withPrefix("klibraries")).apply {
|
||||
isCanBeConsumed = false
|
||||
attributes.attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage::class.java, KotlinNativeUsage.KLIB))
|
||||
attributes.attribute(CppBinary.DEBUGGABLE_ATTRIBUTE, debuggable)
|
||||
attributes.attribute(CppBinary.OPTIMIZED_ATTRIBUTE, optimized)
|
||||
attributes.attribute(KotlinNativeBinary.KONAN_TARGET_ATTRIBUTE, konanTarget.name)
|
||||
attributes.attribute(OperatingSystemFamily.OPERATING_SYSTEM_ATTRIBUTE, konanTarget.getGradleOSFamily(objects))
|
||||
extendsFrom(getImplementationDependencies())
|
||||
}
|
||||
|
||||
override fun getBaseName(): Provider<String> = baseName
|
||||
|
||||
override val compileTask: Property<KotlinNativeCompile> = objects.property(KotlinNativeCompile::class.java)
|
||||
|
||||
open fun isDebuggable(): Boolean = debuggable
|
||||
open fun isOptimized(): Boolean = optimized
|
||||
|
||||
// TODO: Support native libraries
|
||||
fun getLinkLibraries(): FileCollection = fileOperations.files()
|
||||
fun getRuntimeLibraries(): FileCollection = fileOperations.files()
|
||||
|
||||
fun getToolChain(): NativeToolChain =
|
||||
throw NotImplementedError("Kotlin/Native doesn't support the Gradle's toolchain model.")
|
||||
|
||||
/** A name of a root folder for this binary's output under the build directory. */
|
||||
internal abstract val outputRootName: String
|
||||
|
||||
private val outputs: ConfigurableFileCollection = fileOperations.files()
|
||||
override fun getOutputs() = outputs
|
||||
|
||||
override val additionalCompilerOptions = mutableListOf<String>()
|
||||
}
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
package org.jetbrains.kotlin.gradle.plugin.experimental.internal
|
||||
|
||||
import org.gradle.api.artifacts.Configuration
|
||||
import org.gradle.api.internal.file.FileOperations
|
||||
import org.gradle.api.internal.provider.LockableSetProperty
|
||||
import org.gradle.api.model.ObjectFactory
|
||||
import org.gradle.api.provider.Property
|
||||
import org.gradle.language.internal.DefaultBinaryCollection
|
||||
import org.gradle.language.internal.DefaultComponentDependencies
|
||||
import org.gradle.language.nativeplatform.internal.ComponentWithNames
|
||||
import org.gradle.language.nativeplatform.internal.DefaultNativeComponent
|
||||
import org.gradle.language.nativeplatform.internal.Names
|
||||
import org.jetbrains.kotlin.gradle.plugin.experimental.KotlinNativeBinary
|
||||
import org.jetbrains.kotlin.gradle.plugin.experimental.KotlinNativeComponent
|
||||
import org.jetbrains.kotlin.gradle.plugin.experimental.sourcesets.KotlinNativeSourceSetImpl
|
||||
import org.jetbrains.kotlin.konan.target.HostManager
|
||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||
import javax.inject.Inject
|
||||
|
||||
abstract class AbstractKotlinNativeComponent @Inject constructor(
|
||||
private val name: String,
|
||||
override val sources: KotlinNativeSourceSetImpl,
|
||||
val objectFactory: ObjectFactory,
|
||||
fileOperations: FileOperations
|
||||
) : DefaultNativeComponent(fileOperations),
|
||||
KotlinNativeComponent,
|
||||
ComponentWithNames {
|
||||
|
||||
private val baseName: Property<String> = objectFactory.property(String::class.java).apply { set(name) }
|
||||
fun getBaseName(): Property<String> = baseName
|
||||
|
||||
override val konanTargets: LockableSetProperty<KonanTarget> =
|
||||
LockableSetProperty(objectFactory.setProperty(KonanTarget::class.java)).apply {
|
||||
set(mutableSetOf(HostManager.host))
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
private val binaries = objectFactory.newInstance(DefaultBinaryCollection::class.java, KotlinNativeBinary::class.java)
|
||||
as DefaultBinaryCollection<KotlinNativeBinary>
|
||||
override fun getBinaries(): DefaultBinaryCollection<KotlinNativeBinary> = binaries
|
||||
|
||||
override fun getName(): String = name
|
||||
|
||||
private val names = Names.of(name)
|
||||
override fun getNames(): Names = names
|
||||
|
||||
private val dependencies: DefaultComponentDependencies = objectFactory.newInstance(
|
||||
DefaultComponentDependencies::class.java,
|
||||
names.withSuffix("implementation"))
|
||||
|
||||
override fun getDependencies() = dependencies
|
||||
|
||||
override fun getImplementationDependencies(): Configuration = dependencies.implementationDependencies
|
||||
|
||||
// region DSL
|
||||
|
||||
override fun target(vararg targets: String) {
|
||||
val hostManager = HostManager()
|
||||
konanTargets.set(targets.map { hostManager.targetByName(it) })
|
||||
}
|
||||
|
||||
// endregion
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
package org.jetbrains.kotlin.gradle.plugin.experimental.internal
|
||||
|
||||
import org.gradle.api.Named
|
||||
import java.util.*
|
||||
|
||||
class KotlinNativeBuildType(
|
||||
private val name: String,
|
||||
val debuggable: Boolean,
|
||||
val optimized: Boolean
|
||||
) : Named {
|
||||
|
||||
override fun getName() = name
|
||||
|
||||
companion object {
|
||||
val DEBUG = KotlinNativeBuildType("debug", true, false)
|
||||
val RELEASE = KotlinNativeBuildType("release", true, true)
|
||||
val DEFAULT_BUILD_TYPES: Collection<KotlinNativeBuildType> = Arrays.asList(DEBUG, RELEASE)
|
||||
}
|
||||
}
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
package org.jetbrains.kotlin.gradle.plugin.experimental.internal
|
||||
|
||||
import org.gradle.api.artifacts.Configuration
|
||||
import org.gradle.api.artifacts.ConfigurationContainer
|
||||
import org.gradle.api.artifacts.ModuleVersionIdentifier
|
||||
import org.gradle.api.attributes.AttributeContainer
|
||||
import org.gradle.api.component.PublishableComponent
|
||||
import org.gradle.api.file.ProjectLayout
|
||||
import org.gradle.api.file.RegularFileProperty
|
||||
import org.gradle.api.internal.component.SoftwareComponentInternal
|
||||
import org.gradle.api.internal.component.UsageContext
|
||||
import org.gradle.api.internal.file.FileOperations
|
||||
import org.gradle.api.model.ObjectFactory
|
||||
import org.gradle.api.provider.Property
|
||||
import org.gradle.api.provider.Provider
|
||||
import org.gradle.language.cpp.internal.DefaultUsageContext
|
||||
import org.gradle.nativeplatform.Linkage
|
||||
import org.jetbrains.kotlin.gradle.plugin.experimental.KotlinNativeExecutable
|
||||
import org.jetbrains.kotlin.gradle.plugin.experimental.sourcesets.KotlinNativeSourceSet
|
||||
import org.jetbrains.kotlin.konan.target.CompilerOutputKind
|
||||
import javax.inject.Inject
|
||||
|
||||
open class KotlinNativeExecutableImpl @Inject constructor(
|
||||
name: String,
|
||||
baseName: Provider<String>,
|
||||
componentImplementation: Configuration,
|
||||
sources: KotlinNativeSourceSet,
|
||||
identity: KotlinNativeVariantIdentity,
|
||||
objects: ObjectFactory,
|
||||
projectLayout: ProjectLayout,
|
||||
configurations: ConfigurationContainer,
|
||||
fileOperations: FileOperations
|
||||
) : AbstractKotlinNativeBinary(name,
|
||||
baseName,
|
||||
sources,
|
||||
identity,
|
||||
projectLayout,
|
||||
CompilerOutputKind.PROGRAM,
|
||||
objects,
|
||||
componentImplementation,
|
||||
configurations,
|
||||
fileOperations),
|
||||
KotlinNativeExecutable,
|
||||
SoftwareComponentInternal, // TODO: SoftwareComponentInternal will be replaced with ComponentWithVariants by Gradle
|
||||
PublishableComponent
|
||||
{
|
||||
override fun getCoordinates(): ModuleVersionIdentifier = identity.coordinates
|
||||
|
||||
// Properties
|
||||
|
||||
// Runtime elements configuration is created by the NativeBase plugin
|
||||
private val runtimeElementsProperty: Property<Configuration> = objects.property(Configuration::class.java)
|
||||
private val runtimeFileProperty: RegularFileProperty = projectLayout.fileProperty()
|
||||
|
||||
// Interface Implementation
|
||||
override fun getRuntimeElements() = runtimeElementsProperty
|
||||
override fun getRuntimeFile() = runtimeFileProperty
|
||||
|
||||
override fun hasRuntimeFile() = true
|
||||
override fun getRuntimeAttributes(): AttributeContainer = identity.runtimeUsageContext.attributes
|
||||
override fun getLinkage(): Linkage? = null
|
||||
|
||||
override fun getUsages(): Set<UsageContext> = runtimeElementsProperty.get().let {
|
||||
setOf(DefaultUsageContext(identity.runtimeUsageContext, it.allArtifacts, it))
|
||||
}
|
||||
|
||||
override val outputRootName = "exe"
|
||||
}
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
package org.jetbrains.kotlin.gradle.plugin.experimental.internal
|
||||
|
||||
import org.gradle.api.artifacts.Configuration
|
||||
import org.gradle.api.artifacts.ConfigurationContainer
|
||||
import org.gradle.api.artifacts.ModuleVersionIdentifier
|
||||
import org.gradle.api.attributes.AttributeContainer
|
||||
import org.gradle.api.component.PublishableComponent
|
||||
import org.gradle.api.file.ProjectLayout
|
||||
import org.gradle.api.file.RegularFileProperty
|
||||
import org.gradle.api.internal.component.SoftwareComponentInternal
|
||||
import org.gradle.api.internal.component.UsageContext
|
||||
import org.gradle.api.internal.file.FileOperations
|
||||
import org.gradle.api.model.ObjectFactory
|
||||
import org.gradle.api.provider.Property
|
||||
import org.gradle.api.provider.Provider
|
||||
import org.gradle.language.cpp.internal.DefaultUsageContext
|
||||
import org.gradle.nativeplatform.Linkage
|
||||
import org.jetbrains.kotlin.gradle.plugin.experimental.KotlinNativeKLibrary
|
||||
import org.jetbrains.kotlin.gradle.plugin.experimental.sourcesets.KotlinNativeSourceSet
|
||||
import org.jetbrains.kotlin.konan.target.CompilerOutputKind
|
||||
import javax.inject.Inject
|
||||
|
||||
open class KotlinNativeKLibraryImpl @Inject constructor(
|
||||
name: String,
|
||||
baseName: Provider<String>,
|
||||
componentImplementation: Configuration,
|
||||
sources: KotlinNativeSourceSet,
|
||||
identity: KotlinNativeVariantIdentity,
|
||||
objects: ObjectFactory,
|
||||
projectLayout: ProjectLayout,
|
||||
configurations: ConfigurationContainer,
|
||||
fileOperations: FileOperations
|
||||
) : AbstractKotlinNativeBinary(name,
|
||||
baseName,
|
||||
sources,
|
||||
identity,
|
||||
projectLayout,
|
||||
CompilerOutputKind.LIBRARY,
|
||||
objects,
|
||||
componentImplementation,
|
||||
configurations,
|
||||
fileOperations),
|
||||
KotlinNativeKLibrary,
|
||||
SoftwareComponentInternal, // TODO: SoftwareComponentInternal will be replaced with ComponentWithVariants by Gradle
|
||||
PublishableComponent
|
||||
{
|
||||
override fun getCoordinates(): ModuleVersionIdentifier = identity.coordinates
|
||||
|
||||
// Properties
|
||||
|
||||
// The link elements configuration is created by the NativeBase plugin.
|
||||
private val linkElementsProperty: Property<Configuration> = objects.property(Configuration::class.java)
|
||||
private val linkFileProperty: RegularFileProperty = projectLayout.fileProperty()
|
||||
|
||||
// Interface
|
||||
|
||||
override fun getLinkElements() = linkElementsProperty
|
||||
override fun getLinkFile() = linkFileProperty
|
||||
|
||||
override fun getUsages(): Set<UsageContext> = linkElementsProperty.get().let {
|
||||
setOf(DefaultUsageContext(identity.linkUsageContext, it.allArtifacts, it))
|
||||
}
|
||||
|
||||
override fun getLinkAttributes(): AttributeContainer = identity.linkUsageContext.attributes
|
||||
|
||||
// TODO: Does Klib really match a static linkage in Gradle's terms?
|
||||
override fun getLinkage(): Linkage? = Linkage.STATIC
|
||||
|
||||
override val outputRootName = "lib"
|
||||
}
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
package org.jetbrains.kotlin.gradle.plugin.experimental.internal
|
||||
|
||||
import org.gradle.api.component.ComponentWithVariants
|
||||
import org.gradle.api.component.SoftwareComponent
|
||||
import org.gradle.api.internal.component.SoftwareComponentInternal
|
||||
import org.gradle.api.internal.component.UsageContext
|
||||
import org.gradle.api.internal.file.FileOperations
|
||||
import org.gradle.api.internal.provider.LockableSetProperty
|
||||
import org.gradle.api.model.ObjectFactory
|
||||
import org.gradle.api.provider.Property
|
||||
import org.gradle.internal.Describables
|
||||
import org.gradle.internal.DisplayName
|
||||
import org.gradle.language.ProductionComponent
|
||||
import org.gradle.language.cpp.internal.NativeVariantIdentity
|
||||
import org.gradle.language.nativeplatform.internal.PublicationAwareComponent
|
||||
import org.jetbrains.kotlin.gradle.plugin.experimental.KotlinNativeBinary
|
||||
import org.jetbrains.kotlin.gradle.plugin.experimental.sourcesets.KotlinNativeSourceSetImpl
|
||||
import javax.inject.Inject
|
||||
|
||||
open class KotlinNativeMainComponent @Inject constructor(
|
||||
name: String,
|
||||
sources: KotlinNativeSourceSetImpl,
|
||||
objectFactory: ObjectFactory,
|
||||
fileOperations: FileOperations
|
||||
) : AbstractKotlinNativeComponent(name, sources, objectFactory, fileOperations),
|
||||
PublicationAwareComponent,
|
||||
ProductionComponent {
|
||||
|
||||
override fun getDisplayName(): DisplayName = Describables.withTypeAndName("Kotlin/Native component", name)
|
||||
|
||||
val outputKinds = LockableSetProperty(objectFactory.setProperty(OutputKind::class.java)).apply {
|
||||
set(mutableSetOf(OutputKind.KLIBRARY))
|
||||
}
|
||||
|
||||
private val mainPublication = KotlinNativeVariant()
|
||||
|
||||
override fun getMainPublication(): KotlinNativeVariant = mainPublication
|
||||
|
||||
private val developmentBinaryProperty: Property<KotlinNativeBinary> =
|
||||
objectFactory.property(KotlinNativeBinary::class.java)
|
||||
|
||||
override fun getDevelopmentBinary() = developmentBinaryProperty
|
||||
|
||||
private fun <T : KotlinNativeBinary> addBinary(type: Class<T>, identity: NativeVariantIdentity): T =
|
||||
objectFactory.newInstance(
|
||||
type,
|
||||
"$name${identity.name.capitalize()}",
|
||||
baseName,
|
||||
getImplementationDependencies(),
|
||||
sources,
|
||||
identity
|
||||
).apply {
|
||||
binaries.add(this)
|
||||
}
|
||||
|
||||
private inline fun <reified T : KotlinNativeBinary> addBinary(identity: NativeVariantIdentity): T =
|
||||
addBinary(T::class.java, identity)
|
||||
|
||||
fun addExecutable(identity: NativeVariantIdentity) = addBinary<KotlinNativeExecutableImpl>(identity)
|
||||
fun addKLibrary(identity: NativeVariantIdentity) = addBinary<KotlinNativeKLibraryImpl>(identity)
|
||||
|
||||
fun addBinary(kind: OutputKind, identity: NativeVariantIdentity) = addBinary(kind.binaryClass, identity)
|
||||
|
||||
|
||||
// region Kotlin/Native variant
|
||||
// TODO: SoftwareComponentInternal will be replaced with ComponentWithVariants by Gradle
|
||||
inner class KotlinNativeVariant: ComponentWithVariants, SoftwareComponentInternal {
|
||||
|
||||
private val variants = mutableSetOf<SoftwareComponent>()
|
||||
override fun getVariants() = variants
|
||||
|
||||
override fun getName(): String = this@KotlinNativeMainComponent.name
|
||||
|
||||
override fun getUsages(): Set<UsageContext> = emptySet()
|
||||
|
||||
}
|
||||
// endregion
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
val EXECUTABLE = OutputKind.EXECUTABLE
|
||||
|
||||
@JvmStatic
|
||||
val KLIBRARY = OutputKind.KLIBRARY
|
||||
}
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
package org.jetbrains.kotlin.gradle.plugin.experimental.internal
|
||||
|
||||
import org.gradle.api.model.ObjectFactory
|
||||
import org.gradle.internal.os.OperatingSystem
|
||||
import org.gradle.nativeplatform.OperatingSystemFamily
|
||||
import org.gradle.nativeplatform.platform.NativePlatform
|
||||
import org.gradle.nativeplatform.platform.internal.*
|
||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||
import org.jetbrains.kotlin.konan.util.visibleName
|
||||
|
||||
interface KotlinNativePlatform: NativePlatform {
|
||||
val target: KonanTarget
|
||||
}
|
||||
|
||||
fun KonanTarget.getGradleOS(): OperatingSystemInternal = family.visibleName.let {
|
||||
DefaultOperatingSystem(it, OperatingSystem.forName(it))
|
||||
}
|
||||
|
||||
fun KonanTarget.getGradleOSFamily(objectFactory: ObjectFactory): OperatingSystemFamily {
|
||||
return objectFactory.named(OperatingSystemFamily::class.java, family.visibleName)
|
||||
}
|
||||
|
||||
fun KonanTarget.getGradleCPU(): ArchitectureInternal = architecture.visibleName.let {
|
||||
Architectures.forInput(it)
|
||||
}
|
||||
|
||||
class DefaultKotlinNativePlatform(name: String, override val target: KonanTarget):
|
||||
DefaultNativePlatform(name, target.getGradleOS(), target.getGradleCPU()),
|
||||
KotlinNativePlatform
|
||||
{
|
||||
constructor(target: KonanTarget): this(target.visibleName, target)
|
||||
|
||||
// TODO: Extend ImmutableDefaultNativePlatform and get rid of these methods after switch to Gradle 4.8
|
||||
private fun notImplemented(): Nothing = throw NotImplementedError("Not Implemented in Kotlin/Native plugin")
|
||||
override fun operatingSystem(name: String?) = notImplemented()
|
||||
override fun withArchitecture(architecture: ArchitectureInternal?) = notImplemented()
|
||||
override fun architecture(name: String?) = notImplemented()
|
||||
}
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
package org.jetbrains.kotlin.gradle.plugin.experimental.internal
|
||||
|
||||
import org.gradle.api.Task
|
||||
import org.gradle.api.artifacts.Configuration
|
||||
import org.gradle.api.artifacts.ConfigurationContainer
|
||||
import org.gradle.api.file.FileCollection
|
||||
import org.gradle.api.file.ProjectLayout
|
||||
import org.gradle.api.internal.file.FileOperations
|
||||
import org.gradle.api.model.ObjectFactory
|
||||
import org.gradle.api.provider.Property
|
||||
import org.gradle.api.provider.Provider
|
||||
import org.jetbrains.kotlin.gradle.plugin.experimental.KotlinNativeTestExecutable
|
||||
import org.jetbrains.kotlin.gradle.plugin.experimental.sourcesets.KotlinNativeSourceSet
|
||||
import org.jetbrains.kotlin.konan.target.CompilerOutputKind
|
||||
import javax.inject.Inject
|
||||
|
||||
|
||||
open class KotlinNativeTestExecutableImpl @Inject constructor(
|
||||
name: String,
|
||||
baseName: Provider<String>,
|
||||
componentImplementation: Configuration,
|
||||
testSources: KotlinNativeSourceSet,
|
||||
val mainSources: KotlinNativeSourceSet,
|
||||
identity: KotlinNativeVariantIdentity,
|
||||
objects: ObjectFactory,
|
||||
projectLayout: ProjectLayout,
|
||||
configurations: ConfigurationContainer,
|
||||
fileOperations: FileOperations
|
||||
) : AbstractKotlinNativeBinary(name,
|
||||
baseName,
|
||||
testSources,
|
||||
identity,
|
||||
projectLayout,
|
||||
CompilerOutputKind.PROGRAM,
|
||||
objects,
|
||||
componentImplementation,
|
||||
configurations,
|
||||
fileOperations),
|
||||
KotlinNativeTestExecutable {
|
||||
|
||||
init {
|
||||
additionalCompilerOptions.add("-tr")
|
||||
}
|
||||
|
||||
private val runTaskProperty : Property<Task> = objects.property(Task::class.java)
|
||||
override fun getRunTask() = runTaskProperty
|
||||
|
||||
override val sources: FileCollection
|
||||
get() = super.sources + mainSources.getAllSources(konanTarget)
|
||||
|
||||
override val outputRootName: String = "exe"
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
package org.jetbrains.kotlin.gradle.plugin.experimental.internal
|
||||
|
||||
import org.gradle.api.internal.file.FileOperations
|
||||
import org.gradle.api.model.ObjectFactory
|
||||
import org.gradle.api.provider.Property
|
||||
import org.gradle.internal.Describables
|
||||
import org.gradle.internal.DisplayName
|
||||
import org.gradle.language.cpp.internal.NativeVariantIdentity
|
||||
import org.jetbrains.kotlin.gradle.plugin.experimental.KotlinNativeComponent
|
||||
import org.jetbrains.kotlin.gradle.plugin.experimental.KotlinNativeTestComponent
|
||||
import org.jetbrains.kotlin.gradle.plugin.experimental.KotlinNativeTestExecutable
|
||||
import org.jetbrains.kotlin.gradle.plugin.experimental.sourcesets.KotlinNativeSourceSetImpl
|
||||
import javax.inject.Inject
|
||||
|
||||
open class KotlinNativeTestSuite @Inject constructor(
|
||||
name: String,
|
||||
sources: KotlinNativeSourceSetImpl,
|
||||
override val testedComponent: KotlinNativeComponent,
|
||||
objectFactory: ObjectFactory,
|
||||
fileOperations: FileOperations
|
||||
) : AbstractKotlinNativeComponent(name, sources, objectFactory, fileOperations),
|
||||
KotlinNativeTestComponent {
|
||||
|
||||
init {
|
||||
getImplementationDependencies().extendsFrom(testedComponent.getImplementationDependencies())
|
||||
}
|
||||
|
||||
override fun getDisplayName(): DisplayName = Describables.withTypeAndName("Kotlin/Native test suite", name)
|
||||
|
||||
private val testBinaryProperty: Property<KotlinNativeTestExecutable> =
|
||||
objectFactory.property(KotlinNativeTestExecutable::class.java)
|
||||
|
||||
override fun getTestBinary() = testBinaryProperty
|
||||
|
||||
fun addTestExecutable(identity: NativeVariantIdentity): KotlinNativeTestExecutable =
|
||||
objectFactory.newInstance(
|
||||
KotlinNativeTestExecutableImpl::class.java,
|
||||
"$name${identity.name.capitalize()}",
|
||||
getBaseName(),
|
||||
getImplementationDependencies(),
|
||||
sources,
|
||||
testedComponent.sources,
|
||||
identity
|
||||
).apply {
|
||||
binaries.add(this)
|
||||
}
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
package org.jetbrains.kotlin.gradle.plugin.experimental.internal
|
||||
|
||||
object KotlinNativeUsage {
|
||||
const val KLIB = "kotlin-native-klib"
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
package org.jetbrains.kotlin.gradle.plugin.experimental.internal
|
||||
|
||||
import org.gradle.api.internal.component.UsageContext
|
||||
import org.gradle.api.model.ObjectFactory
|
||||
import org.gradle.api.provider.Provider
|
||||
import org.gradle.language.cpp.internal.NativeVariantIdentity
|
||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||
|
||||
open class KotlinNativeVariantIdentity(
|
||||
name: String,
|
||||
baseName: Provider<String>,
|
||||
group: Provider<String>,
|
||||
version: Provider<String>,
|
||||
val konanTarget: KonanTarget,
|
||||
debuggable: Boolean,
|
||||
optimized: Boolean,
|
||||
linkUsage: UsageContext?,
|
||||
runtimeUsage: UsageContext?,
|
||||
objects: ObjectFactory
|
||||
) : NativeVariantIdentity(
|
||||
name,
|
||||
baseName,
|
||||
group,
|
||||
version,
|
||||
debuggable,
|
||||
optimized,
|
||||
konanTarget.getGradleOSFamily(objects),
|
||||
linkUsage,
|
||||
runtimeUsage
|
||||
) {
|
||||
val targetPlatform = DefaultKotlinNativePlatform(konanTarget)
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
package org.jetbrains.kotlin.gradle.plugin.experimental.internal
|
||||
|
||||
import org.gradle.api.attributes.Usage
|
||||
import org.jetbrains.kotlin.gradle.plugin.experimental.KotlinNativeBinary
|
||||
import org.jetbrains.kotlin.konan.target.CompilerOutputKind
|
||||
|
||||
enum class OutputKind(
|
||||
val compilerOutputKind: CompilerOutputKind,
|
||||
val binaryClass: Class<out KotlinNativeBinary>,
|
||||
private val developmentBinaryPriority: Int,
|
||||
val runtimeUsageName: String? = null,
|
||||
val linkUsageName: String? = null
|
||||
) {
|
||||
EXECUTABLE(CompilerOutputKind.PROGRAM,
|
||||
KotlinNativeExecutableImpl::class.java,
|
||||
1,
|
||||
Usage.NATIVE_RUNTIME,
|
||||
null
|
||||
),
|
||||
KLIBRARY(CompilerOutputKind.LIBRARY,
|
||||
KotlinNativeKLibraryImpl::class.java,
|
||||
0,
|
||||
null,
|
||||
KotlinNativeUsage.KLIB
|
||||
);
|
||||
|
||||
companion object {
|
||||
internal fun Collection<OutputKind>.getDevelopmentKind() = maxBy { it.developmentBinaryPriority }
|
||||
}
|
||||
}
|
||||
+161
@@ -0,0 +1,161 @@
|
||||
package org.jetbrains.kotlin.gradle.plugin.experimental.plugins
|
||||
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.Plugin
|
||||
import org.gradle.api.component.SoftwareComponentContainer
|
||||
import org.gradle.api.file.DirectoryProperty
|
||||
import org.gradle.api.internal.FeaturePreviews
|
||||
import org.gradle.api.internal.project.ProjectInternal
|
||||
import org.gradle.api.plugins.BasePlugin
|
||||
import org.gradle.api.provider.ProviderFactory
|
||||
import org.gradle.api.tasks.TaskContainer
|
||||
import org.gradle.language.base.plugins.LifecycleBasePlugin
|
||||
import org.gradle.language.plugins.NativeBasePlugin
|
||||
import org.gradle.nativeplatform.test.tasks.RunTestExecutable
|
||||
import org.gradle.util.GradleVersion
|
||||
import org.jetbrains.kotlin.gradle.plugin.KonanPlugin
|
||||
import org.jetbrains.kotlin.gradle.plugin.experimental.internal.AbstractKotlinNativeBinary
|
||||
import org.jetbrains.kotlin.gradle.plugin.experimental.internal.KotlinNativeExecutableImpl
|
||||
import org.jetbrains.kotlin.gradle.plugin.experimental.internal.KotlinNativeKLibraryImpl
|
||||
import org.jetbrains.kotlin.gradle.plugin.experimental.internal.KotlinNativeTestExecutableImpl
|
||||
import org.jetbrains.kotlin.gradle.plugin.experimental.tasks.KotlinNativeCompile
|
||||
import org.jetbrains.kotlin.gradle.plugin.hasProperty
|
||||
import org.jetbrains.kotlin.gradle.plugin.konanCompilerDownloadDir
|
||||
import org.jetbrains.kotlin.gradle.plugin.setProperty
|
||||
import org.jetbrains.kotlin.gradle.plugin.tasks.KonanCompilerDownloadTask
|
||||
import org.jetbrains.kotlin.konan.target.HostManager
|
||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||
|
||||
class KotlinNativeBasePlugin: Plugin<ProjectInternal> {
|
||||
|
||||
private fun TaskContainer.createRunTestTask(
|
||||
taskName: String,
|
||||
binary: KotlinNativeTestExecutableImpl,
|
||||
compileTask: KotlinNativeCompile
|
||||
) = create(taskName, RunTestExecutable::class.java).apply {
|
||||
group = LifecycleBasePlugin.VERIFICATION_GROUP
|
||||
description = "Executes Kotlin/Native unit tests."
|
||||
|
||||
val testExecutableProperty = compileTask.outputFile
|
||||
executable = testExecutableProperty.asFile.get().absolutePath
|
||||
|
||||
onlyIf { testExecutableProperty.asFile.get().exists() }
|
||||
inputs.file(testExecutableProperty)
|
||||
dependsOn(testExecutableProperty)
|
||||
|
||||
// TODO: Find or implement some mechanism for test result saving.
|
||||
outputDir = project.layout.buildDirectory.dir("test-results/" + binary.names.dirName).get().asFile
|
||||
}
|
||||
|
||||
private fun TaskContainer.createDummyTestTask(taskName: String, target: KonanTarget) =
|
||||
create(taskName, DefaultTask::class.java).apply {
|
||||
doLast {
|
||||
logger.warn("""
|
||||
|
||||
The current host doesn't support running executables for target '${target.name}'.
|
||||
Skipping tests.
|
||||
|
||||
""".trimIndent())
|
||||
}
|
||||
}
|
||||
|
||||
private val KonanTarget.canRunOnHost: Boolean
|
||||
get() = this == HostManager.host
|
||||
|
||||
private fun addCompilationTasks(
|
||||
tasks: TaskContainer,
|
||||
components: SoftwareComponentContainer,
|
||||
buildDirectory: DirectoryProperty,
|
||||
providers: ProviderFactory
|
||||
) {
|
||||
components.withType(AbstractKotlinNativeBinary::class.java) { binary ->
|
||||
val names = binary.names
|
||||
val target = binary.konanTarget
|
||||
val kind = binary.kind
|
||||
|
||||
val compileTask = tasks.create(
|
||||
names.getCompileTaskName(LANGUAGE_NAME),
|
||||
KotlinNativeCompile::class.java
|
||||
).apply {
|
||||
this.binary = binary
|
||||
outputFile.set(buildDirectory.file(providers.provider {
|
||||
val root = binary.outputRootName
|
||||
val prefix = kind.prefix(target)
|
||||
val suffix = kind.suffix(target)
|
||||
val baseName = binary.getBaseName().get()
|
||||
"$root/${names.dirName}/${prefix}${baseName}${suffix}"
|
||||
}))
|
||||
|
||||
group = BasePlugin.BUILD_GROUP
|
||||
description = "Compiles Kotlin/Native source set '${binary.sourceSet.name}' into a ${binary.kind.name.toLowerCase()}"
|
||||
}
|
||||
binary.compileTask.set(compileTask)
|
||||
binary.outputs.from(compileTask.outputFile)
|
||||
|
||||
when(binary) {
|
||||
is KotlinNativeExecutableImpl -> binary.runtimeFile.set(compileTask.outputFile)
|
||||
is KotlinNativeKLibraryImpl -> binary.linkFile.set(compileTask.outputFile)
|
||||
}
|
||||
|
||||
if (binary is KotlinNativeTestExecutableImpl) {
|
||||
val taskName = binary.names.getTaskName("run")
|
||||
val testTask = if (target.canRunOnHost) {
|
||||
tasks.createRunTestTask(taskName, binary, compileTask)
|
||||
} else {
|
||||
// We create dummy tasks that just write an error message to avoid having an unset
|
||||
// runTask property for targets that cannot be executed on the current host.
|
||||
tasks.createDummyTestTask(taskName, target)
|
||||
}
|
||||
binary.runTask.set(testTask)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun ProjectInternal.checkGradleMetadataFeature() {
|
||||
val metadataEnabled = gradle.services
|
||||
.get(FeaturePreviews::class.java)
|
||||
.isFeatureEnabled(FeaturePreviews.Feature.GRADLE_METADATA)
|
||||
if (!metadataEnabled) {
|
||||
logger.warn(
|
||||
"The GRADLE_METADATA feature is not enabled: publication and external dependencies will not work properly."
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkGradleVersion() = GradleVersion.current().let { current ->
|
||||
check(current >= KonanPlugin.REQUIRED_GRADLE_VERSION) {
|
||||
"Kotlin/Native Gradle plugin is incompatible with this version of Gradle.\n" +
|
||||
"The minimal required version is ${KonanPlugin.REQUIRED_GRADLE_VERSION}\n" +
|
||||
"Current version is ${current}"
|
||||
}
|
||||
}
|
||||
|
||||
private fun ProjectInternal.addCompilerDownloadingTask(): KonanCompilerDownloadTask {
|
||||
val result = tasks.create(KonanPlugin.KONAN_DOWNLOAD_TASK_NAME, KonanCompilerDownloadTask::class.java)
|
||||
if (!hasProperty(KonanPlugin.ProjectProperty.KONAN_HOME)) {
|
||||
setProperty(KonanPlugin.ProjectProperty.KONAN_HOME, project.konanCompilerDownloadDir())
|
||||
setProperty(KonanPlugin.ProjectProperty.DOWNLOAD_COMPILER, true)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
override fun apply(project: ProjectInternal): Unit = with(project) {
|
||||
// TODO: Deal with compiler downloading.
|
||||
// Apply base plugins
|
||||
project.pluginManager.apply(LifecycleBasePlugin::class.java)
|
||||
project.pluginManager.apply(NativeBasePlugin::class.java)
|
||||
|
||||
checkGradleMetadataFeature()
|
||||
checkGradleVersion()
|
||||
addCompilerDownloadingTask()
|
||||
|
||||
// Create compile tasks
|
||||
addCompilationTasks(tasks, components, layout.buildDirectory, providers)
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val LANGUAGE_NAME = "KotlinNative"
|
||||
const val SOURCE_SETS_EXTENSION = "sourceSets"
|
||||
}
|
||||
|
||||
}
|
||||
+212
@@ -0,0 +1,212 @@
|
||||
package org.jetbrains.kotlin.gradle.plugin.experimental.plugins
|
||||
|
||||
import org.gradle.api.Plugin
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.attributes.Usage
|
||||
import org.gradle.api.internal.FactoryNamedDomainObjectContainer
|
||||
import org.gradle.api.internal.attributes.ImmutableAttributesFactory
|
||||
import org.gradle.api.internal.project.ProjectInternal
|
||||
import org.gradle.api.model.ObjectFactory
|
||||
import org.gradle.api.provider.Provider
|
||||
import org.gradle.internal.reflect.Instantiator
|
||||
import org.gradle.language.cpp.CppBinary.DEBUGGABLE_ATTRIBUTE
|
||||
import org.gradle.language.cpp.CppBinary.OPTIMIZED_ATTRIBUTE
|
||||
import org.gradle.language.cpp.internal.DefaultUsageContext
|
||||
import org.gradle.nativeplatform.test.plugins.NativeTestingBasePlugin
|
||||
import org.jetbrains.kotlin.gradle.plugin.experimental.KotlinNativeBinary.Companion.KONAN_TARGET_ATTRIBUTE
|
||||
import org.jetbrains.kotlin.gradle.plugin.experimental.internal.*
|
||||
import org.jetbrains.kotlin.gradle.plugin.experimental.internal.OutputKind.Companion.getDevelopmentKind
|
||||
import org.jetbrains.kotlin.gradle.plugin.experimental.sourcesets.KotlinNativeSourceSetFactory
|
||||
import org.jetbrains.kotlin.gradle.plugin.experimental.sourcesets.KotlinNativeSourceSetImpl
|
||||
import org.jetbrains.kotlin.konan.target.HostManager
|
||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||
import javax.inject.Inject
|
||||
|
||||
class KotlinNativePlugin @Inject constructor(val attributesFactory: ImmutableAttributesFactory)
|
||||
: Plugin<ProjectInternal> {
|
||||
|
||||
val hostManager = HostManager()
|
||||
|
||||
private val Collection<*>.isDimensionVisible: Boolean
|
||||
get() = size > 1
|
||||
|
||||
private fun createDimensionSuffix(dimensionName: String, multivalueProperty: Collection<*>): String =
|
||||
if (multivalueProperty.isDimensionVisible) {
|
||||
dimensionName.toLowerCase().capitalize()
|
||||
} else {
|
||||
""
|
||||
}
|
||||
|
||||
private fun createUsageContext(
|
||||
usageName: String,
|
||||
variantName: String,
|
||||
usageContextSuffix: String,
|
||||
buildType: KotlinNativeBuildType,
|
||||
target: KonanTarget,
|
||||
objectFactory: ObjectFactory
|
||||
): DefaultUsageContext {
|
||||
val usage = objectFactory.named(Usage::class.java, usageName)
|
||||
val attributes = attributesFactory.mutable().apply {
|
||||
attribute(Usage.USAGE_ATTRIBUTE, usage)
|
||||
attribute(DEBUGGABLE_ATTRIBUTE, buildType.debuggable)
|
||||
attribute(OPTIMIZED_ATTRIBUTE, buildType.optimized)
|
||||
attribute(KONAN_TARGET_ATTRIBUTE, target.name)
|
||||
}
|
||||
return DefaultUsageContext(variantName + usageContextSuffix, usage, attributes)
|
||||
}
|
||||
|
||||
private fun AbstractKotlinNativeComponent.getAndLockTargets(): Set<KonanTarget> {
|
||||
konanTargets.lockNow()
|
||||
return konanTargets.get().also {
|
||||
require(it.isNotEmpty()) { "A Kotlin/Native target needs to be specified for the component." }
|
||||
}
|
||||
}
|
||||
|
||||
private fun KotlinNativeMainComponent.getAndLockOutputKinds(): Set<OutputKind> {
|
||||
outputKinds.lockNow()
|
||||
return outputKinds.get().also {
|
||||
require(it.isNotEmpty()) { "An output kind needs to be specified for the component." }
|
||||
}
|
||||
}
|
||||
|
||||
private fun Collection<KonanTarget>.getDevelopmentTarget(): KonanTarget =
|
||||
if (contains(HostManager.host)) HostManager.host else first()
|
||||
|
||||
private fun Project.addBinariesForMainComponents(group: Provider<String>, version: Provider<String>) {
|
||||
for (component in components.withType(KotlinNativeMainComponent::class.java)) {
|
||||
val targets = component.getAndLockTargets()
|
||||
val outputKinds = component.getAndLockOutputKinds()
|
||||
val developmentKind = outputKinds.getDevelopmentKind()
|
||||
val developmentTarget = targets.getDevelopmentTarget()
|
||||
val objectFactory = objects
|
||||
val hostManager = HostManager()
|
||||
|
||||
for (kind in outputKinds) {
|
||||
for (buildType in KotlinNativeBuildType.DEFAULT_BUILD_TYPES) {
|
||||
for (target in targets) {
|
||||
|
||||
val buildTypeSuffix = buildType.name
|
||||
val outputKindSuffix = createDimensionSuffix(kind.name, outputKinds)
|
||||
val targetSuffix = createDimensionSuffix(target.name, targets)
|
||||
val variantName = "${buildTypeSuffix}${outputKindSuffix}${targetSuffix}"
|
||||
|
||||
val linkUsageContext: DefaultUsageContext? = kind.linkUsageName?.let {
|
||||
createUsageContext(it, variantName, "Link", buildType, target, objectFactory)
|
||||
}
|
||||
|
||||
val runtimeUsageContext = kind.runtimeUsageName?.let {
|
||||
createUsageContext(it, variantName, "Runtime", buildType, target, objectFactory)
|
||||
}
|
||||
|
||||
// TODO: Do we need something like klibUsageContext?
|
||||
val variantIdentity = KotlinNativeVariantIdentity(
|
||||
variantName,
|
||||
component.baseName,
|
||||
group, version, target,
|
||||
buildType.debuggable,
|
||||
buildType.optimized,
|
||||
linkUsageContext,
|
||||
runtimeUsageContext,
|
||||
objects
|
||||
)
|
||||
|
||||
val binary = component.addBinary(kind, variantIdentity)
|
||||
|
||||
if (hostManager.isEnabled(target)) {
|
||||
component.mainPublication.variants.add(binary)
|
||||
} else {
|
||||
// Known but not buildable.
|
||||
// It allows us to publish different parts of a multitarget library from differnt hosts.
|
||||
component.mainPublication.variants.add(variantIdentity)
|
||||
}
|
||||
|
||||
if (kind == developmentKind &&
|
||||
buildType == KotlinNativeBuildType.DEBUG &&
|
||||
target == developmentTarget) {
|
||||
component.developmentBinary.set(binary)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
component.binaries.realizeNow()
|
||||
}
|
||||
}
|
||||
|
||||
private fun Project.addBinariesForTestComponents(group: Provider<String>, version: Provider<String>) {
|
||||
for (component in components.withType(KotlinNativeTestSuite::class.java)) {
|
||||
val targets = component.getAndLockTargets()
|
||||
val buildType = KotlinNativeBuildType.DEBUG
|
||||
|
||||
for (target in targets) {
|
||||
val buildTypeSuffix = buildType.name
|
||||
val targetSuffix = createDimensionSuffix(target.name, targets)
|
||||
val variantName = "${buildTypeSuffix}${targetSuffix}"
|
||||
|
||||
val variantIdentity = KotlinNativeVariantIdentity(
|
||||
variantName,
|
||||
component.getBaseName(),
|
||||
group, version, target,
|
||||
buildType.debuggable,
|
||||
buildType.optimized,
|
||||
null,
|
||||
null,
|
||||
objects
|
||||
)
|
||||
|
||||
val binary = component.addTestExecutable(variantIdentity)
|
||||
if (target == HostManager.host) {
|
||||
component.testBinary.set(binary)
|
||||
}
|
||||
}
|
||||
component.binaries.realizeNow()
|
||||
}
|
||||
}
|
||||
|
||||
override fun apply(project: ProjectInternal): Unit = with(project) {
|
||||
pluginManager.apply(KotlinNativeBasePlugin::class.java)
|
||||
pluginManager.apply(NativeTestingBasePlugin::class.java)
|
||||
|
||||
val instantiator = services.get(Instantiator::class.java)
|
||||
val objectFactory = objects
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
val sourceSets = project.extensions.create(
|
||||
KotlinNativeBasePlugin.SOURCE_SETS_EXTENSION,
|
||||
FactoryNamedDomainObjectContainer::class.java,
|
||||
KotlinNativeSourceSetImpl::class.java,
|
||||
instantiator,
|
||||
KotlinNativeSourceSetFactory(this)
|
||||
) as FactoryNamedDomainObjectContainer<KotlinNativeSourceSetImpl>
|
||||
|
||||
// TODO: We should be able to create a component automatically once
|
||||
// a source set is created by user. So we need a user DSL or some another way
|
||||
// to determine which component class should be instantiated (main or test).
|
||||
val mainSourceSet = sourceSets.create("main").apply {
|
||||
kotlin.srcDir("src/main/kotlin")
|
||||
component = objectFactory
|
||||
.newInstance(KotlinNativeMainComponent::class.java, name, this)
|
||||
.apply {
|
||||
// Override the default component base name.
|
||||
baseName.set(project.name)
|
||||
project.components.add(this)
|
||||
}
|
||||
}
|
||||
|
||||
sourceSets.create("test").apply {
|
||||
kotlin.srcDir("src/test/kotlin")
|
||||
component = objectFactory
|
||||
.newInstance(KotlinNativeTestSuite::class.java, name, this, mainSourceSet.component)
|
||||
.apply {
|
||||
project.components.add(this)
|
||||
}
|
||||
}
|
||||
// Create binaries for host
|
||||
afterEvaluate {
|
||||
val group = project.provider { project.group.toString() }
|
||||
val version = project.provider { project.version.toString() }
|
||||
|
||||
addBinariesForMainComponents(group, version)
|
||||
addBinariesForTestComponents(group, version)
|
||||
}
|
||||
}
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
package org.jetbrains.kotlin.gradle.plugin.experimental.plugins
|
||||
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.tasks.SourceSet
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformImplementationPluginBase
|
||||
|
||||
class KotlinPlatformNativePlugin : KotlinPlatformImplementationPluginBase("native") {
|
||||
|
||||
override fun apply(project: Project) = with(project) {
|
||||
pluginManager.apply(KotlinNativePlugin::class.java)
|
||||
// This configuration is necessary for correct work of the base platform plugin.
|
||||
configurations.create("compile")
|
||||
super.apply(project)
|
||||
}
|
||||
|
||||
override fun addCommonSourceSetToPlatformSourceSet(commonSourceSet: SourceSet, platformProject: Project) {
|
||||
val platformSourceSet = platformProject.kotlinNativeSourceSets.findByName(commonSourceSet.name)
|
||||
val commonSources = commonSourceSet.kotlin
|
||||
if (platformSourceSet != null && commonSources != null) {
|
||||
platformSourceSet.commonSources.from(commonSources)
|
||||
} else {
|
||||
platformProject.logger.warn("""
|
||||
Cannot add a common source set '${commonSourceSet.name}' in the project '${platformProject.path}'.
|
||||
No such platform source set or the common source set has no Kotlin sources.
|
||||
""".trimIndent())
|
||||
}
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
package org.jetbrains.kotlin.gradle.plugin.experimental.plugins
|
||||
|
||||
import org.gradle.api.NamedDomainObjectContainer
|
||||
import org.gradle.api.Project
|
||||
import org.jetbrains.kotlin.gradle.plugin.experimental.sourcesets.KotlinNativeSourceSetImpl
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
val Project.kotlinNativeSourceSets: NamedDomainObjectContainer<KotlinNativeSourceSetImpl>
|
||||
get() = extensions.getByName(KotlinNativeBasePlugin.SOURCE_SETS_EXTENSION)
|
||||
as NamedDomainObjectContainer<KotlinNativeSourceSetImpl>
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
package org.jetbrains.kotlin.gradle.plugin.experimental.sourcesets
|
||||
|
||||
import groovy.lang.Closure
|
||||
import org.gradle.api.Action
|
||||
import org.gradle.api.Named
|
||||
import org.gradle.api.file.FileCollection
|
||||
import org.gradle.api.file.SourceDirectorySet
|
||||
import org.jetbrains.kotlin.gradle.plugin.experimental.KotlinNativeComponent
|
||||
import org.jetbrains.kotlin.gradle.plugin.experimental.internal.AbstractKotlinNativeComponent
|
||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||
|
||||
interface KotlinNativeSourceSet: Named {
|
||||
|
||||
val kotlin: SourceDirectorySet
|
||||
val component: KotlinNativeComponent
|
||||
|
||||
/** Returns sources added in the source set via an expectedBy dependency. */
|
||||
fun getCommonMultiplatformSources(): FileCollection
|
||||
|
||||
/** Returns sources common for all native targets. */
|
||||
fun getCommonNativeSources(): SourceDirectorySet
|
||||
|
||||
/** Returns native sources specific for the given target. */
|
||||
fun getPlatformSources(target: KonanTarget): SourceDirectorySet
|
||||
|
||||
/** Returns all (common multiplatform, common native and target-specific) sources for the given target. */
|
||||
fun getAllSources(target: KonanTarget): FileCollection
|
||||
|
||||
fun kotlin(configureClosure: Closure<*>): KotlinNativeSourceSet
|
||||
fun kotlin(configureAction: Action<in SourceDirectorySet>): KotlinNativeSourceSet
|
||||
fun kotlin(configureLambda: SourceDirectorySet.() -> Unit): KotlinNativeSourceSet
|
||||
|
||||
fun component(configureClosure: Closure<*>): KotlinNativeSourceSet
|
||||
fun component(configureAction: Action<in AbstractKotlinNativeComponent>): KotlinNativeSourceSet
|
||||
fun component(configureLambda: AbstractKotlinNativeComponent.() -> Unit): KotlinNativeSourceSet
|
||||
|
||||
fun target(target: String): SourceDirectorySet
|
||||
fun target(vararg targets: String): KotlinNativeSourceSet
|
||||
fun target(vararg targets: String, configureClosure: Closure<*>): KotlinNativeSourceSet
|
||||
fun target(vararg targets: String, configureAction: Action<in SourceDirectorySet>): KotlinNativeSourceSet
|
||||
fun target(vararg targets: String, configureLambda: SourceDirectorySet.() -> Unit): KotlinNativeSourceSet
|
||||
fun target(targets: Iterable<String>): KotlinNativeSourceSet
|
||||
fun target(targets: Iterable<String>, configureClosure: Closure<*>): KotlinNativeSourceSet
|
||||
fun target(targets: Iterable<String>, configureAction: Action<in SourceDirectorySet>): KotlinNativeSourceSet
|
||||
fun target(targets: Iterable<String>, configureLambda: SourceDirectorySet.() -> Unit): KotlinNativeSourceSet
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
package org.jetbrains.kotlin.gradle.plugin.experimental.sourcesets
|
||||
|
||||
import org.gradle.api.NamedDomainObjectFactory
|
||||
import org.gradle.api.internal.file.SourceDirectorySetFactory
|
||||
import org.gradle.api.internal.project.ProjectInternal
|
||||
|
||||
class KotlinNativeSourceSetFactory(val project: ProjectInternal) : NamedDomainObjectFactory<KotlinNativeSourceSet> {
|
||||
|
||||
override fun create(name: String): KotlinNativeSourceSet =
|
||||
project.objects.newInstance(
|
||||
KotlinNativeSourceSetImpl::class.java,
|
||||
name,
|
||||
project.services.get(SourceDirectorySetFactory::class.java),
|
||||
project
|
||||
)
|
||||
}
|
||||
+93
@@ -0,0 +1,93 @@
|
||||
package org.jetbrains.kotlin.gradle.plugin.experimental.sourcesets
|
||||
|
||||
import groovy.lang.Closure
|
||||
import org.gradle.api.Action
|
||||
import org.gradle.api.file.ConfigurableFileCollection
|
||||
import org.gradle.api.file.FileCollection
|
||||
import org.gradle.api.file.SourceDirectorySet
|
||||
import org.gradle.api.internal.file.SourceDirectorySetFactory
|
||||
import org.gradle.api.internal.project.ProjectInternal
|
||||
import org.gradle.util.ConfigureUtil.configure
|
||||
import org.jetbrains.kotlin.gradle.plugin.experimental.internal.AbstractKotlinNativeComponent
|
||||
import org.jetbrains.kotlin.konan.target.HostManager
|
||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||
import javax.inject.Inject
|
||||
|
||||
open class KotlinNativeSourceSetImpl @Inject constructor(
|
||||
private val name: String,
|
||||
val sourceDirectorySetFactory: SourceDirectorySetFactory,
|
||||
val project: ProjectInternal
|
||||
) : KotlinNativeSourceSet {
|
||||
|
||||
override lateinit var component: AbstractKotlinNativeComponent
|
||||
|
||||
override val kotlin: SourceDirectorySet
|
||||
get() = nativeSources
|
||||
|
||||
internal val commonSources: ConfigurableFileCollection = project.files()
|
||||
|
||||
private val nativeSources: SourceDirectorySet = newSourceDirectorySet("kotlin")
|
||||
|
||||
private val platformSources = mutableMapOf<KonanTarget, SourceDirectorySet>()
|
||||
|
||||
private fun newSourceDirectorySet(name: String) = sourceDirectorySetFactory.create(name).apply {
|
||||
filter.include("**/*.kt")
|
||||
}
|
||||
|
||||
override fun getPlatformSources(target: KonanTarget) = platformSources.getOrPut(target) {
|
||||
newSourceDirectorySet(target.name)
|
||||
}
|
||||
|
||||
override fun getCommonMultiplatformSources(): FileCollection = commonSources
|
||||
override fun getCommonNativeSources(): SourceDirectorySet = nativeSources
|
||||
|
||||
override fun getAllSources(target: KonanTarget): FileCollection =
|
||||
commonSources + nativeSources + getPlatformSources(target)
|
||||
|
||||
override fun getName(): String = name
|
||||
|
||||
// region DSL
|
||||
|
||||
// Common source directory set configuration.
|
||||
override fun kotlin(configureClosure: Closure<*>) = apply { configure(configureClosure, nativeSources) }
|
||||
override fun kotlin(configureAction: Action<in SourceDirectorySet>) = apply { configureAction.execute(nativeSources) }
|
||||
override fun kotlin(configureLambda: SourceDirectorySet.() -> Unit) = apply { nativeSources.configureLambda() }
|
||||
|
||||
// Configuration of the corresponding software component.
|
||||
override fun component(configureClosure: Closure<*>) = apply { configure(configureClosure, component) }
|
||||
override fun component(configureAction: Action<in AbstractKotlinNativeComponent>) =
|
||||
apply { configureAction.execute(component) }
|
||||
override fun component(configureLambda: AbstractKotlinNativeComponent.() -> Unit) =
|
||||
apply { component.configureLambda() }
|
||||
|
||||
// Adding new targets and configuration of target-specific source directory sets.
|
||||
override fun target(target: String): SourceDirectorySet {
|
||||
val konanTarget = HostManager().targetByName(target)
|
||||
component.konanTargets.add(konanTarget)
|
||||
return getPlatformSources(konanTarget)
|
||||
}
|
||||
|
||||
override fun target(targets: Iterable<String>) = target(targets) {}
|
||||
|
||||
override fun target(targets: Iterable<String>, configureLambda: SourceDirectorySet.() -> Unit) = apply {
|
||||
targets.forEach { target(it).configureLambda() }
|
||||
}
|
||||
|
||||
override fun target(targets: Iterable<String>, configureClosure: Closure<*>) =
|
||||
target(targets) { configure(configureClosure, this) }
|
||||
|
||||
override fun target(targets: Iterable<String>, configureAction: Action<in SourceDirectorySet>) =
|
||||
target(targets) { configureAction.execute(this) }
|
||||
|
||||
override fun target(vararg targets: String) = target(targets.toList())
|
||||
|
||||
override fun target(vararg targets: String, configureLambda: SourceDirectorySet.() -> Unit) =
|
||||
target(targets.toList(), configureLambda)
|
||||
|
||||
override fun target(vararg targets: String, configureClosure: Closure<*>) =
|
||||
target(targets.toList(), configureClosure)
|
||||
|
||||
override fun target(vararg targets: String, configureAction: Action<in SourceDirectorySet>) =
|
||||
target(targets.toList(), configureAction)
|
||||
// endregion
|
||||
}
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
package org.jetbrains.kotlin.gradle.plugin.experimental.tasks
|
||||
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.artifacts.Configuration
|
||||
import org.gradle.api.file.FileCollection
|
||||
import org.gradle.api.file.RegularFileProperty
|
||||
import org.gradle.api.tasks.Input
|
||||
import org.gradle.api.tasks.InputFiles
|
||||
import org.gradle.api.tasks.OutputFile
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
import org.jetbrains.kotlin.gradle.plugin.KonanCompilerRunner
|
||||
import org.jetbrains.kotlin.gradle.plugin.KonanPlugin
|
||||
import org.jetbrains.kotlin.gradle.plugin.addArg
|
||||
import org.jetbrains.kotlin.gradle.plugin.addKey
|
||||
import org.jetbrains.kotlin.gradle.plugin.experimental.internal.AbstractKotlinNativeBinary
|
||||
import org.jetbrains.kotlin.konan.target.CompilerOutputKind
|
||||
|
||||
open class KotlinNativeCompile: DefaultTask() {
|
||||
|
||||
init {
|
||||
super.dependsOn(KonanPlugin.KONAN_DOWNLOAD_TASK_NAME)
|
||||
}
|
||||
|
||||
// TODO: May be replace with Gradle's property
|
||||
internal lateinit var binary: AbstractKotlinNativeBinary
|
||||
|
||||
// Inputs and outputs
|
||||
|
||||
val sources: FileCollection
|
||||
@InputFiles get() = binary.sources
|
||||
|
||||
val libraries: Configuration
|
||||
@InputFiles get() = binary.klibraries
|
||||
|
||||
val optimized: Boolean @Input get() = binary.optimized
|
||||
val debuggable: Boolean @Input get() = binary.debuggable
|
||||
|
||||
val kind: CompilerOutputKind @Input get() = binary.kind
|
||||
|
||||
val target: String @Input get() = binary.konanTarget.name
|
||||
|
||||
@OutputFile
|
||||
val outputFile: RegularFileProperty = newOutputFile()
|
||||
|
||||
// Task action
|
||||
|
||||
@TaskAction
|
||||
fun compile() {
|
||||
val output = outputFile.asFile.get()
|
||||
output.parentFile.mkdirs()
|
||||
|
||||
val args = mutableListOf<String>().apply {
|
||||
addArg("-o", outputFile.get().asFile.absolutePath)
|
||||
addKey("-opt", optimized)
|
||||
addKey("-g", debuggable)
|
||||
addKey("-ea", debuggable)
|
||||
|
||||
addArg("-target", target)
|
||||
addArg("-p", kind.name.toLowerCase())
|
||||
|
||||
add("-Xmulti-platform")
|
||||
|
||||
addAll(binary.additionalCompilerOptions)
|
||||
|
||||
libraries.files.forEach {library ->
|
||||
library.parent?.let { addArg("-r", it) }
|
||||
addArg("-l", library.nameWithoutExtension)
|
||||
}
|
||||
|
||||
addAll(sources.files.map { it.absolutePath })
|
||||
}
|
||||
|
||||
KonanCompilerRunner(project).run(args)
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -36,7 +36,7 @@ import java.io.File
|
||||
*/
|
||||
abstract class KonanCompileTask: KonanBuildingTask(), KonanCompileSpec {
|
||||
|
||||
@Internal override val toolRunner = KonanCompilerRunner(project)
|
||||
@Internal override val toolRunner = KonanCompilerRunner(project, project.konanExtension.jvmArgs)
|
||||
|
||||
abstract val produce: CompilerOutputKind
|
||||
@Internal get
|
||||
|
||||
+1
-1
@@ -72,7 +72,7 @@ open class KonanCompilerDownloadTask : DefaultTask() {
|
||||
|
||||
// Download dependencies if a user said so.
|
||||
if (downloadDependencies) {
|
||||
val runner = KonanCompilerRunner(project)
|
||||
val runner = KonanCompilerRunner(project, project.konanExtension.jvmArgs)
|
||||
project.konanTargets.forEach {
|
||||
runner.run("--check_dependencies", "-target", it.visibleName)
|
||||
}
|
||||
|
||||
+1
-1
@@ -36,7 +36,7 @@ import java.io.File
|
||||
*/
|
||||
open class KonanInteropTask: KonanBuildingTask(), KonanInteropSpec {
|
||||
|
||||
@Internal override val toolRunner: KonanToolRunner = KonanInteropRunner(project)
|
||||
@Internal override val toolRunner: KonanToolRunner = KonanInteropRunner(project, project.konanExtension.jvmArgs)
|
||||
|
||||
override fun init(config: KonanBuildingConfig<*>, destinationDir: File, artifactName: String, target: KonanTarget) {
|
||||
super.init(config, destinationDir, artifactName, target)
|
||||
|
||||
@@ -0,0 +1,377 @@
|
||||
package org.jetbrains.kotlin.gradle.plugin.test
|
||||
|
||||
import org.gradle.testkit.runner.TaskOutcome
|
||||
import org.jetbrains.kotlin.konan.target.HostManager
|
||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||
import org.junit.Rule
|
||||
import org.junit.rules.TemporaryFolder
|
||||
import java.io.File
|
||||
import java.nio.file.Paths
|
||||
import java.util.concurrent.TimeUnit
|
||||
import kotlin.test.*
|
||||
|
||||
class ExperimentalPluginTests {
|
||||
|
||||
val tmpFolder = TemporaryFolder()
|
||||
@Rule get
|
||||
|
||||
val projectDirectory: File
|
||||
get() = tmpFolder.root
|
||||
|
||||
val exeSuffix = HostManager.host.family.exeSuffix
|
||||
|
||||
@Test
|
||||
fun `Plugin should compile one executable`() {
|
||||
val project = KonanProject.create(projectDirectory).apply {
|
||||
settingsFile.appendText("\nrootProject.name = 'test'")
|
||||
buildFile.writeText("""
|
||||
plugins { id 'kotlin-native' }
|
||||
|
||||
sourceSets.main.component {
|
||||
outputKinds = [ EXECUTABLE, KLIBRARY ]
|
||||
}
|
||||
""".trimIndent())
|
||||
}
|
||||
val assembleResult = project.createRunner().withArguments("assemble").build()
|
||||
|
||||
assertEquals(TaskOutcome.SUCCESS, assembleResult.task(":compileDebugKotlinNative")?.outcome)
|
||||
assertTrue(projectDirectory.resolve("build/exe/main/debug/test.$exeSuffix").exists())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Plugin should build a klibrary and support a project dependency on it`() {
|
||||
val libraryDir = tmpFolder.newFolder("library")
|
||||
val libraryProject = KonanProject.createEmpty(libraryDir).apply {
|
||||
buildFile.writeText("""
|
||||
plugins { id 'kotlin-native' }
|
||||
""".trimIndent())
|
||||
generateSrcFile("library.kt", "fun foo() = 42")
|
||||
}
|
||||
|
||||
val project = KonanProject.createEmpty(projectDirectory).apply {
|
||||
settingsFile.writeText("""
|
||||
include ':library'
|
||||
rootProject.name = 'test'
|
||||
""".trimIndent())
|
||||
buildFile.writeText("""
|
||||
plugins { id 'kotlin-native' }
|
||||
|
||||
dependencies {
|
||||
implementation project(':library')
|
||||
}
|
||||
|
||||
sourceSets.main.component {
|
||||
outputKinds = [ EXECUTABLE ]
|
||||
}
|
||||
""".trimIndent())
|
||||
generateSrcFile("main.kt", "fun main(args: Array<String>) { println(foo()) }")
|
||||
}
|
||||
|
||||
val compileDebugResult = project.createRunner().withArguments("compileDebugKotlinNative").build()
|
||||
assertEquals(TaskOutcome.SUCCESS, compileDebugResult.task(":compileDebugKotlinNative")?.outcome)
|
||||
assertEquals(TaskOutcome.SUCCESS, compileDebugResult.task(":library:compileDebugKotlinNative")?.outcome)
|
||||
assertTrue(projectDirectory.resolve("build/exe/main/debug/test.$exeSuffix").exists())
|
||||
assertTrue(libraryDir.resolve("build/lib/main/debug/library.klib").exists())
|
||||
|
||||
val compileReleaseResult = project.createRunner().withArguments("compileReleaseKotlinNative").build()
|
||||
assertEquals(TaskOutcome.SUCCESS, compileReleaseResult.task(":compileReleaseKotlinNative")?.outcome)
|
||||
assertEquals(TaskOutcome.SUCCESS, compileReleaseResult.task(":library:compileReleaseKotlinNative")?.outcome)
|
||||
assertTrue(projectDirectory.resolve("build/exe/main/release/test.$exeSuffix").exists())
|
||||
assertTrue(libraryDir.resolve("build/lib/main/release/library.klib").exists())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Plugin should be able to publish a component and support a maven dependency on it`() {
|
||||
val libraryDir = tmpFolder.newFolder("library")
|
||||
val libraryProject = KonanProject.createEmpty(libraryDir).apply {
|
||||
buildFile.writeText("""
|
||||
plugins {
|
||||
id 'kotlin-native'
|
||||
id 'maven-publish'
|
||||
}
|
||||
|
||||
group 'test'
|
||||
version '1.0'
|
||||
|
||||
sourceSets.main.component {
|
||||
target 'host', 'wasm32'
|
||||
}
|
||||
|
||||
publishing {
|
||||
repositories {
|
||||
maven {
|
||||
url = '../repo'
|
||||
}
|
||||
}
|
||||
}
|
||||
""".trimIndent())
|
||||
generateSrcFile("library.kt", "fun foo() = 42")
|
||||
}
|
||||
|
||||
val project = KonanProject.createEmpty(projectDirectory).apply {
|
||||
settingsFile.writeText("""
|
||||
enableFeaturePreview('GRADLE_METADATA')
|
||||
include ':library'
|
||||
rootProject.name = 'test'
|
||||
""".trimIndent())
|
||||
buildFile.writeText("""
|
||||
plugins { id 'kotlin-native' }
|
||||
|
||||
repositories {
|
||||
maven {
|
||||
url = 'repo'
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'test:library:1.0'
|
||||
}
|
||||
|
||||
sourceSets.main.component {
|
||||
target 'host', 'wasm32'
|
||||
outputKinds = [ EXECUTABLE ]
|
||||
}
|
||||
""".trimIndent())
|
||||
generateSrcFile("main.kt", "fun main(args: Array<String>) { println(foo()) }")
|
||||
}
|
||||
|
||||
val publishResult = project.createRunner().withArguments("library:publish").build()
|
||||
assertEquals(TaskOutcome.SUCCESS, publishResult.task(":library:compileDebugWasm32KotlinNative")?.outcome)
|
||||
assertEquals(TaskOutcome.SUCCESS,
|
||||
publishResult.task(":library:compileDebug${HostManager.hostName.capitalize()}KotlinNative")?.outcome)
|
||||
|
||||
project.createRunner().withArguments(":assemble").build()
|
||||
project.createRunner().withArguments(":compileDebugWasm32KotlinNative").build()
|
||||
val wasm32ExeSuffix = HostManager().targetByName("wasm32").family.exeSuffix
|
||||
|
||||
assertTrue(projectDirectory.resolve("build/exe/main/debug/${HostManager.hostName}/test.$exeSuffix").exists())
|
||||
assertTrue(projectDirectory.resolve("build/exe/main/debug/wasm32/test.$wasm32ExeSuffix").exists())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Plugin should be able to build a component for different targets with target-specific sources`() {
|
||||
val project = KonanProject.createEmpty(projectDirectory).apply {
|
||||
settingsFile.appendText("\nrootProject.name = 'test'")
|
||||
buildFile.writeText("""
|
||||
plugins { id 'kotlin-native' }
|
||||
|
||||
sourceSets.main {
|
||||
target('macos_x64').srcDir 'src/main/macos_x64'
|
||||
target('linux_x64').srcDir 'src/main/linux_x64'
|
||||
target('mingw_x64').srcDir 'src/main/mingw_x64'
|
||||
component {
|
||||
outputKinds = [ EXECUTABLE ]
|
||||
}
|
||||
}
|
||||
""".trimIndent())
|
||||
generateSrcFile("main.kt", """
|
||||
fun main(args: Array<String>) {
|
||||
print(foo())
|
||||
}
|
||||
|
||||
expect fun foo(): String
|
||||
""".trimIndent())
|
||||
listOf(KonanTarget.MACOS_X64, KonanTarget.LINUX_X64, KonanTarget.MINGW_X64).forEach {
|
||||
val target = it.name
|
||||
generateSrcFile(Paths.get("src/main/$target"),"foo.kt", "actual fun foo() = \"$target\"")
|
||||
}
|
||||
}
|
||||
project.createRunner().withArguments("assemble").build()
|
||||
|
||||
val process = ProcessBuilder(
|
||||
projectDirectory.resolve("build/exe/main/debug/${HostManager.hostName}/test.$exeSuffix").absolutePath
|
||||
).start()
|
||||
process.waitFor(10, TimeUnit.SECONDS)
|
||||
|
||||
assertEquals(HostManager.hostName, process.inputStream.reader().readText())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Plugin should support transitive project klib dependencies`() {
|
||||
val fooDir = tmpFolder.newFolder("foo")
|
||||
val barDir = tmpFolder.newFolder("bar")
|
||||
val foo = KonanProject.createEmpty(fooDir).apply {
|
||||
buildFile.writeText("""
|
||||
plugins { id 'kotlin-native' }
|
||||
|
||||
sourceSets.main.component {
|
||||
target 'host', 'wasm32'
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation project(':bar')
|
||||
}
|
||||
""".trimIndent())
|
||||
generateSrcFile("foo.kt", "fun foo() = bar()")
|
||||
}
|
||||
|
||||
val bar = KonanProject.createEmpty(barDir).apply {
|
||||
buildFile.writeText("""
|
||||
plugins { id 'kotlin-native'}
|
||||
|
||||
sourceSets.main.component {
|
||||
target 'host', 'wasm32'
|
||||
}
|
||||
|
||||
""".trimIndent())
|
||||
generateSrcFile("bar.kt", "fun bar() = \"Bar\"")
|
||||
}
|
||||
|
||||
val project = KonanProject.createEmpty(projectDirectory).apply {
|
||||
settingsFile.writeText("""
|
||||
include ':foo'
|
||||
include ':bar'
|
||||
""".trimIndent())
|
||||
buildFile.writeText("""
|
||||
plugins { id 'kotlin-native' }
|
||||
|
||||
sourceSets.main.component {
|
||||
target 'host', 'wasm32'
|
||||
outputKinds = [ EXECUTABLE ]
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation project('foo')
|
||||
}
|
||||
""".trimIndent())
|
||||
generateSrcFile("main.kt", "fun main(args: Array<String>) { println(foo()) }")
|
||||
}
|
||||
|
||||
project.createRunner().withArguments(
|
||||
":assembleReleaseWasm32",
|
||||
":assembleRelease${HostManager.hostName.capitalize()}"
|
||||
).build()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Project should support transitive maven klib dependencies`() {
|
||||
val fooDir = tmpFolder.newFolder("foo")
|
||||
val barDir = tmpFolder.newFolder("bar")
|
||||
val foo = KonanProject.createEmpty(fooDir).apply {
|
||||
buildFile.writeText("""
|
||||
plugins {
|
||||
id 'kotlin-native'
|
||||
id 'maven-publish'
|
||||
}
|
||||
|
||||
repositories {
|
||||
maven {
|
||||
url = '../repo'
|
||||
}
|
||||
}
|
||||
|
||||
group 'test'
|
||||
version '1.0'
|
||||
|
||||
sourceSets.main.component {
|
||||
target 'host', 'wasm32'
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'test:bar:1.0'
|
||||
}
|
||||
|
||||
publishing {
|
||||
repositories {
|
||||
maven {
|
||||
url = '../repo'
|
||||
}
|
||||
}
|
||||
}
|
||||
""".trimIndent())
|
||||
generateSrcFile("foo.kt", "fun foo() = bar()")
|
||||
}
|
||||
|
||||
val bar = KonanProject.createEmpty(barDir).apply {
|
||||
buildFile.writeText("""
|
||||
plugins {
|
||||
id 'kotlin-native'
|
||||
id 'maven-publish'
|
||||
}
|
||||
|
||||
group 'test'
|
||||
version '1.0'
|
||||
|
||||
sourceSets.main.component {
|
||||
target 'host', 'wasm32'
|
||||
}
|
||||
|
||||
publishing {
|
||||
repositories {
|
||||
maven {
|
||||
url = '../repo'
|
||||
}
|
||||
}
|
||||
}
|
||||
""".trimIndent())
|
||||
generateSrcFile("bar.kt", "fun bar() = \"Bar\"")
|
||||
}
|
||||
|
||||
val project = KonanProject.createEmpty(projectDirectory).apply {
|
||||
settingsFile.writeText("""
|
||||
enableFeaturePreview('GRADLE_METADATA')
|
||||
include ':foo'
|
||||
include ':bar'
|
||||
rootProject.name = 'test'
|
||||
""".trimIndent())
|
||||
buildFile.writeText("""
|
||||
plugins { id 'kotlin-native' }
|
||||
|
||||
repositories {
|
||||
maven {
|
||||
url = 'repo'
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'test:foo:1.0'
|
||||
}
|
||||
|
||||
sourceSets.main.component {
|
||||
target 'host', 'wasm32'
|
||||
outputKinds = [ EXECUTABLE ]
|
||||
}
|
||||
""".trimIndent())
|
||||
generateSrcFile("main.kt", "fun main(args: Array<String>) { println(foo()) }")
|
||||
}
|
||||
|
||||
project.createRunner().withArguments(":bar:publish").build()
|
||||
project.createRunner().withArguments(":foo:publish").build()
|
||||
project.createRunner().withArguments(
|
||||
":assembleReleaseWasm32",
|
||||
":assembleRelease${HostManager.hostName.capitalize()}"
|
||||
).build()
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
fun `Plugin should allow creating components by creating source sets`() {
|
||||
val project = KonanProject.create(projectDirectory).apply {
|
||||
settingsFile.appendText("\nrootProject.name = 'test'")
|
||||
buildFile.writeText("""
|
||||
plugins { id 'kotlin-native' }
|
||||
|
||||
sourceSets {
|
||||
foo {
|
||||
kotlin.srcDir 'src/foo/kotlin'
|
||||
component {
|
||||
outputKinds = [ EXECUTABLE ]
|
||||
}
|
||||
}
|
||||
}
|
||||
""".trimIndent())
|
||||
generateSrcFile(
|
||||
Paths.get("src/foo/kotlin"),
|
||||
"foo.kt",
|
||||
"fun main(args: Array<String>) { println(\"Foo\") }"
|
||||
)
|
||||
}
|
||||
val assembleResult = project.createRunner().withArguments("assembleFooDebug", "assembleFooRelease").build()
|
||||
|
||||
assertEquals(TaskOutcome.SUCCESS, assembleResult.task(":compileFooDebugKotlinNative")?.outcome)
|
||||
assertEquals(TaskOutcome.SUCCESS, assembleResult.task(":compileFooReleaseKotlinNative")?.outcome)
|
||||
assertTrue(projectDirectory.resolve("build/exe/foo/debug/foo.$exeSuffix").exists())
|
||||
assertTrue(projectDirectory.resolve("build/exe/foo/release/foo.$exeSuffix").exists())
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,125 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Release publisher. Downloads the working tree in the working directory (it must be empty),
|
||||
# builds bundle and gradle-plugin, check them and upload to bintray/CDN.
|
||||
|
||||
# Usage: publish-release.sh [--no-upload] <version>
|
||||
# --no-upload - don't upload the built binaries (gradle plugin and bundle)
|
||||
# to bintray/CDN, only test them.
|
||||
|
||||
# The script uses the following environment variables:
|
||||
# BINTRAY_USER and BINTRAY_KEY to upload gradle plugin to bintray;
|
||||
# CDN_USER and CDN_PASS to upload the bundle to CDN.
|
||||
|
||||
function stage {
|
||||
echo
|
||||
echo "==================================="
|
||||
date
|
||||
echo "$1"
|
||||
}
|
||||
|
||||
set -eu
|
||||
|
||||
if [[ $# -lt 1 ]]; then
|
||||
echo "No version is set. Usage: `basename $0` [--no-upload] [--no-build] <version>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
UPLOAD=true
|
||||
BUILD=true
|
||||
# Prepare command line args.
|
||||
while [[ $# -gt 1 ]]; do
|
||||
arg="$1"
|
||||
case $arg in
|
||||
--no-upload)
|
||||
UPLOAD=false
|
||||
;;
|
||||
--no-build)
|
||||
BUILD=false
|
||||
;;
|
||||
*)
|
||||
echo "Unknown option: $arg. Usage: `basename $0` [--no-upload] <version>"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
# The variables used.
|
||||
case "$OSTYPE" in
|
||||
darwin*) OS=macos ;;
|
||||
linux*) OS=linux ;;
|
||||
*) echo "unknown: $OSTYPE" && exit 1;;
|
||||
esac
|
||||
|
||||
VERSION=${1}
|
||||
BRANCH="v${VERSION}-fixes"
|
||||
REPO="https://github.com/JetBrains/kotlin-native.git"
|
||||
TREE_DIR=${PWD}
|
||||
BUNDLE_TAR="$TREE_DIR/kotlin-native-$OS-$VERSION.tar.gz"
|
||||
BUNDLE_DIR="$TREE_DIR/kotlin-native-$OS-$VERSION"
|
||||
WAIT_TIME=120
|
||||
|
||||
if [ "$BUILD" == "true" ]; then
|
||||
# Build and test.
|
||||
# 1. Download kotlin-native sources
|
||||
stage "Cloning repo: $REPO (branch: $BRANCH)"
|
||||
git clone "$REPO" .
|
||||
git checkout "$BRANCH"
|
||||
|
||||
# 2.1 Update dependencies
|
||||
stage "Building bundle: $BUNDLE_TAR"
|
||||
./gradlew dependencies:update
|
||||
|
||||
# 2.2 Build the bundle
|
||||
./gradlew clean bundle
|
||||
tar -xf "$BUNDLE_TAR"
|
||||
fi
|
||||
|
||||
# 3. Check the bundle in commandline mode
|
||||
stage "Checking commandline build"
|
||||
cd "$BUNDLE_DIR/samples"
|
||||
./build.sh
|
||||
|
||||
# 4. Build the gradle plugin
|
||||
stage "Building gradle plugin"
|
||||
cd "$TREE_DIR"
|
||||
./gradlew tools:kotlin-native-gradle-plugin:jar
|
||||
|
||||
# 5. Build samples in the tree with the plugin built
|
||||
stage "Building samples with the plugin built"
|
||||
cd "$TREE_DIR/samples"
|
||||
./gradlew build --refresh-dependencies
|
||||
|
||||
if [ "$UPLOAD" == "true" ]; then
|
||||
# 6. Upload the plugin
|
||||
stage "Uploading the gradle plugin to bintray"
|
||||
cd "$TREE_DIR"
|
||||
export BINTRAY_USER
|
||||
export BINTRAY_KEY
|
||||
./gradlew :tools:kotlin-native-gradle-plugin:bintrayUpload -Poverride
|
||||
|
||||
sleep 10 # Wait some time to ensure that the plugin can be downloaded on the following step.
|
||||
|
||||
# 5. Build the bundle samples with the plugin
|
||||
stage "Building samples with gradle plugin and bundle compiler"
|
||||
cd "$BUNDLE_DIR/samples"
|
||||
./gradlew build --refresh-dependencies
|
||||
|
||||
# 6. Upload the bundle to the CDN
|
||||
stage "Uploading the bundle to CDN: $BUNDLE_TAR -> ftp://uploadcds.labs.intellij.net/builds/releases/$VERSION/$OS"
|
||||
curl --upload-file "$BUNDLE_TAR" "ftp://$CDN_USER:$CDN_PASS@uploadcds.labs.intellij.net/builds/releases/$VERSION/$OS"
|
||||
echo "Available at https://download.jetbrains.com/kotlin/native/builds/releases/$VERSION/$OS/$BUNDLE_TAR"
|
||||
|
||||
echo "Wait ${WAIT_TIME} seconds to ensure that the bundle can be downloaded."
|
||||
sleep ${WAIT_TIME}
|
||||
|
||||
# 7. Remove gradle.properties and build the bundle samples with gradle plugin.
|
||||
stage "Building samples with gradle plugin and downloaded compiler"
|
||||
cd "$BUNDLE_DIR/samples"
|
||||
rm -rf gradle.properties
|
||||
./gradlew build --refresh-dependencies
|
||||
fi
|
||||
|
||||
date
|
||||
echo "Done."
|
||||
Reference in New Issue
Block a user