Gradle: Remove the kotlin-platform-native plugin

The kotlin-platform-native plugin isn't supported since 1.3.50.
But its code still exists in the repo. Some internal APIs are
used in this code that drastically complicates updating Gradle
version used by the K/N build. This patch completely removes the
kotlin-platform-native plugin to get rid of issues with Gradle
updating.
This commit is contained in:
Ilya Matveev
2019-11-26 15:35:01 +07:00
committed by Ilya Matveev
parent ac74fb0a5a
commit 2720c24821
35 changed files with 0 additions and 4473 deletions
@@ -182,14 +182,6 @@ gradlePlugin {
id = 'konan'
implementationClass = 'org.jetbrains.kotlin.gradle.plugin.konan.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'
}
// We bundle a shaded version of kotlinx-serialization plugin
create('kotlinx-serialization-native') {
id = 'kotlinx-serialization-native'
@@ -200,13 +192,5 @@ gradlePlugin {
id = 'org.jetbrains.kotlin.konan'
implementationClass = 'org.jetbrains.kotlin.gradle.plugin.konan.KonanPlugin'
}
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'
}
}
}
@@ -1,75 +0,0 @@
/*
* Copyright 2010-2018 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.gradle.plugin.experimental
import groovy.lang.Closure
import org.gradle.api.Action
import org.gradle.api.Named
import org.gradle.api.file.FileCollection
import org.gradle.language.ComponentDependencies
import org.jetbrains.kotlin.konan.target.KonanTarget
interface CInteropSettings {
interface IncludeDirectories {
fun allHeaders(vararg includeDirs: Any)
fun allHeaders(includeDirs: Collection<Any>)
fun headerFilterOnly(vararg includeDirs: Any)
fun headerFilterOnly(includeDirs: Collection<Any>)
}
fun defFile(file: Any)
fun packageName(value: String)
fun header(file: Any) = headers(file)
fun headers(vararg files: Any)
fun headers(files: FileCollection)
fun includeDirs(vararg values: Any)
fun includeDirs(closure: Closure<Unit>)
fun includeDirs(action: Action<IncludeDirectories>)
fun includeDirs(configure: IncludeDirectories.() -> Unit)
fun compilerOpts(vararg values: String)
fun compilerOpts(values: List<String>)
fun linkerOpts(vararg values: String)
fun linkerOpts(values: List<String>)
fun extraOpts(vararg values: Any)
fun extraOpts(values: List<Any>)
val dependencies: ComponentDependencies
fun dependencies(action: ComponentDependencies.() -> Unit)
fun dependencies(action: Closure<Unit>)
fun dependencies(action: Action<ComponentDependencies>)
}
interface CInterop : Named, CInteropSettings {
fun target(target: String): CInteropSettings
fun target(target: KonanTarget): CInteropSettings
fun target(target: String, action: CInteropSettings.() -> Unit)
fun target(target: String, action: Closure<Unit>)
fun target(target: String, action: Action<CInteropSettings>)
fun target(target: KonanTarget, action: CInteropSettings.() -> Unit)
fun target(target: KonanTarget, action: Closure<Unit>)
fun target(target: KonanTarget, action: Action<CInteropSettings>)
}
@@ -1,24 +0,0 @@
/*
* Copyright 2010-2018 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
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>
}
@@ -1,133 +0,0 @@
/*
* Copyright 2010-2018 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
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.BitcodeEmbeddingMode
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, ComponentWithOutputs {
/** A component this binary belongs to. */
val component: KotlinNativeComponent
/** Returns the source files of this binary. */
val sources: FileCollection
/**
* Returns common sources used to build this binary
* (both common for all native targets and avalable via expectedBy relation).
*/
val commonSources: 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 klibs: FileCollection
/**
* Binary kind in terms of the KN compiler (program, library, dynamic etc).
*/
val kind: CompilerOutputKind
/**
* Additional command line options passed to the compiler when this binary is compiled.
*/
val additionalCompilerOptions: Collection<String>
/**
* Additional options passed to a linker when this binary is built.
*/
val linkerOpts: List<String>
companion object {
val KONAN_TARGET_ATTRIBUTE = Attribute.of("org.jetbrains.kotlin.native.target", String::class.java)
val OLD_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,
PublishableComponent,
ConfigurableComponentWithRuntimeUsage
/**
* A component representing a klibrary.
*/
// TODO: Consider implementing ComponentWithLinkFile.
interface KotlinNativeLibrary : KotlinNativeBinary,
PublishableComponent,
ConfigurableComponentWithLinkUsage
/**
* Represents an Objective C framework compiled from Kotlin/Native sources.
*/
interface KotlinNativeFramework : KotlinNativeBinary {
/** Klibs exported in the framework. */
val export: FileCollection
/** Mode of bitcode embedding: disabled, enabled or marker. */
var embedBitcode: BitcodeEmbeddingMode
}
/**
* A shared library compiled from Kotlin/Native sources.
*/
interface KotlinNativeDynamic : KotlinNativeBinary
/**
* A static library compiled from Kotlin/Native sources.
*/
interface KotlinNativeStatic : KotlinNativeBinary
/**
* Represents a test executable.
*/
// TODO: Consider implementing ComponentWithExecutable and ComponentWithInstallation.
interface KotlinNativeTestExecutable : KotlinNativeBinary, TestComponent
@@ -1,130 +0,0 @@
/*
* Copyright 2010-2018 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.gradle.plugin.experimental
import groovy.lang.Closure
import org.gradle.api.Action
import org.gradle.api.NamedDomainObjectContainer
import org.gradle.api.artifacts.Configuration
import org.gradle.api.artifacts.Dependency
import org.gradle.api.provider.Provider
import org.gradle.api.provider.SetProperty
import org.gradle.api.publish.maven.MavenPom
import org.gradle.language.BinaryCollection
import org.gradle.language.ComponentDependencies
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
interface KotlinNativeDependencies: ComponentDependencies {
val cinterops : NamedDomainObjectContainer<out CInterop>
fun cinterop(name: String): CInterop
fun cinterop(name: String, action: CInterop.() -> Unit)
fun cinterop(name: String, action: Closure<Unit>)
fun cinterop(name: String, action: Action<CInterop>)
fun export(notation: Any)
fun export(notation: Any, configure: Closure<*>)
fun export(notation: Any, configure: Action<in Dependency>)
var transitiveExport: Boolean
}
interface TargetSettings {
/**
* Additional options passed to a linker when a binary is built.
*/
val linkerOpts: MutableList<String>
fun linkerOpts(values: List<String>)
fun linkerOpts(vararg values: String)
}
/**
* 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
/** Allows a user to specify targets this component is built for. */
var targets: List<String>
/** Provides an access to component's dependencies including cinterop and jsinterop DSL */
override fun getDependencies(): KotlinNativeDependencies
fun dependencies(action: KotlinNativeDependencies.() -> Unit)
fun dependencies(action: Closure<Unit>)
fun dependencies(action: Action<KotlinNativeDependencies>)
/** Set native targets for this component. */
@Deprecated("Use the 'targets' property instead. E.g. targets = ['macos_x64', 'linux_x64']")
fun target(vararg targets: String)
/** Allows providing target-specific compiler options. */
fun target(target: String): TargetSettings
fun target(konanTarget: KonanTarget): TargetSettings
fun target(target: String, action: TargetSettings.() -> Unit)
fun target(target: String, action: Closure<Unit>)
fun target(target: String, action: Action<TargetSettings>)
fun allTargets(action: TargetSettings.() -> Unit)
fun allTargets(action: Closure<Unit>)
fun allTargets(action: Action<TargetSettings>)
/** Set additional compiler options for this component. */
val extraOpts: Collection<String>
fun extraOpts(vararg values: Any)
fun extraOpts(values: List<Any>)
fun pom(action: Action<MavenPom>)
val publishJavadoc: Boolean
val publishSources: Boolean
/** Allows setting custom entry point for executables */
var entryPoint: String?
fun entryPoint(value: String)
// endregion
}
/**
* Class representing a test suite for Kotlin/Native
*/
interface KotlinNativeTestComponent : KotlinNativeComponent, TestSuiteComponent {
val testedComponent: KotlinNativeComponent
override fun getTestBinary(): Provider<KotlinNativeTestExecutable>
}
@@ -1,149 +0,0 @@
/*
* Copyright 2010-2018 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
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.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.cpp.internal.NativeVariantIdentity
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.KotlinPlatformType
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.gradle.plugin.mpp.KotlinUsages
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>,
override val component: AbstractKotlinNativeComponent,
val variant: KotlinNativeVariant,
override val kind: CompilerOutputKind,
protected val objects: ObjectFactory,
componentDependencies: KotlinNativeDependenciesImpl,
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
final override val konanTarget: KonanTarget
get() = variant.konanTarget
val identity: NativeVariantIdentity = variant.identity
override fun getTargetPlatform(): KotlinNativePlatform = variant.targetPlatform
val sourceSet: KotlinNativeSourceSet
get() = component.sources
val buildType: KotlinNativeBuildType get() = variant.buildType
open val debuggable: Boolean get() = identity.isDebuggable
open val optimized: Boolean get() = identity.isOptimized
override val sources: FileCollection
get() = sourceSet.getAllSources(konanTarget)
override val commonSources: FileCollection
get() = sourceSet.getCommonMultiplatformSources() + sourceSet.getCommonNativeSources()
private val dependencies = objects.newInstance<DefaultComponentDependencies>(
DefaultComponentDependencies::class.java,
name + "Implementation"
).apply {
implementationDependencies.extendsFrom(componentDependencies.implementationDependencies)
}
override fun getDependencies(): ComponentDependencies = dependencies
fun getImplementationDependencies(): Configuration = dependencies.implementationDependencies
// A configuration containing klibs.
override val klibs = configurations.create(names.withPrefix("klibs")).apply {
isCanBeConsumed = false
attributes.attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage::class.java, KotlinUsages.KOTLIN_API))
attributes.attribute(CppBinary.DEBUGGABLE_ATTRIBUTE, debuggable)
attributes.attribute(CppBinary.OPTIMIZED_ATTRIBUTE, optimized)
attributes.attribute(KotlinPlatformType.attribute, KotlinPlatformType.native)
attributes.attribute(KotlinNativeBinary.KONAN_TARGET_ATTRIBUTE, konanTarget.name)
attributes.attribute(KotlinNativeBinary.OLD_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.configurableFiles()
fun getRuntimeLibraries(): FileCollection = fileOperations.configurableFiles()
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.configurableFiles()
override fun getOutputs() = outputs
override val additionalCompilerOptions: Collection<String>
get() = component.extraOpts
override val linkerOpts: List<String>
get() = component.target(konanTarget).linkerOpts
}
@@ -1,163 +0,0 @@
/*
* Copyright 2010-2018 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.gradle.plugin.experimental.internal
import groovy.lang.Closure
import org.gradle.api.Action
import org.gradle.api.Named
import org.gradle.api.Project
import org.gradle.api.artifacts.Configuration
import org.gradle.api.internal.file.FileOperations
import org.gradle.api.model.ObjectFactory
import org.gradle.api.provider.Property
import org.gradle.api.provider.SetProperty
import org.gradle.api.publish.maven.MavenPom
import org.gradle.language.internal.DefaultBinaryCollection
import org.gradle.language.nativeplatform.internal.ComponentWithNames
import org.gradle.language.nativeplatform.internal.DefaultNativeComponent
import org.gradle.language.nativeplatform.internal.Names
import org.gradle.util.ConfigureUtil
import org.jetbrains.kotlin.gradle.plugin.experimental.KotlinNativeBinary
import org.jetbrains.kotlin.gradle.plugin.experimental.KotlinNativeComponent
import org.jetbrains.kotlin.gradle.plugin.experimental.KotlinNativeDependencies
import org.jetbrains.kotlin.gradle.plugin.experimental.TargetSettings
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 TargetSettingsImpl(val konanTarget: KonanTarget) : Named, TargetSettings {
override fun getName(): String = konanTarget.name
override val linkerOpts = mutableListOf<String>()
override fun linkerOpts(values: List<String>) = linkerOpts(*values.toTypedArray())
override fun linkerOpts(vararg values: String) {
linkerOpts.addAll(values)
}
}
abstract class AbstractKotlinNativeComponent @Inject constructor(
private val name: String,
override val sources: KotlinNativeSourceSetImpl,
val project: Project,
val objectFactory: ObjectFactory,
fileOperations: FileOperations
) : DefaultNativeComponent(objectFactory),
KotlinNativeComponent,
ComponentWithNames {
private val baseName: Property<String> = objectFactory.property(String::class.java).apply { set(name) }
fun getBaseName(): Property<String> = baseName
override val konanTargets: SetProperty<KonanTarget> =
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: KotlinNativeDependenciesImpl = objectFactory.newInstance(
KotlinNativeDependenciesImpl::class.java,
project,
names.withSuffix("implementation"),
names.withSuffix("export")
)
internal val poms = mutableListOf<Action<MavenPom>>()
override fun getDependencies() = dependencies
override fun getImplementationDependencies(): Configuration = dependencies.implementationDependencies
val targetSettings =
project.container(TargetSettingsImpl::class.java) { name ->
TargetSettingsImpl(HostManager().targetByName(name))
}
// region DSL.
override var targets: List<String>
get() = konanTargets.get().map { it.name }
set(value) {
val hostManager = HostManager()
konanTargets.set(value.map { hostManager.targetByName(it) })
}
private val String.canonicalTargetName: String
get() = HostManager().targetByName(this).name
override fun target(konanTarget: KonanTarget): TargetSettings = targetSettings.maybeCreate(konanTarget.name)
override fun target(target: String): TargetSettings = targetSettings.maybeCreate(target.canonicalTargetName)
override fun target(target: String, action: TargetSettings.() -> Unit) =
targetSettings.maybeCreate(target.canonicalTargetName).action()
override fun target(target: String, action: Closure<Unit>) =
target(target, ConfigureUtil.configureUsing(action))
override fun target(target: String, action: Action<TargetSettings>) =
target(target) { action.execute(this) }
override fun allTargets(action: TargetSettings.() -> Unit) = targetSettings.all(action)
override fun allTargets(action: Closure<Unit>) = targetSettings.all(action)
override fun allTargets(action: Action<TargetSettings>) = targetSettings.all(action)
@Deprecated("Use the 'targets' property instead. E.g. targets = ['macos_x64', 'linux_x64']")
override fun target(vararg targets: String) {
project.logger.warn("""
Kotlin/Native component's method 'target' is deprecated. Use the 'targets' property instead.
E.g. targets = ['macos_x64', 'linux_x64']
""".trimIndent())
this.targets = targets.toList()
}
override val extraOpts = mutableListOf<String>()
override fun extraOpts(vararg values: Any) = extraOpts(values.toList())
override fun extraOpts(values: List<Any>) {
extraOpts.addAll(values.map { it.toString() })
}
override fun pom(action: Action<MavenPom>) {
poms.add(action)
}
override var publishJavadoc: Boolean = true
override var publishSources: Boolean = true
override fun dependencies(action: KotlinNativeDependencies.() -> Unit) {
dependencies.action()
}
override fun dependencies(action: Closure<Unit>) =
dependencies(ConfigureUtil.configureUsing(action))
override fun dependencies(action: Action<KotlinNativeDependencies>) {
action.execute(dependencies)
}
override var entryPoint: String? = null
override fun entryPoint(value: String) { entryPoint = value }
// endregion
}
@@ -1,45 +0,0 @@
/*
* Copyright 2010-2018 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
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,
internal val iosEmbedBitcode: BitcodeEmbeddingMode
) : Named {
override fun getName() = name
companion object {
val DEBUG = KotlinNativeBuildType("debug", true, false, BitcodeEmbeddingMode.MARKER)
val RELEASE = KotlinNativeBuildType("release", false, true, BitcodeEmbeddingMode.BITCODE)
val DEFAULT_BUILD_TYPES: Collection<KotlinNativeBuildType> = Arrays.asList(DEBUG, RELEASE)
}
}
enum class BitcodeEmbeddingMode {
/** Don't embed LLVM IR bitcode. */
DISABLE,
/** Embed LLVM IR bitcode as data. */
BITCODE,
/** Embed placeholder LLVM IR data as a marker. */
MARKER,
}
@@ -1,85 +0,0 @@
/*
* Copyright 2010-2018 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.gradle.plugin.experimental.internal
import groovy.lang.Closure
import org.gradle.api.Action
import org.gradle.api.Project
import org.gradle.api.artifacts.ConfigurationContainer
import org.gradle.api.artifacts.Dependency
import org.gradle.language.internal.DefaultComponentDependencies
import org.gradle.util.ConfigureUtil
import org.jetbrains.kotlin.gradle.plugin.experimental.CInterop
import org.jetbrains.kotlin.gradle.plugin.experimental.KotlinNativeDependencies
import org.jetbrains.kotlin.gradle.plugin.experimental.internal.cinterop.CInteropImpl
import javax.inject.Inject
open class KotlinNativeDependenciesImpl @Inject constructor(
private val project: Project,
configurations: ConfigurationContainer,
implementationName: String,
exportName: String
) : DefaultComponentDependencies(configurations, implementationName),
KotlinNativeDependencies {
internal val exportDependencies = configurations.create(exportName).apply {
isCanBeConsumed = false
isCanBeResolved = false
isTransitive = false
implementationDependencies.extendsFrom(this)
}
override var transitiveExport: Boolean = false
override fun export(notation: Any) {
exportDependencies.dependencies.add(dependencyHandler.create(notation))
}
override fun export(notation: Any, configure: Closure<*>) {
val dependency = dependencyHandler.create(notation)
ConfigureUtil.configure(configure, dependency)
exportDependencies.dependencies.add(dependency)
}
override fun export(notation: Any, configure: Action<in Dependency>) {
val dependency = dependencyHandler.create(notation)
configure.execute(dependency)
exportDependencies.dependencies.add(dependency)
}
override val cinterops = project.container(CInteropImpl::class.java) { name ->
CInteropImpl(project, name).apply {
dependencies.implementationDependencies.extendsFrom(
this@KotlinNativeDependenciesImpl.implementationDependencies
)
}
}
override fun cinterop(name: String) = cinterops.maybeCreate(name)
override fun cinterop(name: String, action: CInterop.() -> Unit) {
cinterop(name).apply { action() }
}
override fun cinterop(name: String, action: Closure<Unit>) {
cinterop(name, ConfigureUtil.configureUsing(action))
}
override fun cinterop(name: String, action: Action<CInterop>) {
cinterop(name).apply { action.execute(this) }
}
}
@@ -1,48 +0,0 @@
/*
* Copyright 2010-2018 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.gradle.plugin.experimental.internal
import org.gradle.api.artifacts.ConfigurationContainer
import org.gradle.api.internal.file.FileOperations
import org.gradle.api.model.ObjectFactory
import org.gradle.api.provider.Provider
import org.jetbrains.kotlin.gradle.plugin.experimental.KotlinNativeDynamic
import org.jetbrains.kotlin.konan.target.CompilerOutputKind
import javax.inject.Inject
open class KotlinNativeDynamicImpl @Inject constructor(
name: String,
baseName: Provider<String>,
componentDependencies: KotlinNativeDependenciesImpl,
component: KotlinNativeMainComponent,
variant: KotlinNativeVariant,
objects: ObjectFactory,
configurations: ConfigurationContainer,
fileOperations: FileOperations
) : AbstractKotlinNativeBinary(
name,
baseName,
component,
variant,
CompilerOutputKind.DYNAMIC,
objects,
componentDependencies,
configurations,
fileOperations
), KotlinNativeDynamic {
override val outputRootName: String = "lib"
}
@@ -1,85 +0,0 @@
/*
* Copyright 2010-2018 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
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.gradle.nativeplatform.TargetMachine
import org.jetbrains.kotlin.gradle.plugin.experimental.KotlinNativeExecutable
import org.jetbrains.kotlin.konan.target.CompilerOutputKind
import javax.inject.Inject
open class KotlinNativeExecutableImpl @Inject constructor(
name: String,
baseName: Provider<String>,
componentDependencies: KotlinNativeDependenciesImpl,
component: KotlinNativeMainComponent,
variant: KotlinNativeVariant,
objects: ObjectFactory,
projectLayout: ProjectLayout,
configurations: ConfigurationContainer,
fileOperations: FileOperations
) : AbstractKotlinNativeBinary(name,
baseName,
component,
variant,
CompilerOutputKind.PROGRAM,
objects,
componentDependencies,
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"
override fun getTargetMachine(): TargetMachine = konanTarget.toTargetMachine(objects)
}
@@ -1,78 +0,0 @@
/*
* Copyright 2010-2018 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.gradle.plugin.experimental.internal
import org.gradle.api.artifacts.ConfigurationContainer
import org.gradle.api.attributes.Usage
import org.gradle.api.internal.file.FileOperations
import org.gradle.api.model.ObjectFactory
import org.gradle.api.provider.Provider
import org.gradle.language.cpp.CppBinary
import org.gradle.nativeplatform.OperatingSystemFamily
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
import org.jetbrains.kotlin.gradle.plugin.experimental.KotlinNativeBinary
import org.jetbrains.kotlin.gradle.plugin.experimental.KotlinNativeFramework
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsages
import org.jetbrains.kotlin.konan.target.CompilerOutputKind
import org.jetbrains.kotlin.konan.target.KonanTarget
import javax.inject.Inject
open class KotlinNativeFrameworkImpl @Inject constructor(
name: String,
baseName: Provider<String>,
componentDependencies: KotlinNativeDependenciesImpl,
component: KotlinNativeMainComponent,
variant: KotlinNativeVariant,
objects: ObjectFactory,
configurations: ConfigurationContainer,
fileOperations: FileOperations
) : AbstractKotlinNativeBinary(
name,
baseName,
component,
variant,
CompilerOutputKind.FRAMEWORK,
objects,
componentDependencies,
configurations,
fileOperations
), KotlinNativeFramework {
override val outputRootName: String = "lib"
// A configuration containing exported klibs.
override val export = configurations.create(names.withPrefix("export")).apply {
isCanBeConsumed = false
isTransitive = component.dependencies.transitiveExport
attributes.attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage::class.java, KotlinUsages.KOTLIN_API))
attributes.attribute(CppBinary.DEBUGGABLE_ATTRIBUTE, debuggable)
attributes.attribute(CppBinary.OPTIMIZED_ATTRIBUTE, optimized)
attributes.attribute(KotlinPlatformType.attribute, KotlinPlatformType.native)
attributes.attribute(KotlinNativeBinary.KONAN_TARGET_ATTRIBUTE, konanTarget.name)
attributes.attribute(KotlinNativeBinary.OLD_KONAN_TARGET_ATTRIBUTE, konanTarget.name)
attributes.attribute(OperatingSystemFamily.OPERATING_SYSTEM_ATTRIBUTE, konanTarget.getGradleOSFamily(objects))
extendsFrom(componentDependencies.exportDependencies)
getImplementationDependencies().extendsFrom(this)
}
override var embedBitcode: BitcodeEmbeddingMode =
if (konanTarget == KonanTarget.IOS_ARM64 || konanTarget == KonanTarget.IOS_ARM32) {
buildType.iosEmbedBitcode
} else {
BitcodeEmbeddingMode.DISABLE
}
}
@@ -1,87 +0,0 @@
/*
* Copyright 2010-2018 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
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.gradle.nativeplatform.TargetMachine
import org.jetbrains.kotlin.gradle.plugin.experimental.KotlinNativeLibrary
import org.jetbrains.kotlin.konan.target.CompilerOutputKind
import javax.inject.Inject
open class KotlinNativeLibraryImpl @Inject constructor(
name: String,
baseName: Provider<String>,
componentDependencies: KotlinNativeDependenciesImpl,
component: KotlinNativeMainComponent,
variant: KotlinNativeVariant,
projectLayout: ProjectLayout,
objects: ObjectFactory,
configurations: ConfigurationContainer,
fileOperations: FileOperations
) : AbstractKotlinNativeBinary(name,
baseName,
component,
variant,
CompilerOutputKind.LIBRARY,
objects,
componentDependencies,
configurations,
fileOperations),
KotlinNativeLibrary,
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"
override fun getTargetMachine(): TargetMachine = konanTarget.toTargetMachine(objects)
}
@@ -1,109 +0,0 @@
/*
* Copyright 2010-2018 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.gradle.plugin.experimental.internal
import org.gradle.api.Project
import org.gradle.api.attributes.Usage
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.model.ObjectFactory
import org.gradle.api.provider.Property
import org.gradle.api.provider.SetProperty
import org.gradle.internal.Describables
import org.gradle.internal.DisplayName
import org.gradle.language.ProductionComponent
import org.gradle.language.nativeplatform.internal.PublicationAwareComponent
import org.gradle.util.WrapUtil
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
import org.jetbrains.kotlin.gradle.plugin.experimental.KotlinNativeBinary
import org.jetbrains.kotlin.gradle.plugin.experimental.sourcesets.KotlinNativeSourceSetImpl
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsages
import javax.inject.Inject
open class KotlinNativeMainComponent @Inject constructor(
name: String,
sources: KotlinNativeSourceSetImpl,
project: Project,
objectFactory: ObjectFactory,
fileOperations: FileOperations
) : AbstractKotlinNativeComponent(name, sources, project, objectFactory, fileOperations),
PublicationAwareComponent,
ProductionComponent {
override fun getDisplayName(): DisplayName = Describables.withTypeAndName("Kotlin/Native component", name)
val outputKinds: SetProperty<OutputKind> = objectFactory.setProperty(OutputKind::class.java).apply {
set(mutableSetOf(OutputKind.KLIBRARY))
}
private val metadataDependencies = project.configurations.create(names.withPrefix("metadata")).apply {
isCanBeConsumed = false
attributes.attribute(Usage.USAGE_ATTRIBUTE, project.objects.named(Usage::class.java, KotlinUsages.KOTLIN_API))
attributes.attribute(KotlinPlatformType.attribute, KotlinPlatformType.common)
extendsFrom(getImplementationDependencies())
}
private val mainPublication = KotlinNativePublicationVariants()
override fun getMainPublication(): KotlinNativePublicationVariants = mainPublication
private val developmentBinaryProperty: Property<KotlinNativeBinary> =
objectFactory.property(KotlinNativeBinary::class.java)
override fun getDevelopmentBinary() = developmentBinaryProperty
private fun <T : KotlinNativeBinary> addBinary(type: Class<T>, variant: KotlinNativeVariant): T {
val name = "$name${variant.identity.name.capitalize()}"
return objectFactory.newInstance(type, name, baseName, dependencies, this, variant).apply {
binaries.add(this)
}
}
private inline fun <reified T : KotlinNativeBinary> addBinary(variant: KotlinNativeVariant): T =
addBinary(T::class.java, variant)
fun addExecutable(variant: KotlinNativeVariant) = addBinary<KotlinNativeExecutableImpl>(variant)
fun addLibrary(variant: KotlinNativeVariant) = addBinary<KotlinNativeLibraryImpl>(variant)
fun addFramework(variant: KotlinNativeVariant) = addBinary<KotlinNativeFrameworkImpl>(variant)
fun addBinary(kind: OutputKind, variant: KotlinNativeVariant) = addBinary(kind.binaryClass, variant)
// region Kotlin/Native component passed to Gradle to determine publication variants
// TODO: SoftwareComponentInternal will be replaced with ComponentWithVariants by Gradle
inner class KotlinNativePublicationVariants: ComponentWithVariants, SoftwareComponentInternal {
private val variants = WrapUtil.toDomainObjectSet(SoftwareComponent::class.java)
override fun getVariants(): MutableSet<SoftwareComponent> = variants
override fun getName(): String = this@KotlinNativeMainComponent.name
override fun getUsages(): Set<UsageContext> =
setOf(MetadataUsageContext("metadata-api", project.objects, metadataDependencies))
}
// endregion
companion object {
@JvmStatic val EXECUTABLE = OutputKind.EXECUTABLE
@JvmStatic val KLIBRARY = OutputKind.KLIBRARY
@JvmStatic val FRAMEWORK = OutputKind.FRAMEWORK
@JvmStatic val DYNAMIC = OutputKind.DYNAMIC
@JvmStatic val STATIC = OutputKind.STATIC
}
}
@@ -1,49 +0,0 @@
/*
* Copyright 2010-2018 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.gradle.plugin.experimental.internal
import org.gradle.api.artifacts.ConfigurationContainer
import org.gradle.api.internal.file.FileOperations
import org.gradle.api.model.ObjectFactory
import org.gradle.api.provider.Provider
import org.jetbrains.kotlin.gradle.plugin.experimental.KotlinNativeStatic
import org.jetbrains.kotlin.konan.target.CompilerOutputKind
import javax.inject.Inject
open class KotlinNativeStaticImpl @Inject constructor(
name: String,
baseName: Provider<String>,
componentDependencies: KotlinNativeDependenciesImpl,
component: KotlinNativeMainComponent,
variant: KotlinNativeVariant,
objects: ObjectFactory,
configurations: ConfigurationContainer,
fileOperations: FileOperations
) : AbstractKotlinNativeBinary(
name,
baseName,
component,
variant,
CompilerOutputKind.STATIC,
objects,
componentDependencies,
configurations,
fileOperations
), KotlinNativeStatic {
override val outputRootName: String = "lib"
}
@@ -1,71 +0,0 @@
/*
* Copyright 2010-2018 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.gradle.plugin.experimental.internal
import org.gradle.api.Task
import org.gradle.api.artifacts.ConfigurationContainer
import org.gradle.api.file.FileCollection
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>,
componentDependencies: KotlinNativeDependenciesImpl,
val testComponent: KotlinNativeTestSuite,
val mainSources: KotlinNativeSourceSet,
variant: KotlinNativeVariant,
objects: ObjectFactory,
configurations: ConfigurationContainer,
fileOperations: FileOperations
) : AbstractKotlinNativeBinary(name,
baseName,
testComponent,
variant,
CompilerOutputKind.PROGRAM,
objects,
componentDependencies,
configurations,
fileOperations),
KotlinNativeTestExecutable {
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 commonSources: FileCollection
get() = super.commonSources +
mainSources.getCommonNativeSources() +
mainSources.getCommonMultiplatformSources()
override val outputRootName: String = "test-exe"
override val additionalCompilerOptions: Collection<String>
get() = listOf("-tr") + super.additionalCompilerOptions
override val linkerOpts: List<String>
get() = super.linkerOpts + testComponent.testedComponent.target(konanTarget).linkerOpts
}
@@ -1,66 +0,0 @@
/*
* Copyright 2010-2018 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.gradle.plugin.experimental.internal
import org.gradle.api.Project
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,
project: Project,
objectFactory: ObjectFactory,
fileOperations: FileOperations
) : AbstractKotlinNativeComponent(name, sources, project, objectFactory, fileOperations),
KotlinNativeTestComponent {
init {
getImplementationDependencies().extendsFrom(testedComponent.getImplementationDependencies())
konanTargets.set(project.provider { testedComponent.konanTargets.get() })
}
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(variant: KotlinNativeVariant): KotlinNativeTestExecutable =
objectFactory.newInstance(
KotlinNativeTestExecutableImpl::class.java,
"$name${variant.identity.name.capitalize()}",
getBaseName(),
dependencies,
this,
testedComponent.sources,
variant
).apply {
binaries.add(this)
}
}
@@ -1,22 +0,0 @@
/*
* Copyright 2010-2018 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.gradle.plugin.experimental.internal
object KotlinNativeUsage {
const val KLIB = "kotlin-native-klib"
const val FRAMEWORK = "kotlin-native-framework"
}
@@ -1,51 +0,0 @@
/*
* Copyright 2010-2018 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.gradle.plugin.experimental.internal
import org.gradle.api.Project
import org.gradle.api.internal.component.UsageContext
import org.gradle.api.provider.Provider
import org.gradle.language.cpp.internal.NativeVariantIdentity
import org.jetbrains.kotlin.konan.target.KonanTarget
class KotlinNativeVariant(
name: String,
baseName: Provider<String>,
group: Provider<String>,
version: Provider<String>,
val konanTarget: KonanTarget,
val buildType: KotlinNativeBuildType,
linkUsage: UsageContext?,
runtimeUsage: UsageContext?,
project: Project
) {
val identity: NativeVariantIdentity = compatibleVariantIdentity(
project,
name,
baseName,
group,
version,
buildType.debuggable,
buildType.optimized,
konanTarget,
linkUsage,
runtimeUsage
)
val targetPlatform = DefaultKotlinNativePlatform(konanTarget)
}
@@ -1,70 +0,0 @@
/*
* Copyright 2010-2018 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.gradle.plugin.experimental.internal
import org.gradle.api.attributes.*
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsages
open class Compatible: AttributeCompatibilityRule<Boolean> {
override fun execute(details: CompatibilityCheckDetails<Boolean>) = details.compatible()
}
open class PreferValue(val defaultPreferred: Boolean): AttributeDisambiguationRule<Boolean> {
override fun execute(details: MultipleCandidatesDetails<Boolean>) = with(details) {
val preferredValue = consumerValue ?: defaultPreferred
if (candidateValues.contains(preferredValue)) {
closestMatch(preferredValue)
} else {
closestMatch(!preferredValue)
}
}
}
open class DebuggableDisambiguation: PreferValue(false)
open class OptimizedDisambiguation: PreferValue(false)
open class UsageCompatibility: AttributeCompatibilityRule<Usage> {
override fun execute(details: CompatibilityCheckDetails<Usage>) = with(details) {
val requested = consumerValue?.name
val provided = producerValue?.name
when {
requested == null -> compatible()
requested in supportedRequestedUsages && provided in supportedProvidedUsages -> compatible()
}
}
companion object {
val supportedRequestedUsages = listOf(KotlinUsages.KOTLIN_API, Usage.JAVA_API)
val supportedProvidedUsages = listOf(KotlinUsages.KOTLIN_API, Usage.JAVA_API, KotlinNativeUsage.KLIB)
}
}
open class UsageDisambiguation: AttributeDisambiguationRule<Usage> {
override fun execute(details: MultipleCandidatesDetails<Usage>): Unit = with(details) {
val usagePriority = listOf(KotlinUsages.KOTLIN_API, Usage.JAVA_API, KotlinNativeUsage.KLIB)
usagePriority.forEach { usage ->
val found = candidateValues.find { it.name == usage }
if (found != null) {
closestMatch(found)
return
}
}
}
}
@@ -1,35 +0,0 @@
package org.jetbrains.kotlin.gradle.plugin.experimental.internal
import org.gradle.api.Named
import org.gradle.api.artifacts.*
import org.gradle.api.attributes.AttributeContainer
import org.gradle.api.attributes.Usage
import org.gradle.api.capabilities.Capability
import org.gradle.api.internal.component.UsageContext
import org.gradle.api.model.ObjectFactory
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsages
class MetadataUsageContext(
private val _name: String,
val objects: ObjectFactory,
val configuration: Configuration
): UsageContext, Named {
override fun getUsage(): Usage = objects.named(Usage::class.java, KotlinUsages.KOTLIN_API)
override fun getName(): String = _name
override fun getCapabilities(): Set<Capability> = emptySet()
override fun getGlobalExcludes(): Set<ExcludeRule> = emptySet()
override fun getDependencies(): Set<out ModuleDependency> =
configuration.incoming.dependencies.withType(ModuleDependency::class.java)
override fun getDependencyConstraints(): MutableSet<out DependencyConstraint> =
configuration.incoming.dependencyConstraints
override fun getArtifacts(): MutableSet<out PublishArtifact> =
configuration.outgoing.artifacts
override fun getAttributes(): AttributeContainer =
configuration.outgoing.attributes
}
@@ -1,85 +0,0 @@
/*
* Copyright 2010-2018 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
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.gradle.plugin.mpp.KotlinUsages
import org.jetbrains.kotlin.konan.target.CompilerOutputKind
import org.jetbrains.kotlin.konan.target.Family
import org.jetbrains.kotlin.konan.target.KonanTarget
enum class OutputKind(
val compilerOutputKind: CompilerOutputKind,
val binaryClass: Class<out KotlinNativeBinary>,
private val developmentBinaryPriority: Int,
val runtimeUsageName: String? = null,
val linkUsageName: String? = null,
val publishable: Boolean = true
) {
EXECUTABLE(
CompilerOutputKind.PROGRAM,
KotlinNativeExecutableImpl::class.java,
0,
Usage.NATIVE_RUNTIME,
null
),
KLIBRARY(
CompilerOutputKind.LIBRARY,
KotlinNativeLibraryImpl::class.java,
1,
null,
KotlinUsages.KOTLIN_API
),
FRAMEWORK(
CompilerOutputKind.FRAMEWORK,
KotlinNativeFrameworkImpl::class.java,
2,
null,
KotlinNativeUsage.FRAMEWORK,
false
) {
override fun availableFor(target: KonanTarget) =
target.family.isAppleFamily
},
DYNAMIC(
CompilerOutputKind.DYNAMIC,
KotlinNativeDynamicImpl::class.java,
3,
Usage.NATIVE_RUNTIME,
Usage.NATIVE_LINK,
false
) {
override fun availableFor(target: KonanTarget): Boolean = target != KonanTarget.WASM32
},
STATIC(
CompilerOutputKind.STATIC,
KotlinNativeStaticImpl::class.java,
4,
Usage.NATIVE_RUNTIME,
Usage.NATIVE_LINK,
false
) {
override fun availableFor(target: KonanTarget): Boolean = target != KonanTarget.WASM32
};
open fun availableFor(target: KonanTarget) = true
companion object {
internal fun Collection<OutputKind>.getDevelopmentKind() = minBy { it.developmentBinaryPriority }
}
}
@@ -1,113 +0,0 @@
/*
* Copyright 2010-2018 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.gradle.plugin.experimental.internal.cinterop
import groovy.lang.Closure
import org.gradle.api.Action
import org.gradle.api.DomainObjectCollection
import org.gradle.api.Project
import org.gradle.api.file.FileCollection
import org.gradle.language.ComponentDependencies
import org.gradle.language.internal.DefaultComponentDependencies
import org.gradle.util.ConfigureUtil
import org.jetbrains.kotlin.gradle.plugin.experimental.CInterop
import org.jetbrains.kotlin.gradle.plugin.experimental.CInteropSettings
import org.jetbrains.kotlin.gradle.plugin.experimental.CInteropSettings.IncludeDirectories
import org.jetbrains.kotlin.konan.target.HostManager
import org.jetbrains.kotlin.konan.target.KonanTarget
import javax.inject.Inject
open class CInteropImpl @Inject constructor(
private val project: Project,
private val name: String
): CInterop {
private val String.konanTarget: KonanTarget
get() = HostManager().targetByName(this)
override fun getName(): String = name
private val platformSettings: DomainObjectCollection<CInteropSettingsImpl> =
project.container(CInteropSettingsImpl::class.java)
private val targetToSettings: MutableMap<KonanTarget, CInteropSettingsImpl> = mutableMapOf()
// DSL.
override val dependencies =
DefaultComponentDependencies(project.configurations, name + "InteropImplementation")
override fun target(target: String): CInteropSettings = target(target.konanTarget)
override fun target(target: KonanTarget): CInteropSettings =
targetToSettings.getOrPut(target) {
CInteropSettingsImpl(project, name, target).also {
platformSettings.add(it)
it.dependencies.implementationDependencies.extendsFrom(
this.dependencies.implementationDependencies
)
}
}
override fun target(target: String, action: CInteropSettings.() -> Unit) = target(target.konanTarget, action)
override fun target(target: String, action: Closure<Unit>) = target(target.konanTarget, action)
override fun target(target: String, action: Action<CInteropSettings>) = target(target.konanTarget, action)
override fun target(target: KonanTarget, action: CInteropSettings.() -> Unit) =
target(target).action()
override fun target(target: KonanTarget, action: Closure<Unit>) =
target(target, ConfigureUtil.configureUsing(action))
override fun target(target: KonanTarget, action: Action<CInteropSettings>) {
action.execute(target(target))
}
override fun defFile(file: Any) = platformSettings.all { it.defFile(file) }
override fun packageName(value: String) = platformSettings.all { it.packageName(value) }
override fun headers(vararg files: Any) = platformSettings.all { it.headers(*files) }
override fun headers(files: FileCollection) = platformSettings.all { it.headers(files) }
override fun includeDirs(vararg values: Any) =
platformSettings.all {it.includeDirs(*values) }
override fun includeDirs(closure: Closure<Unit>) =
platformSettings.all { it.includeDirs(closure) }
override fun includeDirs(action: Action<IncludeDirectories>) =
platformSettings.all { it.includeDirs(action) }
override fun includeDirs(configure: IncludeDirectories.() -> Unit) =
platformSettings.all { it.includeDirs(configure) }
override fun compilerOpts(vararg values: String) = platformSettings.all { it.compilerOpts(*values) }
override fun compilerOpts(values: List<String>) = platformSettings.all { it.compilerOpts(values) }
override fun linkerOpts(vararg values: String) = platformSettings.all { it.linkerOpts(*values) }
override fun linkerOpts(values: List<String>) = platformSettings.all { it.linkerOpts(values) }
override fun extraOpts(vararg values: Any) = platformSettings.all { it.extraOpts(*values) }
override fun extraOpts(values: List<Any>) = platformSettings.all { it.extraOpts(values) }
override fun dependencies(action: ComponentDependencies.() -> Unit) {
dependencies.action()
}
override fun dependencies(action: Closure<Unit>) =
dependencies(ConfigureUtil.configureUsing(action))
override fun dependencies(action: Action<ComponentDependencies>) {
action.execute(dependencies)
}
}
@@ -1,140 +0,0 @@
/*
* Copyright 2010-2018 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.gradle.plugin.experimental.internal.cinterop
import groovy.lang.Closure
import org.gradle.api.Action
import org.gradle.api.Named
import org.gradle.api.Project
import org.gradle.api.attributes.Usage
import org.gradle.api.file.FileCollection
import org.gradle.language.ComponentDependencies
import org.gradle.language.cpp.CppBinary
import org.gradle.language.internal.DefaultComponentDependencies
import org.gradle.nativeplatform.OperatingSystemFamily
import org.gradle.util.ConfigureUtil
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
import org.jetbrains.kotlin.gradle.plugin.experimental.CInteropSettings
import org.jetbrains.kotlin.gradle.plugin.experimental.CInteropSettings.IncludeDirectories
import org.jetbrains.kotlin.gradle.plugin.experimental.KotlinNativeBinary
import org.jetbrains.kotlin.gradle.plugin.experimental.internal.KotlinNativeBuildType
import org.jetbrains.kotlin.gradle.plugin.experimental.internal.getGradleOSFamily
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsages
import org.jetbrains.kotlin.konan.target.KonanTarget
import java.io.File
import javax.inject.Inject
open class CInteropSettingsImpl @Inject constructor(
private val project: Project,
val baseName: String,
val konanTarget: KonanTarget
) : CInteropSettings,
Named
{
inner class IncludeDirectoriesSpecImpl: IncludeDirectories {
var allHeadersDirs: FileCollection = project.files()
var headerFilterDirs: FileCollection = project.files()
override fun allHeaders(vararg includeDirs: Any) = allHeaders(includeDirs.toList())
override fun allHeaders(includeDirs: Collection<Any>) {
allHeadersDirs += project.files(*includeDirs.toTypedArray())
}
override fun headerFilterOnly(vararg includeDirs: Any) = headerFilterOnly(includeDirs.toList())
override fun headerFilterOnly(includeDirs: Collection<Any>) {
headerFilterDirs += project.files(*includeDirs.toTypedArray())
}
}
override fun getName(): String = "$baseName${konanTarget.name.capitalize()}"
var defFile: File = project.projectDir.resolve("src/main/c_interop/$baseName.def")
var packageName: String? = null
val compilerOpts = mutableListOf<String>()
val linkerOpts = mutableListOf<String>()
val extraOpts = mutableListOf<String>()
val includeDirs = IncludeDirectoriesSpecImpl()
var headers: FileCollection = project.files()
// DSL methods.
override val dependencies = DefaultComponentDependencies(
project.configurations,
name + "InteropImplementation"
).apply {
with(implementationDependencies) {
val objects = project.objects
isCanBeConsumed = false
isCanBeResolved = true
attributes.attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage::class.java, KotlinUsages.KOTLIN_API))
attributes.attribute(CppBinary.DEBUGGABLE_ATTRIBUTE, KotlinNativeBuildType.DEBUG.debuggable)
attributes.attribute(CppBinary.OPTIMIZED_ATTRIBUTE, KotlinNativeBuildType.DEBUG.optimized)
attributes.attribute(KotlinPlatformType.attribute, KotlinPlatformType.native)
attributes.attribute(KotlinNativeBinary.KONAN_TARGET_ATTRIBUTE, konanTarget.name)
attributes.attribute(KotlinNativeBinary.OLD_KONAN_TARGET_ATTRIBUTE, konanTarget.name)
attributes.attribute(
OperatingSystemFamily.OPERATING_SYSTEM_ATTRIBUTE,
konanTarget.getGradleOSFamily(objects)
)
}
}
override fun defFile(file: Any) {
defFile = project.file(file)
}
override fun packageName(value: String) {
packageName = value
}
override fun header(file: Any) = headers(file)
override fun headers(vararg files: Any) = headers(project.files(files))
override fun headers(files: FileCollection) {
headers += files
}
override fun includeDirs(vararg values: Any) = includeDirs.allHeaders(values.toList())
override fun includeDirs(closure: Closure<Unit>) = includeDirs(ConfigureUtil.configureUsing(closure))
override fun includeDirs(action: Action<IncludeDirectories>) = includeDirs { action.execute(this) }
override fun includeDirs(configure: IncludeDirectories.() -> Unit) = includeDirs.configure()
override fun compilerOpts(vararg values: String) = compilerOpts(values.toList())
override fun compilerOpts(values: List<String>) {
compilerOpts.addAll(values)
}
override fun linkerOpts(vararg values: String) = linkerOpts(values.toList())
override fun linkerOpts(values: List<String>) {
linkerOpts.addAll(values)
}
override fun extraOpts(vararg values: Any) = extraOpts(values.toList())
override fun extraOpts(values: List<Any>) {
extraOpts.addAll(values.map { it.toString() })
}
override fun dependencies(action: ComponentDependencies.() -> Unit) {
dependencies.action()
}
override fun dependencies(action: Closure<Unit>) =
dependencies(ConfigureUtil.configureUsing(action))
override fun dependencies(action: Action<ComponentDependencies>) {
action.execute(dependencies)
}
}
@@ -1,344 +0,0 @@
/*
* Copyright 2010-2018 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.gradle.plugin.experimental.plugins
import org.gradle.api.DefaultTask
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.attributes.Usage
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.internal.FeaturePreviews
import org.gradle.api.internal.project.ProjectInternal
import org.gradle.api.logging.Logging
import org.gradle.api.plugins.BasePlugin
import org.gradle.api.plugins.HelpTasksPlugin
import org.gradle.api.tasks.TaskContainer
import org.gradle.language.base.plugins.LifecycleBasePlugin
import org.gradle.language.cpp.CppBinary
import org.gradle.language.plugins.NativeBasePlugin
import org.gradle.nativeplatform.test.tasks.RunTestExecutable
import org.gradle.util.GradleVersion
import org.jetbrains.kotlin.gradle.plugin.NATIVE_COMPILER_PLUGIN_CLASSPATH_CONFIGURATION_NAME
import org.jetbrains.kotlin.gradle.plugin.PLUGIN_CLASSPATH_CONFIGURATION_NAME
import org.jetbrains.kotlin.gradle.plugin.SubpluginEnvironment
import org.jetbrains.kotlin.gradle.plugin.experimental.CInteropSettings
import org.jetbrains.kotlin.gradle.plugin.experimental.KotlinNativeComponent
import org.jetbrains.kotlin.gradle.plugin.experimental.KotlinNativeLibrary
import org.jetbrains.kotlin.gradle.plugin.experimental.KotlinNativeTestComponent
import org.jetbrains.kotlin.gradle.plugin.experimental.internal.*
import org.jetbrains.kotlin.gradle.plugin.experimental.tasks.CInteropTask
import org.jetbrains.kotlin.gradle.plugin.experimental.tasks.KotlinNativeCompile
import org.jetbrains.kotlin.gradle.plugin.konan.*
import org.jetbrains.kotlin.gradle.plugin.loadKotlinVersionFromResource
import org.jetbrains.kotlin.gradle.plugin.tasks.KonanCompilerDownloadTask
import org.jetbrains.kotlin.konan.target.CompilerOutputKind
import org.jetbrains.kotlin.konan.target.HostManager
import org.jetbrains.kotlin.konan.target.KonanTarget
class KotlinNativeBasePlugin: Plugin<ProjectInternal> {
private val log = Logging.getLogger(this.javaClass)
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 testExecutable = compileTask.outputFile
executable = testExecutable.absolutePath
onlyIf { testExecutable.exists() }
inputs.file(testExecutable)
dependsOn(compileTask)
// 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 lowerCamelCase(vararg components: String) =
if (components.isEmpty()) {
""
} else {
buildString {
append(components[0].decapitalize())
for (i in 1 until components.size) {
append(components[i].capitalize())
}
}
}
private fun Project.addTargetInfoTask() = tasks.create("targets").apply {
group = HelpTasksPlugin.HELP_GROUP
description = "Prints Kotlin/Native targets available for this project"
doLast { _ ->
components.withType(AbstractKotlinNativeComponent::class.java) { component ->
logger.lifecycle("Component '${component.name}' targets:")
component.konanTargets.get().forEach {
logger.lifecycle(it.name)
}
logger.lifecycle("")
}
}
}
// TODO: Rework this part: the task should be created in the binary constructor (if it is possible).
private fun Project.addCompilationTasks() {
val kotlinVersion = this@KotlinNativeBasePlugin.loadKotlinVersionFromResource(log)
val assembleTask = tasks.getByName(LifecycleBasePlugin.ASSEMBLE_TASK_NAME)
val typeToAssemble = mutableMapOf<KotlinNativeBuildType, Task>()
val targetToAssemble = mutableMapOf<KonanTarget, Task>()
fun TaskContainer.createSpecialAssembleTask(name: String, description: String) = create(name) {
it.group = BasePlugin.BUILD_GROUP
it.description = description
assembleTask.dependsOn(it)
}
project.configurations.apply {
maybeCreate(NATIVE_COMPILER_PLUGIN_CLASSPATH_CONFIGURATION_NAME).apply {
isTransitive = false
}
maybeCreate(PLUGIN_CLASSPATH_CONFIGURATION_NAME).apply {
isTransitive = false
}
}
components.withType(AbstractKotlinNativeBinary::class.java) { binary ->
val names = binary.names
val target = binary.konanTarget
val buildType = binary.buildType
val compileTask = tasks.create(
names.getCompileTaskName(LANGUAGE_NAME),
KotlinNativeCompile::class.java,
binary
).also {
it.group = BasePlugin.BUILD_GROUP
it.description = "Compiles Kotlin/Native source set '${binary.sourceSet.name}' into a ${binary.kind.name.toLowerCase()}"
SubpluginEnvironment.loadSubplugins(this, kotlinVersion)
.addSubpluginOptions(this, it, it.compilerPluginOptions)
it.compilerPluginClasspath = project.configurations.getByName(NATIVE_COMPILER_PLUGIN_CLASSPATH_CONFIGURATION_NAME)
// Register an API header produced for shared/static library as a task output.
if (binary.kind == CompilerOutputKind.DYNAMIC || binary.kind == CompilerOutputKind.STATIC) {
val headerFileProvider = provider {
with(binary) {
val prefix = kind.prefix(konanTarget)
val baseName = getBaseName().get().replace('-', '_')
it.outputFile.parentFile.resolve("$prefix${baseName}_api.h")
}
}
it.outputs.file(headerFileProvider)
}
}
binary.compileTask.set(compileTask)
binary.outputs.from(compileTask.outputLocationProvider)
when(binary) {
is KotlinNativeExecutableImpl -> binary.runtimeFile.set(compileTask.outputLocationProvider as RegularFileProperty)
is KotlinNativeLibraryImpl -> binary.linkFile.set(compileTask.outputLocationProvider as RegularFileProperty)
}
if (binary is KotlinNativeTestExecutableImpl) {
// Generate a task for test execution.
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)
} else {
// Add dependency for assemble tasks.
targetToAssemble.getOrPut(target) {
tasks.createSpecialAssembleTask(
"assembleAll${target.name.capitalize()}",
"Compiles all Kotlin/Native binaries for target '${target.name}'"
)
}.dependsOn(compileTask)
typeToAssemble.getOrPut(buildType) {
val buildTypeName = buildType.name
tasks.createSpecialAssembleTask(
"assembleAll${buildTypeName.capitalize()}",
"Compiles all ${buildTypeName} Kotlin/Native binaries for all targets"
)
}.dependsOn(compileTask)
}
}
}
private fun Project.addInteropTasks() {
val settingsToTask = mutableMapOf<CInteropSettings, CInteropTask>()
val namesWithWarning = mutableSetOf<String>()
fun AbstractKotlinNativeBinary.setupInteropFromComponent(component: KotlinNativeComponent) {
component.dependencies.cinterops.all { cinterop ->
val settings = cinterop.target(konanTarget)
val interopTask = settingsToTask.getOrPut(settings) {
tasks.create(
lowerCamelCase("cinterop", cinterop.name, konanTarget.name),
CInteropTask::class.java,
settings
).apply {
group = INTEROP_GROUP
description =
"Generates Kotlin/Native interop library '${cinterop.name}' for target '${konanTarget.name}'"
}
}
klibs.dependencies.add(project.dependencies.create(files(interopTask.outputFileProvider)))
if (this is KotlinNativeLibrary) {
linkElements.get().outgoing.artifact(interopTask.outputFileProvider) {
it.classifier = "interop-${cinterop.name}"
}
// User can create an interop with the same name as the main library.
// In this case we get two libraries with the same name and one of them depends
// on the another. Such a situation is considered as a cyclic dependency by the compiler
// so we warn a user about it.
val mainLibraryName = linkFile.get().asFile.nameWithoutExtension
val interopLibraryName = interopTask.outputFile.nameWithoutExtension
if (mainLibraryName == interopLibraryName && mainLibraryName !in namesWithWarning) {
logger.warn(
"""
Warning: you have an interop with the same name as the main library ($mainLibraryName)!
It may cause failures in dependent projects so consider renaming the interop.
""".trimIndent()
)
namesWithWarning.add(mainLibraryName)
}
}
}
}
components.withType(AbstractKotlinNativeBinary::class.java) { binary ->
binary.component.let {
binary.setupInteropFromComponent(it)
if (it is KotlinNativeTestComponent) {
binary.setupInteropFromComponent(it.testedComponent)
}
}
}
}
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)
project.warnAboutDeprecatedProperty(KonanPlugin.ProjectProperty.KONAN_HOME)
if (!hasProperty(KonanPlugin.ProjectProperty.KONAN_HOME)) {
setProperty(KonanPlugin.ProjectProperty.KONAN_HOME, project.konanCompilerDownloadDir())
setProperty(KonanPlugin.ProjectProperty.DOWNLOAD_COMPILER, true)
}
return result
}
private fun Project.setUpMatchingStrategy(): Unit = with(dependencies.attributesSchema) {
attribute(CppBinary.DEBUGGABLE_ATTRIBUTE).apply {
compatibilityRules.add(Compatible::class.java)
disambiguationRules.add(DebuggableDisambiguation::class.java)
}
attribute(CppBinary.OPTIMIZED_ATTRIBUTE).apply {
compatibilityRules.add(Compatible::class.java)
disambiguationRules.add(OptimizedDisambiguation::class.java)
}
attribute(Usage.USAGE_ATTRIBUTE).apply {
compatibilityRules.add(UsageCompatibility::class.java)
disambiguationRules.add(UsageDisambiguation::class.java)
}
}
override fun apply(project: ProjectInternal): Unit = with(project) {
logger.warn("""
|The 'kotlin-platform-native' plugin applied in the project '${project.path}' has been deprecated and will not be available since 1.3.50.
|Consider using the 'kotlin-multiplatform' plugin.
|
|See details at: https://kotlinlang.org/docs/reference/native/gradle_plugin.html
""".trimMargin())
// TODO: Deal with compiler downloading.
// Apply base plugins
project.pluginManager.apply(LifecycleBasePlugin::class.java)
checkGradleMetadataFeature()
checkGradleVersion()
addCompilerDownloadingTask()
setUpMatchingStrategy()
addCompilationTasks()
// The NativeBasePlugin accesses some properties which are set by the methods above
// (e.g. linkFile for libraries). Thus we have to apply it after setting there properties.
project.pluginManager.apply(NativeBasePlugin::class.java)
addInteropTasks()
addTargetInfoTask()
}
companion object {
const val LANGUAGE_NAME = "KotlinNative"
const val SOURCE_SETS_EXTENSION = "sourceSets"
const val INTEROP_GROUP = "interop"
}
}
@@ -1,312 +0,0 @@
/*
* Copyright 2010-2018 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
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.api.publish.PublishingExtension
import org.gradle.api.publish.maven.MavenPublication
import org.gradle.internal.reflect.Instantiator
import org.gradle.jvm.tasks.Jar
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.KotlinPlatformType
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.gradle.utils.isGradleVersionAtLeast
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(KotlinPlatformType.attribute, KotlinPlatformType.native)
attribute(KONAN_TARGET_ATTRIBUTE, target.name)
}
return DefaultUsageContext(variantName + usageContextSuffix, attributes)
}
private fun AbstractKotlinNativeComponent.getAndLockTargets(): Set<KonanTarget> {
if (isGradleVersionAtLeast(5, 0)) {
konanTargets.finalizeValue()
}
return konanTargets.get().also {
require(it.isNotEmpty()) { "A Kotlin/Native target needs to be specified for the component." }
}
}
private fun KotlinNativeMainComponent.getAndLockOutputKinds(): Set<OutputKind> {
if (isGradleVersionAtLeast(5, 0)) {
konanTargets.finalizeValue()
}
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) {
val buildTypes = if (kind == OutputKind.KLIBRARY)
listOf(KotlinNativeBuildType.DEBUG)
else
KotlinNativeBuildType.DEFAULT_BUILD_TYPES
for (buildType in buildTypes) {
for (target in targets.filter { kind.availableFor(it) }) {
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 variant = KotlinNativeVariant(
variantName,
component.baseName,
group, version, target,
buildType,
linkUsageContext,
runtimeUsageContext,
project
)
if (hostManager.isEnabled(target)) {
val binary = component.addBinary(kind, variant)
if (kind == developmentKind &&
buildType == KotlinNativeBuildType.DEBUG &&
target == developmentTarget) {
component.developmentBinary.set(binary)
}
if (kind.publishable) {
component.mainPublication.variants.add(binary)
}
} else {
if (kind.publishable) {
// Known but not buildable.
// It allows us to publish different parts of a multitarget library from differnt hosts.
component.mainPublication.variants.add(variant.identity)
}
}
}
}
}
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 variant = KotlinNativeVariant(
variantName,
component.getBaseName(),
group, version, target,
buildType,
null,
null,
project
)
if (hostManager.isEnabled(target)) {
val binary = component.addTestExecutable(variant)
if (target == HostManager.host) {
component.testBinary.set(binary)
}
}
}
component.binaries.realizeNow()
}
}
private fun KotlinNativeSourceSetImpl.createJarTask(taskName: String, configure: (Jar) -> Unit): Jar {
val task = project.tasks.findByName(taskName)
return if (task != null) {
task as Jar
} else {
project.tasks.create(taskName, Jar::class.java, configure)
}
}
private fun KotlinNativeSourceSetImpl.createSourcesJarTask(target: KonanTarget): Jar =
createJarTask("sourcesJar${name.capitalize()}${target.name.capitalize()}") {
it.destinationDir = project.buildDir.resolve("libs")
it.appendix = "$name-${target.name}"
it.classifier = "sources"
it.from(getAllSources(target))
}
private fun KotlinNativeSourceSetImpl.createEmptyJarTask(namePrefix: String, classifier: String): Jar =
createJarTask("$namePrefix${name.capitalize()}") {
it.destinationDir = project.buildDir.resolve("libs")
it.appendix = name
it.classifier = classifier
}
private fun Project.setUpMavenPublish() = pluginManager.withPlugin("maven-publish") { _ ->
val publishingExtension = project.extensions.getByType(PublishingExtension::class.java)
loop@for (publication in publishingExtension.publications) {
if (publication !is MavenPublication) continue
val publicationComponent = components.find { it.name == publication.name } ?: continue
val sourcesJar: Jar
val mainComponent: AbstractKotlinNativeComponent
when (publicationComponent) {
is KotlinNativeMainComponent -> {
mainComponent = publicationComponent
sourcesJar = mainComponent.sources.createEmptyJarTask("sourcesJar", "sources")
}
is AbstractKotlinNativeBinary -> {
mainComponent = publicationComponent.component
sourcesJar = mainComponent.sources.createSourcesJarTask(publicationComponent.konanTarget)
}
else -> {
logger.info("Unknown component type: $publicationComponent, ${publicationComponent::class.java}")
continue@loop
}
}
val javadocJar = mainComponent.sources.createEmptyJarTask("javadocJar", "javadoc")
with(mainComponent) {
poms.forEach { publication.pom(it) }
if (publishSources) { publication.artifact(sourcesJar) }
if (publishJavadoc) { publication.artifact(javadocJar) }
}
}
}
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_SOURCE_SET_NAME).apply {
kotlin.srcDir("src/$MAIN_SOURCE_SET_NAME/kotlin")
component = objectFactory
.newInstance(KotlinNativeMainComponent::class.java, name, this, project)
.apply {
// Override the default component base name.
baseName.set(project.name)
project.components.add(this)
}
}
sourceSets.create(TEST_SOURCE_SET_NAME).apply {
kotlin.srcDir("src/$TEST_SOURCE_SET_NAME/kotlin")
component = objectFactory
.newInstance(KotlinNativeTestSuite::class.java, name, this, mainSourceSet.component, project)
.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)
setUpMavenPublish()
}
}
companion object {
const val MAIN_SOURCE_SET_NAME = "main"
const val TEST_SOURCE_SET_NAME = "test"
}
}
@@ -1,46 +0,0 @@
/*
* Copyright 2010-2018 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.gradle.plugin.experimental.plugins
import org.gradle.api.Named
import org.gradle.api.Project
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: Named, platformProject: Project) {
val platformSourceSet = platformProject.kotlinNativeSourceSets.findByName(commonSourceSet.name)
val commonSources = getKotlinSourceDirectorySetSafe(commonSourceSet)
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())
}
}
override fun namedSourceSetsContainer(project: Project) = project.kotlinNativeSourceSets
}
@@ -1,26 +0,0 @@
/*
* Copyright 2010-2018 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
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>
@@ -1,69 +0,0 @@
/*
* Copyright 2010-2018 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
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.KotlinNativeDependencies
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
val dependencies: KotlinNativeDependencies
fun dependencies(action: KotlinNativeDependencies.() -> Unit)
fun dependencies(action: Closure<Unit>)
fun dependencies(action: Action<KotlinNativeDependencies>)
}
@@ -1,32 +0,0 @@
/*
* Copyright 2010-2018 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
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
)
}
@@ -1,118 +0,0 @@
/*
* Copyright 2010-2018 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
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.KotlinNativeDependencies
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)
override val dependencies: KotlinNativeDependencies
get() = component.dependencies
override fun dependencies(action: KotlinNativeDependencies.() -> Unit) = component.dependencies(action)
override fun dependencies(action: Closure<Unit>) = component.dependencies(action)
override fun dependencies(action: Action<KotlinNativeDependencies>) = component.dependencies(action)
// endregion
}
@@ -1,124 +0,0 @@
/*
* Copyright 2010-2018 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
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.tasks.*
import org.jetbrains.kotlin.gradle.plugin.experimental.internal.cinterop.CInteropSettingsImpl
import org.jetbrains.kotlin.gradle.plugin.konan.*
import org.jetbrains.kotlin.konan.target.CompilerOutputKind
import org.jetbrains.kotlin.konan.target.KonanTarget
import java.io.File
import javax.inject.Inject
open class CInteropTask @Inject constructor(val settings: CInteropSettingsImpl): DefaultTask() {
val konanTarget: KonanTarget
@Internal get() = settings.konanTarget
val outputFileName: String
@Internal get() = with(CompilerOutputKind.LIBRARY) {
val prefix = prefix(konanTarget)
val suffix = suffix(konanTarget)
return "$prefix$baseName$suffix"
}
val outputFile: File
get() = outputFileProvider.get().asFile
// Inputs and outputs.
@OutputFile
val outputFileProvider = newOutputFile().apply {
set { project.buildDir.resolve("cinterop/$baseName/$targetName/$outputFileName") }
}
val baseName: String
@Input get() = settings.baseName
val targetName: String
@Input get() = konanTarget.name
val defFile: File
@InputFile get() = settings.defFile
val packageName: String?
@Optional @Input get() = settings.packageName
val compilerOpts: List<String>
@Input get() = settings.compilerOpts
val linkerOpts: List<String>
@Input get() = settings.linkerOpts
val headers: FileCollection
@InputFiles get() = settings.headers
val allHeadersDirs: Set<File>
@Input get() = settings.includeDirs.allHeadersDirs.files
val headerFilterDirs: Set<File>
@Input get() = settings.includeDirs.headerFilterDirs.files
val libraries: Configuration
@InputFiles get() = settings.dependencies.implementationDependencies
val extraOpts: List<String>
@Input get() = settings.extraOpts
val konanVersion: String
@Input get() = project.konanVersion.toString(true, true)
// Task action.
@TaskAction
fun processInterop() {
val args = mutableListOf<String>().apply {
addArg("-o", outputFile.absolutePath)
addArgIfNotNull("-target", konanTarget.visibleName)
addArgIfNotNull("-def", defFile.canonicalPath)
addArgIfNotNull("-pkg", packageName)
addFileArgs("-header", headers)
compilerOpts.forEach {
addArg("-compiler-option", it)
}
linkerOpts.forEach {
addArg("-linker-option", it)
}
addArgs("-compiler-option", allHeadersDirs.map { "-I${it.absolutePath}" })
addArgs("-headerFilterAdditionalSearchPrefix", headerFilterDirs.map { it.absolutePath })
libraries.files.filter {
it.extension == "klib"
}.forEach {
addArg("-l", it.absolutePath)
}
addAll(extraOpts)
}
outputFile.parentFile.mkdirs()
KonanInteropRunner(project).run(args)
}
}
@@ -1,209 +0,0 @@
/*
* Copyright 2010-2018 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.gradle.plugin.experimental.tasks
import org.gradle.api.artifacts.Configuration
import org.gradle.api.file.FileCollection
import org.gradle.api.file.FileSystemLocation
import org.gradle.api.file.FileTree
import org.gradle.api.provider.Provider
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.InputFiles
import org.gradle.api.tasks.Optional
import org.gradle.api.tasks.TaskAction
import org.gradle.api.tasks.compile.AbstractCompile
import org.jetbrains.kotlin.gradle.plugin.experimental.KotlinNativeFramework
import org.jetbrains.kotlin.gradle.plugin.experimental.internal.AbstractKotlinNativeBinary
import org.jetbrains.kotlin.gradle.plugin.experimental.internal.BitcodeEmbeddingMode
import org.jetbrains.kotlin.gradle.plugin.konan.*
import org.jetbrains.kotlin.gradle.tasks.CompilerPluginOptions
import org.jetbrains.kotlin.konan.target.CompilerOutputKind
import org.jetbrains.kotlin.konan.target.CompilerOutputKind.*
import org.jetbrains.kotlin.konan.target.KonanTarget
import java.io.File
import javax.inject.Inject
open class KotlinNativeCompile @Inject constructor(internal val binary: AbstractKotlinNativeBinary) : AbstractCompile()
{
init {
super.dependsOn(KonanPlugin.KONAN_DOWNLOAD_TASK_NAME)
}
// Inputs and outputs
val sources: FileCollection
@InputFiles get() = binary.sources
override fun getSource(): FileTree = sources.asFileTree
private val commonSources: FileCollection
get() = binary.commonSources
val libraries: Configuration
@InputFiles get() = binary.klibs
@get:InputFiles
val exportLibraries: FileCollection
get() = if (binary is KotlinNativeFramework) {
binary.export
} else {
project.files()
}
override fun getClasspath(): FileCollection = libraries
override fun setClasspath(configuration: FileCollection?) {
throw UnsupportedOperationException("Use klibs to set compile classpath in Kotlin/Native")
}
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
val additionalCompilerOptions: Collection<String> @Input get() = binary.additionalCompilerOptions
val linkerOpts: List<String>
@Input get() = binary.linkerOpts
val entryPoint: String?
@Optional @Input get() = binary.component.entryPoint
val compilerPluginOptions = CompilerPluginOptions()
var compilerPluginClasspath: FileCollection? = null
val outputFile: File
get() = outputLocationProvider.get().asFile
@get:Input
val embedBitcode: BitcodeEmbeddingMode
get() = if (binary is KotlinNativeFramework) {
binary.embedBitcode
} else {
BitcodeEmbeddingMode.DISABLE
}
val konanVersion: String
@Input get() = project.konanVersion.toString(true, true)
private val outputPathProvider: Provider<String> = project.provider {
with(binary) {
val root = outputRootName
val prefix = kind.prefix(konanTarget)
val suffix = kind.suffix(konanTarget)
val baseName = getBaseName().get()
var fileName = "${prefix}${baseName}${suffix}"
if (kind == FRAMEWORK ||
kind == STATIC ||
kind == DYNAMIC ||
kind == PROGRAM && konanTarget == KonanTarget.WASM32
) {
fileName = fileName.replace('-', '_')
}
"$root/${binary.names.dirName}/$fileName"
}
}
val outputLocationProvider: Provider<out FileSystemLocation> = with(project.layout) {
if (kind == CompilerOutputKind.FRAMEWORK) {
newOutputDirectory().apply {
set(buildDirectory.dir(outputPathProvider))
outputs.dir(this)
}
} else {
newOutputFile().apply {
set(buildDirectory.file(outputPathProvider))
outputs.file(this)
}
}
}
// Initializing AbstractCompile properties.
init {
this.setDestinationDir(project.provider {
if (kind == FRAMEWORK) outputFile else outputFile.parentFile
})
sourceCompatibility = "1.6"
targetCompatibility = "1.6"
}
// Task action.
@TaskAction
override fun compile() {
outputFile.parentFile.mkdirs()
val args = mutableListOf<String>().apply {
addArg("-o", outputFile.absolutePath)
addKey("-opt", optimized)
addKey("-g", debuggable)
addKey("-ea", debuggable)
addArg("-target", target)
addArg("-p", kind.name.toLowerCase())
add("-Xmulti-platform")
addArgIfNotNull("-entry", entryPoint)
compilerPluginClasspath?.let { pluginClasspath ->
pluginClasspath.map { it.canonicalPath }.sorted().forEach { path ->
add("-Xplugin=$path")
}
compilerPluginOptions.arguments.forEach {
add("-P$it")
}
}
addAll(additionalCompilerOptions)
fun Set<File>.filterKlibs() = filter {
it.extension == "klib"
}
libraries.files.filterKlibs().forEach {
addArg("-l", it.absolutePath)
}
// There is no need to check that all exported dependencies are passed with -l option
// because export configuration extends the libraries one.
exportLibraries.files.filterKlibs().forEach {
add("-Xexport-library=${it.absolutePath}")
}
when (embedBitcode) {
BitcodeEmbeddingMode.MARKER -> add("-Xembed-bitcode-marker")
BitcodeEmbeddingMode.BITCODE -> add("-Xembed-bitcode")
else -> { /* Do nothing. */ }
}
linkerOpts.forEach {
addArg("-linker-option", it)
}
addAll(sources.files.map { it.absolutePath })
commonSources.files.mapTo(this) { "-Xcommon-sources=${it.absolutePath}" }
}
KonanCompilerRunner(project).run(args)
}
}
@@ -18,7 +18,6 @@ package org.jetbrains.kotlin.gradle.plugin.model
import org.gradle.api.Project
import org.gradle.tooling.provider.model.ToolingModelBuilder
import org.jetbrains.kotlin.gradle.plugin.experimental.internal.AbstractKotlinNativeBinary
import org.jetbrains.kotlin.gradle.plugin.konan.konanArtifactsContainer
import org.jetbrains.kotlin.gradle.plugin.konan.konanExtension
import org.jetbrains.kotlin.gradle.plugin.konan.konanHome
@@ -45,55 +44,15 @@ object KonanToolingModelBuilder : ToolingModelBuilder {
)
}
private fun buildModelKotlinNative(project: Project): KonanModel {
val artifacts = project.components.withType(AbstractKotlinNativeBinary::class.java).map {
it.toModelArtifact()
}
return KonanModelImpl(
artifacts,
project.file(project.konanHome),
KonanVersion.CURRENT,
null,
null
)
}
private fun AbstractKotlinNativeBinary.toModelArtifact(): KonanModelArtifact {
val compileTask = compileTask.get()
val sourceRoots = with(component.sources) {
kotlin.srcDirs + getPlatformSources(konanTarget).srcDirs
}
return KonanModelArtifactImpl(
name,
compileTask.outputFile,
kind,
konanTarget.name,
compileTask.name,
sourceRoots.toList(),
sources.files.toList(),
klibs.files.toList(),
klibs.files.map { it.parentFile }
)
}
private val Project.hasKonanPlugin: Boolean
get() = with(pluginManager) {
hasPlugin("konan") ||
hasPlugin("org.jetbrains.kotlin.konan")
}
private val Project.hasKotlinNativePlugin: Boolean
get() = with(pluginManager) {
hasPlugin("kotlin-native") ||
hasPlugin("kotlin-platform-native") ||
hasPlugin("org.jetbrains.kotlin.native") ||
hasPlugin("org.jetbrains.kotlin.platform.native")
}
override fun buildAll(modelName: String, project: Project): KonanModel =
when {
project.hasKotlinNativePlugin -> buildModelKotlinNative(project)
project.hasKonanPlugin -> buildModelKonan(project)
else -> throw IllegalStateException("The project '${project.path}' has no Kotlin/Native plugin")
}
File diff suppressed because it is too large Load Diff