Basic native support in kotlin-multiplatform (#1811)
* Add dependency on KN shared in gradle-plugin
* Basic support for Kotlin/Native:
* Target presets
* Compilation into a klib
* Compilation into native binraies: framework and executable
* Basic dependencies between projects
* No jars in native publications
* Replace '-' with '_' in framework names
* Escape quotes in native command lines on Windows
* Move targets from Kotlin/Native repo
* Download KN compiler using Gradle's mechanisms
* Support source set dependencies in native
This commit is contained in:
@@ -0,0 +1,21 @@
|
|||||||
|
plugins {
|
||||||
|
kotlin("jvm")
|
||||||
|
id("jps-compatible")
|
||||||
|
}
|
||||||
|
|
||||||
|
description = "Kotlin/Native utils"
|
||||||
|
|
||||||
|
jvmTarget = "1.6"
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
compile(projectDist(":kotlin-stdlib"))
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceSets {
|
||||||
|
"main" { projectDefault() }
|
||||||
|
"test" {}
|
||||||
|
}
|
||||||
|
|
||||||
|
standardPublicJars()
|
||||||
|
|
||||||
|
publish()
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||||
|
* that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.konan
|
||||||
|
|
||||||
|
import java.io.Serializable
|
||||||
|
|
||||||
|
interface KonanVersion : Serializable {
|
||||||
|
val meta: MetaVersion
|
||||||
|
val major: Int
|
||||||
|
val minor: Int
|
||||||
|
val maintenance: Int
|
||||||
|
val build: Int
|
||||||
|
|
||||||
|
fun toString(showMeta: Boolean, showBuild: Boolean): String
|
||||||
|
|
||||||
|
companion object
|
||||||
|
}
|
||||||
|
|
||||||
|
data class KonanVersionImpl(
|
||||||
|
override val meta: MetaVersion = MetaVersion.DEV,
|
||||||
|
override val major: Int,
|
||||||
|
override val minor: Int,
|
||||||
|
override val maintenance: Int,
|
||||||
|
override val build: Int = -1
|
||||||
|
) : KonanVersion {
|
||||||
|
|
||||||
|
override fun toString(showMeta: Boolean, showBuild: Boolean) = buildString {
|
||||||
|
append(major)
|
||||||
|
append('.')
|
||||||
|
append(minor)
|
||||||
|
if (maintenance != 0) {
|
||||||
|
append('.')
|
||||||
|
append(maintenance)
|
||||||
|
}
|
||||||
|
if (showMeta) {
|
||||||
|
append('-')
|
||||||
|
append(meta.metaString)
|
||||||
|
}
|
||||||
|
if (showBuild && build != -1) {
|
||||||
|
append('-')
|
||||||
|
append(build)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val isRelease: Boolean
|
||||||
|
get() = meta == MetaVersion.RELEASE
|
||||||
|
|
||||||
|
private val versionString by lazy { toString(!isRelease, !isRelease) }
|
||||||
|
|
||||||
|
override fun toString() = versionString
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||||
|
* that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.konan
|
||||||
|
|
||||||
|
/**
|
||||||
|
* https://en.wikipedia.org/wiki/Software_versioning
|
||||||
|
* scheme major.minor[.build[.revision]].
|
||||||
|
*/
|
||||||
|
|
||||||
|
enum class MetaVersion(val metaString: String) {
|
||||||
|
DEV("dev"),
|
||||||
|
EAP("eap"),
|
||||||
|
ALPHA("alpha"),
|
||||||
|
BETA("beta"),
|
||||||
|
RC1("rc1"),
|
||||||
|
RC2("rc2"),
|
||||||
|
RELEASE("release")
|
||||||
|
}
|
||||||
@@ -0,0 +1,279 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||||
|
* that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.konan.target
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.konan.target.KonanTarget.*
|
||||||
|
import org.jetbrains.kotlin.konan.util.Named
|
||||||
|
|
||||||
|
enum class Family(val exeSuffix:String, val dynamicPrefix: String, val dynamicSuffix: String,
|
||||||
|
val staticPrefix: String, val staticSuffix: String) {
|
||||||
|
OSX ("kexe", "lib", "dylib", "lib", "a"),
|
||||||
|
IOS ("kexe", "lib", "dylib", "lib", "a"),
|
||||||
|
LINUX ("kexe", "lib", "so" , "lib", "a"),
|
||||||
|
MINGW ("exe" , "" , "dll" , "lib", "a"),
|
||||||
|
ANDROID ("so" , "lib", "so" , "lib", "a"),
|
||||||
|
WASM ("wasm", "" , "wasm" , "", "wasm"),
|
||||||
|
ZEPHYR ("o" , "lib", "a" , "lib", "a")
|
||||||
|
}
|
||||||
|
|
||||||
|
enum class Architecture(val bitness: Int) {
|
||||||
|
X64(64),
|
||||||
|
ARM64(64),
|
||||||
|
ARM32(32),
|
||||||
|
MIPS32(32),
|
||||||
|
MIPSEL32(32),
|
||||||
|
WASM32(32);
|
||||||
|
}
|
||||||
|
|
||||||
|
sealed class KonanTarget(override val name: String, val family: Family, val architecture: Architecture) : Named {
|
||||||
|
object ANDROID_ARM32 : KonanTarget( "android_arm32", Family.ANDROID, Architecture.ARM32)
|
||||||
|
object ANDROID_ARM64 : KonanTarget( "android_arm64", Family.ANDROID, Architecture.ARM64)
|
||||||
|
object IOS_ARM32 : KonanTarget( "ios_arm32", Family.IOS, Architecture.ARM32)
|
||||||
|
object IOS_ARM64 : KonanTarget( "ios_arm64", Family.IOS, Architecture.ARM64)
|
||||||
|
object IOS_X64 : KonanTarget( "ios_x64", Family.IOS, Architecture.X64)
|
||||||
|
object LINUX_X64 : KonanTarget( "linux_x64", Family.LINUX, Architecture.X64)
|
||||||
|
object MINGW_X64 : KonanTarget( "mingw_x64", Family.MINGW, Architecture.X64)
|
||||||
|
object MACOS_X64 : KonanTarget( "macos_x64", Family.OSX, Architecture.X64)
|
||||||
|
object LINUX_ARM32_HFP :KonanTarget( "linux_arm32_hfp", Family.LINUX, Architecture.ARM32)
|
||||||
|
object LINUX_MIPS32 : KonanTarget( "linux_mips32", Family.LINUX, Architecture.MIPS32)
|
||||||
|
object LINUX_MIPSEL32 : KonanTarget( "linux_mipsel32", Family.LINUX, Architecture.MIPSEL32)
|
||||||
|
object WASM32 : KonanTarget( "wasm32", Family.WASM, Architecture.WASM32)
|
||||||
|
|
||||||
|
// Tunable targets
|
||||||
|
class ZEPHYR(val subName: String, val genericName: String = "zephyr") :
|
||||||
|
KonanTarget("${genericName}_$subName", Family.ZEPHYR, Architecture.ARM32)
|
||||||
|
|
||||||
|
override fun toString() = name
|
||||||
|
}
|
||||||
|
|
||||||
|
fun hostTargetSuffix(host: KonanTarget, target: KonanTarget) =
|
||||||
|
if (target == host) host.name else "${host.name}-${target.name}"
|
||||||
|
|
||||||
|
enum class CompilerOutputKind {
|
||||||
|
PROGRAM {
|
||||||
|
override fun suffix(target: KonanTarget?) = ".${target!!.family.exeSuffix}"
|
||||||
|
},
|
||||||
|
DYNAMIC {
|
||||||
|
override fun suffix(target: KonanTarget?) = ".${target!!.family.dynamicSuffix}"
|
||||||
|
override fun prefix(target: KonanTarget?) = "${target!!.family.dynamicPrefix}"
|
||||||
|
},
|
||||||
|
STATIC {
|
||||||
|
override fun suffix(target: KonanTarget?) = ".${target!!.family.staticSuffix}"
|
||||||
|
override fun prefix(target: KonanTarget?) = "${target!!.family.staticPrefix}"
|
||||||
|
},
|
||||||
|
FRAMEWORK {
|
||||||
|
override fun suffix(target: KonanTarget?): String = ".framework"
|
||||||
|
},
|
||||||
|
LIBRARY {
|
||||||
|
override fun suffix(target: KonanTarget?) = ".klib"
|
||||||
|
},
|
||||||
|
BITCODE {
|
||||||
|
override fun suffix(target: KonanTarget?) = ".bc"
|
||||||
|
};
|
||||||
|
|
||||||
|
abstract fun suffix(target: KonanTarget? = null): String
|
||||||
|
open fun prefix(target: KonanTarget? = null): String = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
interface TargetManager {
|
||||||
|
val target: KonanTarget
|
||||||
|
val targetName : String
|
||||||
|
fun list() : Unit
|
||||||
|
val hostTargetSuffix: String
|
||||||
|
val targetSuffix: String
|
||||||
|
}
|
||||||
|
|
||||||
|
/** */
|
||||||
|
interface SubTargetProvider {
|
||||||
|
fun availableSubTarget(genericName: String): List<String>
|
||||||
|
}
|
||||||
|
|
||||||
|
private class NoSubTargets: SubTargetProvider {
|
||||||
|
override fun availableSubTarget(genericName: String): List<String> = emptyList()
|
||||||
|
}
|
||||||
|
|
||||||
|
private class TargetManagerImpl(val userRequest: String?, val hostManager: HostManager): TargetManager {
|
||||||
|
override val target = determineCurrent()
|
||||||
|
override val targetName
|
||||||
|
get() = target.visibleName
|
||||||
|
|
||||||
|
override fun list() {
|
||||||
|
hostManager.enabled.forEach {
|
||||||
|
val isDefault = if (it == target) "(default)" else ""
|
||||||
|
val aliasList = HostManager.listAliases(it.visibleName).joinToString(", ")
|
||||||
|
println(String.format("%1$-30s%2$-10s%3\$s", "${it.visibleName}:", "$isDefault", aliasList))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun determineCurrent(): KonanTarget {
|
||||||
|
return if (userRequest == null || userRequest == "host") {
|
||||||
|
HostManager.host
|
||||||
|
} else {
|
||||||
|
val resolvedAlias = HostManager.resolveAlias(userRequest)
|
||||||
|
hostManager.targets[hostManager.known(resolvedAlias)]!!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override val hostTargetSuffix get() = hostTargetSuffix(HostManager.host, target)
|
||||||
|
override val targetSuffix get() = target.name
|
||||||
|
}
|
||||||
|
|
||||||
|
open class HostManager(subtargetProvider: SubTargetProvider = NoSubTargets()) {
|
||||||
|
|
||||||
|
fun targetManager(userRequest: String? = null): TargetManager = TargetManagerImpl(userRequest, this)
|
||||||
|
|
||||||
|
// TODO: need a better way to enumerated predefined targets.
|
||||||
|
private val predefinedTargets = listOf(
|
||||||
|
KonanTarget.ANDROID_ARM32, ANDROID_ARM64,
|
||||||
|
IOS_ARM32, IOS_ARM64, IOS_X64,
|
||||||
|
LINUX_X64, LINUX_ARM32_HFP, LINUX_MIPS32, LINUX_MIPSEL32,
|
||||||
|
MINGW_X64,
|
||||||
|
MACOS_X64,
|
||||||
|
WASM32)
|
||||||
|
|
||||||
|
private val zephyrSubtargets = subtargetProvider.availableSubTarget("zephyr").map { ZEPHYR(it) }
|
||||||
|
|
||||||
|
private val configurableSubtargets = zephyrSubtargets
|
||||||
|
|
||||||
|
val targetValues: List<KonanTarget> by lazy {
|
||||||
|
predefinedTargets + configurableSubtargets
|
||||||
|
}
|
||||||
|
|
||||||
|
val targets = targetValues.associate{ it.visibleName to it }
|
||||||
|
|
||||||
|
fun toKonanTargets(names: Iterable<String>): List<KonanTarget> {
|
||||||
|
return names.map {
|
||||||
|
if (it == "host") HostManager.host
|
||||||
|
else targets[known(resolveAlias(it))]!!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun known(name: String): String {
|
||||||
|
if (targets[name] == null) {
|
||||||
|
throw TargetSupportException("Unknown target: $name. Use -list_targets to see the list of available targets")
|
||||||
|
}
|
||||||
|
return name
|
||||||
|
}
|
||||||
|
|
||||||
|
fun targetByName(name: String): KonanTarget {
|
||||||
|
if (name == "host") return host
|
||||||
|
val target = targets[resolveAlias(name)]
|
||||||
|
if (target == null) throw TargetSupportException("Unknown target name: $name")
|
||||||
|
return target
|
||||||
|
}
|
||||||
|
|
||||||
|
val enabled: List<KonanTarget> by lazy {
|
||||||
|
when (host) {
|
||||||
|
KonanTarget.LINUX_X64 -> listOf(
|
||||||
|
KonanTarget.LINUX_X64,
|
||||||
|
KonanTarget.LINUX_ARM32_HFP,
|
||||||
|
KonanTarget.LINUX_MIPS32,
|
||||||
|
KonanTarget.LINUX_MIPSEL32,
|
||||||
|
KonanTarget.ANDROID_ARM32,
|
||||||
|
KonanTarget.ANDROID_ARM64,
|
||||||
|
KonanTarget.WASM32
|
||||||
|
) + zephyrSubtargets
|
||||||
|
KonanTarget.MINGW_X64 -> listOf(
|
||||||
|
KonanTarget.MINGW_X64,
|
||||||
|
KonanTarget.WASM32
|
||||||
|
) + zephyrSubtargets
|
||||||
|
KonanTarget.MACOS_X64 -> listOf(
|
||||||
|
KonanTarget.MACOS_X64,
|
||||||
|
KonanTarget.IOS_ARM32,
|
||||||
|
KonanTarget.IOS_ARM64,
|
||||||
|
KonanTarget.IOS_X64,
|
||||||
|
KonanTarget.ANDROID_ARM32,
|
||||||
|
KonanTarget.ANDROID_ARM64,
|
||||||
|
KonanTarget.WASM32
|
||||||
|
) + zephyrSubtargets
|
||||||
|
else ->
|
||||||
|
throw TargetSupportException("Unknown host platform: $host")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun isEnabled(target: KonanTarget) = enabled.contains(target)
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun host_os(): String {
|
||||||
|
val javaOsName = System.getProperty("os.name")
|
||||||
|
return when {
|
||||||
|
javaOsName == "Mac OS X" -> "osx"
|
||||||
|
javaOsName == "Linux" -> "linux"
|
||||||
|
javaOsName.startsWith("Windows") -> "windows"
|
||||||
|
else -> throw TargetSupportException("Unknown operating system: ${javaOsName}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun simpleOsName(): String {
|
||||||
|
val hostOs = host_os()
|
||||||
|
return if (hostOs == "osx") "macos" else hostOs
|
||||||
|
}
|
||||||
|
|
||||||
|
val jniHostPlatformIncludeDir: String
|
||||||
|
get() = when(host) {
|
||||||
|
KonanTarget.MACOS_X64 -> "darwin"
|
||||||
|
KonanTarget.LINUX_X64 -> "linux"
|
||||||
|
KonanTarget.MINGW_X64 ->"win32"
|
||||||
|
else -> throw TargetSupportException("Unknown host: $host.")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun host_arch(): String {
|
||||||
|
val javaArch = System.getProperty("os.arch")
|
||||||
|
return when (javaArch) {
|
||||||
|
"x86_64" -> "x86_64"
|
||||||
|
"amd64" -> "x86_64"
|
||||||
|
"arm64" -> "arm64"
|
||||||
|
else -> throw TargetSupportException("Unknown hardware platform: ${javaArch}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val host: KonanTarget = when (host_os()) {
|
||||||
|
"osx" -> KonanTarget.MACOS_X64
|
||||||
|
"linux" -> KonanTarget.LINUX_X64
|
||||||
|
"windows" -> KonanTarget.MINGW_X64
|
||||||
|
else -> throw TargetSupportException("Unknown host target: ${host_os()} ${host_arch()}")
|
||||||
|
}
|
||||||
|
|
||||||
|
val hostIsMac = (host == KonanTarget.MACOS_X64)
|
||||||
|
val hostIsLinux = (host == KonanTarget.LINUX_X64)
|
||||||
|
val hostIsMingw = (host == KonanTarget.MINGW_X64)
|
||||||
|
|
||||||
|
val hostSuffix get() = host.name
|
||||||
|
@JvmStatic
|
||||||
|
val hostName get() = host.name
|
||||||
|
|
||||||
|
val knownTargetTemplates = listOf("zephyr")
|
||||||
|
|
||||||
|
private val targetAliasResolutions = mapOf(
|
||||||
|
"linux" to "linux_x64",
|
||||||
|
"macbook" to "macos_x64",
|
||||||
|
"macos" to "macos_x64",
|
||||||
|
"imac" to "macos_x64",
|
||||||
|
"raspberrypi" to "linux_arm32_hfp",
|
||||||
|
"iphone32" to "ios_arm32",
|
||||||
|
"iphone" to "ios_arm64",
|
||||||
|
"ipad" to "ios_arm64",
|
||||||
|
"ios" to "ios_arm64",
|
||||||
|
"iphone_sim" to "ios_x64",
|
||||||
|
"mingw" to "mingw_x64"
|
||||||
|
)
|
||||||
|
|
||||||
|
private val targetAliases: Map<String, List<String>> by lazy {
|
||||||
|
val result = mutableMapOf<String, MutableList<String>>()
|
||||||
|
targetAliasResolutions.entries.forEach {
|
||||||
|
result.getOrPut(it.value, { mutableListOf() } ).add(it.key)
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
fun resolveAlias(request: String): String = targetAliasResolutions[request] ?: request
|
||||||
|
|
||||||
|
fun listAliases(target: String): List<String> = targetAliases[target] ?: emptyList()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class TargetSupportException (message: String = "", cause: Throwable? = null) : Exception(message, cause)
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||||
|
* that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.konan.util
|
||||||
|
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
object DependencyDirectories {
|
||||||
|
val localKonanDir: File by lazy {
|
||||||
|
File(System.getenv("KONAN_DATA_DIR") ?: (System.getProperty("user.home") + File.separator + ".konan"))
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
val defaultDependenciesRoot: File
|
||||||
|
get() = localKonanDir.resolve("dependencies")
|
||||||
|
|
||||||
|
val defaultDependencyCacheDir: File
|
||||||
|
get() = localKonanDir.resolve("cache")
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||||
|
* that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.konan.util
|
||||||
|
|
||||||
|
val <T : Enum<T>> T.visibleName get() = name.toLowerCase()
|
||||||
|
interface Named {
|
||||||
|
val name: String
|
||||||
|
val visibleName get() = name
|
||||||
|
}
|
||||||
@@ -15,7 +15,8 @@ pill {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compile project(':kotlin-stdlib')
|
compile project(':kotlin-stdlib')
|
||||||
|
compile project('::konan:konan-utils')
|
||||||
|
|
||||||
compileOnly gradleApi()
|
compileOnly gradleApi()
|
||||||
compileOnly 'com.android.tools.build:gradle:0.4.2'
|
compileOnly 'com.android.tools.build:gradle:0.4.2'
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-2
@@ -12,8 +12,7 @@ import org.gradle.api.attributes.CompatibilityCheckDetails
|
|||||||
import java.io.Serializable
|
import java.io.Serializable
|
||||||
|
|
||||||
enum class KotlinPlatformType: Named, Serializable {
|
enum class KotlinPlatformType: Named, Serializable {
|
||||||
common, jvm, js, androidJvm,
|
common, jvm, js, androidJvm, native;
|
||||||
native; // TODO: split native into separate entries here or transform the enum to interface and implement entries in K/N
|
|
||||||
|
|
||||||
override fun toString(): String = name
|
override fun toString(): String = name
|
||||||
override fun getName(): String = name
|
override fun getName(): String = name
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ dependencies {
|
|||||||
compileOnly project(':compiler:daemon-common')
|
compileOnly project(':compiler:daemon-common')
|
||||||
|
|
||||||
compile project(':kotlin-stdlib')
|
compile project(':kotlin-stdlib')
|
||||||
|
compile project(':konan:konan-utils')
|
||||||
compileOnly project(':kotlin-reflect-api')
|
compileOnly project(':kotlin-reflect-api')
|
||||||
compileOnly project(':kotlin-android-extensions')
|
compileOnly project(':kotlin-android-extensions')
|
||||||
compileOnly project(':kotlin-build-common')
|
compileOnly project(':kotlin-build-common')
|
||||||
|
|||||||
+1
-1
@@ -102,7 +102,7 @@ class Android25ProjectHandler(kotlinConfigurationTools: KotlinConfigurationTools
|
|||||||
override fun setUpDependencyResolution(variant: BaseVariant, compilation: KotlinJvmAndroidCompilation) {
|
override fun setUpDependencyResolution(variant: BaseVariant, compilation: KotlinJvmAndroidCompilation) {
|
||||||
val project = compilation.target.project
|
val project = compilation.target.project
|
||||||
|
|
||||||
KotlinTargetConfigurator.defineConfigurationsForCompilation(compilation, compilation.target, project.configurations)
|
AbstractKotlinTargetConfigurator.defineConfigurationsForCompilation(compilation, compilation.target, project.configurations)
|
||||||
|
|
||||||
compilation.compileDependencyFiles = variant.compileConfiguration.apply {
|
compilation.compileDependencyFiles = variant.compileConfiguration.apply {
|
||||||
usesPlatformOf(compilation.target)
|
usesPlatformOf(compilation.target)
|
||||||
|
|||||||
+162
@@ -0,0 +1,162 @@
|
|||||||
|
/*
|
||||||
|
* 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.compilerRunner
|
||||||
|
|
||||||
|
import org.gradle.api.Named
|
||||||
|
import org.gradle.api.Project
|
||||||
|
import org.gradle.api.file.FileCollection
|
||||||
|
import org.jetbrains.kotlin.konan.target.HostManager
|
||||||
|
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||||
|
import org.jetbrains.kotlin.konan.util.DependencyDirectories
|
||||||
|
|
||||||
|
/** Copied from Kotlin/Native repository. */
|
||||||
|
|
||||||
|
// TODO: Rename to FQ names
|
||||||
|
internal enum class KotlinNativeProjectProperty(val propertyName: String) {
|
||||||
|
KONAN_HOME ("konan.home"),
|
||||||
|
KONAN_JVM_ARGS ("konan.jvmArgs"),
|
||||||
|
KONAN_USE_ENVIRONMENT_VARIABLES("konan.useEnvironmentVariables"),
|
||||||
|
DOWNLOAD_COMPILER ("download.compiler"),
|
||||||
|
|
||||||
|
// Properties used instead of env vars until https://github.com/gradle/gradle/issues/3468 is fixed.
|
||||||
|
// TODO: Remove them when an API for env vars is provided.
|
||||||
|
KONAN_CONFIGURATION_BUILD_DIR ("konan.configuration.build.dir"),
|
||||||
|
KONAN_DEBUGGING_SYMBOLS ("konan.debugging.symbols"),
|
||||||
|
KONAN_OPTIMIZATIONS_ENABLE ("konan.optimizations.enable"),
|
||||||
|
KONAN_PUBLICATION_ENABLED ("konan.publication.enabled")
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun Project.hasProperty(property: KotlinNativeProjectProperty) = hasProperty(property.propertyName)
|
||||||
|
internal fun Project.findProperty(property: KotlinNativeProjectProperty): Any? = findProperty(property.propertyName)
|
||||||
|
|
||||||
|
internal fun Project.setProperty(property: KotlinNativeProjectProperty, value: Any?) =
|
||||||
|
extensions.extraProperties.set(property.propertyName, value)
|
||||||
|
|
||||||
|
internal fun Project.getProperty(property: KotlinNativeProjectProperty) = findProperty(property)
|
||||||
|
?: throw IllegalArgumentException("No such property in the project: ${property.propertyName}")
|
||||||
|
|
||||||
|
internal val Project.jvmArgs
|
||||||
|
get() = (findProperty(KotlinNativeProjectProperty.KONAN_JVM_ARGS) as String?)?.split("\\s+".toRegex()).orEmpty()
|
||||||
|
|
||||||
|
// konanHome extension is set by downloadKonanCompiler task.
|
||||||
|
internal val Project.konanHome: String
|
||||||
|
get() {
|
||||||
|
assert(hasProperty(KotlinNativeProjectProperty.KONAN_HOME))
|
||||||
|
return project.file(getProperty(KotlinNativeProjectProperty.KONAN_HOME)).canonicalPath
|
||||||
|
}
|
||||||
|
|
||||||
|
internal interface KonanToolRunner: Named {
|
||||||
|
val mainClass: String
|
||||||
|
val classpath: FileCollection
|
||||||
|
val jvmArgs: List<String>
|
||||||
|
val environment: Map<String, Any>
|
||||||
|
val additionalSystemProperties: Map<String, String>
|
||||||
|
|
||||||
|
fun run(args: List<String>)
|
||||||
|
fun run(vararg args: String) = run(args.toList())
|
||||||
|
}
|
||||||
|
|
||||||
|
internal abstract class KonanCliRunner(
|
||||||
|
val toolName: String,
|
||||||
|
val fullName: String,
|
||||||
|
val project: Project,
|
||||||
|
private val additionalJvmArgs: List<String>
|
||||||
|
): KonanToolRunner {
|
||||||
|
override val mainClass = "org.jetbrains.kotlin.cli.utilities.MainKt"
|
||||||
|
|
||||||
|
override fun getName() = toolName
|
||||||
|
|
||||||
|
// We need to unset some environment variables which are set by XCode and may potentially affect the tool executed.
|
||||||
|
protected val blacklistEnvironment: List<String> by lazy {
|
||||||
|
KonanToolRunner::class.java.getResourceAsStream("/env_blacklist")?.let { stream ->
|
||||||
|
stream.reader().use { it.readLines() }
|
||||||
|
} ?: emptyList<String>()
|
||||||
|
}
|
||||||
|
|
||||||
|
override val classpath: FileCollection =
|
||||||
|
project.fileTree("${project.konanHome}/konan/lib/")
|
||||||
|
.apply { include("*.jar") }
|
||||||
|
|
||||||
|
override val jvmArgs = mutableListOf("-ea").apply {
|
||||||
|
if (additionalJvmArgs.none { it.startsWith("-Xmx") } &&
|
||||||
|
project.jvmArgs.none { it.startsWith("-Xmx") }) {
|
||||||
|
add("-Xmx3G")
|
||||||
|
}
|
||||||
|
addAll(additionalJvmArgs)
|
||||||
|
addAll(project.jvmArgs)
|
||||||
|
}
|
||||||
|
|
||||||
|
override val additionalSystemProperties = mutableMapOf(
|
||||||
|
"konan.home" to project.konanHome,
|
||||||
|
"java.library.path" to "${project.konanHome}/konan/nativelib"
|
||||||
|
)
|
||||||
|
|
||||||
|
override val environment = mutableMapOf("LIBCLANG_DISABLE_CRASH_RECOVERY" to "1")
|
||||||
|
|
||||||
|
private fun String.escapeQuotes() = replace("\"", "\\\"")
|
||||||
|
|
||||||
|
private fun List<Pair<String, String>>.escapeQuotesForWindows() =
|
||||||
|
if (HostManager.hostIsMingw) {
|
||||||
|
map { (key, value) -> key.escapeQuotes() to value.escapeQuotes() }
|
||||||
|
} else {
|
||||||
|
this
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun run(args: List<String>) {
|
||||||
|
project.logger.info("Run tool: $toolName with args: ${args.joinToString(separator = " ")}")
|
||||||
|
if (classpath.isEmpty) {
|
||||||
|
throw IllegalStateException("Classpath of the tool is empty: $toolName\n" +
|
||||||
|
"Probably the 'konan.home' project property contains an incorrect path.\n" +
|
||||||
|
"Please change it to the compiler root directory and rerun the build.")
|
||||||
|
}
|
||||||
|
|
||||||
|
project.javaexec { spec ->
|
||||||
|
spec.main = mainClass
|
||||||
|
spec.classpath = classpath
|
||||||
|
spec.jvmArgs(jvmArgs)
|
||||||
|
spec.systemProperties(
|
||||||
|
System.getProperties()
|
||||||
|
.map { (k, v) -> k.toString() to v.toString() }
|
||||||
|
.escapeQuotesForWindows()
|
||||||
|
.toMap()
|
||||||
|
)
|
||||||
|
spec.systemProperties(additionalSystemProperties)
|
||||||
|
spec.args(listOf(toolName) + args)
|
||||||
|
blacklistEnvironment.forEach { spec.environment.remove(it) }
|
||||||
|
spec.environment(environment)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class KonanInteropRunner(project: Project, additionalJvmArgs: List<String> = emptyList())
|
||||||
|
: KonanCliRunner("cinterop", "Kotlin/Native cinterop tool", project, additionalJvmArgs)
|
||||||
|
{
|
||||||
|
init {
|
||||||
|
if (HostManager.host == KonanTarget.MINGW_X64) {
|
||||||
|
//TODO: Oh-ho-ho fix it in more convinient way.
|
||||||
|
environment.put("PATH", DependencyDirectories.defaultDependenciesRoot.absolutePath +
|
||||||
|
"\\msys2-mingw-w64-x86_64-gcc-7.2.0-clang-llvm-5.0.0-windows-x86-64" +
|
||||||
|
"\\bin;${environment.get("PATH")}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class KonanCompilerRunner(project: Project, additionalJvmArgs: List<String> = emptyList())
|
||||||
|
: KonanCliRunner("konanc", "Kotlin/Native compiler", project, additionalJvmArgs)
|
||||||
|
|
||||||
|
internal class KonanKlibRunner(project: Project, additionalJvmArgs: List<String> = emptyList())
|
||||||
|
: KonanCliRunner("klib", "Klib management tool", project, additionalJvmArgs)
|
||||||
+1
-1
@@ -432,7 +432,7 @@ internal abstract class AbstractKotlinPlugin(
|
|||||||
// Setup the consuming configurations:
|
// Setup the consuming configurations:
|
||||||
project.dependencies.attributesSchema.attribute(KotlinPlatformType.attribute)
|
project.dependencies.attributesSchema.attribute(KotlinPlatformType.attribute)
|
||||||
kotlinTarget.compilations.all { compilation ->
|
kotlinTarget.compilations.all { compilation ->
|
||||||
KotlinTargetConfigurator.defineConfigurationsForCompilation(compilation, kotlinTarget, project.configurations)
|
AbstractKotlinTargetConfigurator.defineConfigurationsForCompilation(compilation, kotlinTarget, project.configurations)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup the published configurations:
|
// Setup the published configurations:
|
||||||
|
|||||||
+274
-67
@@ -18,6 +18,8 @@ import org.gradle.api.attributes.Usage.USAGE_ATTRIBUTE
|
|||||||
import org.gradle.api.file.ConfigurableFileCollection
|
import org.gradle.api.file.ConfigurableFileCollection
|
||||||
import org.gradle.api.file.FileCollection
|
import org.gradle.api.file.FileCollection
|
||||||
import org.gradle.api.internal.artifacts.ArtifactAttributes
|
import org.gradle.api.internal.artifacts.ArtifactAttributes
|
||||||
|
import org.gradle.api.internal.artifacts.publish.DefaultPublishArtifact
|
||||||
|
import org.gradle.api.internal.plugins.DefaultArtifactPublicationSet
|
||||||
import org.gradle.api.internal.plugins.DslObject
|
import org.gradle.api.internal.plugins.DslObject
|
||||||
import org.gradle.api.plugins.BasePlugin
|
import org.gradle.api.plugins.BasePlugin
|
||||||
import org.gradle.api.plugins.JavaBasePlugin
|
import org.gradle.api.plugins.JavaBasePlugin
|
||||||
@@ -26,22 +28,26 @@ import org.gradle.api.tasks.testing.Test
|
|||||||
import org.gradle.internal.cleanup.BuildOutputCleanupRegistry
|
import org.gradle.internal.cleanup.BuildOutputCleanupRegistry
|
||||||
import org.gradle.language.base.plugins.LifecycleBasePlugin
|
import org.gradle.language.base.plugins.LifecycleBasePlugin
|
||||||
import org.gradle.language.jvm.tasks.ProcessResources
|
import org.gradle.language.jvm.tasks.ProcessResources
|
||||||
|
import org.gradle.nativeplatform.test.tasks.RunTestExecutable
|
||||||
import org.jetbrains.kotlin.gradle.dsl.kotlinExtension
|
import org.jetbrains.kotlin.gradle.dsl.kotlinExtension
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinOnlyTarget
|
import org.jetbrains.kotlin.gradle.plugin.mpp.*
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.disambiguateName
|
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.defaultSourceSetName
|
|
||||||
import org.jetbrains.kotlin.gradle.plugin.sources.getSourceSetHierarchy
|
import org.jetbrains.kotlin.gradle.plugin.sources.getSourceSetHierarchy
|
||||||
import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile
|
import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile
|
||||||
|
import org.jetbrains.kotlin.gradle.tasks.KonanCompilerDownloadTask
|
||||||
|
import org.jetbrains.kotlin.gradle.tasks.KotlinNativeCompile
|
||||||
import org.jetbrains.kotlin.gradle.utils.isGradleVersionAtLeast
|
import org.jetbrains.kotlin.gradle.utils.isGradleVersionAtLeast
|
||||||
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
|
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
|
||||||
|
import org.jetbrains.kotlin.konan.target.CompilerOutputKind
|
||||||
|
import org.jetbrains.kotlin.konan.target.HostManager
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
import java.util.*
|
||||||
import java.util.concurrent.Callable
|
import java.util.concurrent.Callable
|
||||||
|
|
||||||
open class KotlinTargetConfigurator(
|
abstract class AbstractKotlinTargetConfigurator<KotlinTargetType : KotlinTarget>(
|
||||||
private val buildOutputCleanupRegistry: BuildOutputCleanupRegistry
|
private val buildOutputCleanupRegistry: BuildOutputCleanupRegistry
|
||||||
) {
|
) {
|
||||||
fun <KotlinCompilationType: KotlinCompilation> configureTarget(
|
open fun configureTarget(
|
||||||
target: KotlinOnlyTarget<KotlinCompilationType>
|
target: KotlinTargetType
|
||||||
) {
|
) {
|
||||||
configureCompilationDefaults(target)
|
configureCompilationDefaults(target)
|
||||||
configureCompilations(target)
|
configureCompilations(target)
|
||||||
@@ -49,11 +55,12 @@ open class KotlinTargetConfigurator(
|
|||||||
configureArchivesAndComponent(target)
|
configureArchivesAndComponent(target)
|
||||||
configureTest(target)
|
configureTest(target)
|
||||||
configureBuild(target)
|
configureBuild(target)
|
||||||
|
|
||||||
setCompatibilityOfAbstractCompileTasks(target.project)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun <KotlinCompilationType: KotlinCompilation> configureCompilations(platformTarget: KotlinOnlyTarget<KotlinCompilationType>) {
|
|
||||||
|
abstract fun configureArchivesAndComponent(target: KotlinTargetType)
|
||||||
|
|
||||||
|
protected fun configureCompilations(platformTarget: KotlinTargetType) {
|
||||||
val project = platformTarget.project
|
val project = platformTarget.project
|
||||||
val main = platformTarget.compilations.create(KotlinCompilation.MAIN_COMPILATION_NAME)
|
val main = platformTarget.compilations.create(KotlinCompilation.MAIN_COMPILATION_NAME)
|
||||||
|
|
||||||
@@ -75,7 +82,7 @@ open class KotlinTargetConfigurator(
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun <KotlinCompilationType: KotlinCompilation> configureCompilationDefaults(target: KotlinOnlyTarget<KotlinCompilationType>) {
|
protected fun configureCompilationDefaults(target: KotlinTargetType) {
|
||||||
val project = target.project
|
val project = target.project
|
||||||
|
|
||||||
target.compilations.all { compilation ->
|
target.compilations.all { compilation ->
|
||||||
@@ -94,49 +101,7 @@ open class KotlinTargetConfigurator(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun configureArchivesAndComponent(target: KotlinOnlyTarget<*>) {
|
protected fun configureTest(target: KotlinTarget) {
|
||||||
val project = target.project
|
|
||||||
|
|
||||||
val mainCompilation = target.compilations.getByName(KotlinCompilation.MAIN_COMPILATION_NAME)
|
|
||||||
|
|
||||||
val jar = project.tasks.create(target.artifactsTaskName, Jar::class.java)
|
|
||||||
jar.description = "Assembles a jar archive containing the main classes."
|
|
||||||
jar.group = BasePlugin.BUILD_GROUP
|
|
||||||
jar.from(mainCompilation.output)
|
|
||||||
|
|
||||||
val apiElementsConfiguration = project.configurations.getByName(target.apiElementsConfigurationName)
|
|
||||||
|
|
||||||
target.disambiguationClassifier?.let { jar.classifier = it }
|
|
||||||
|
|
||||||
// Workaround: adding the artifact during configuration seems to interfere with the Java plugin, which results into missing
|
|
||||||
// task dependency 'assemble -> jar' if the Java plugin is applied after this steps
|
|
||||||
project.afterEvaluate {
|
|
||||||
project.artifacts.add(Dependency.ARCHIVES_CONFIGURATION, jar) { jarArtifact ->
|
|
||||||
jarArtifact.builtBy(jar)
|
|
||||||
jarArtifact.type = ArtifactTypeDefinition.JAR_TYPE
|
|
||||||
|
|
||||||
addJar(apiElementsConfiguration, jarArtifact)
|
|
||||||
|
|
||||||
if (mainCompilation is KotlinCompilationToRunnableFiles) {
|
|
||||||
val runtimeConfiguration = project.configurations.getByName(mainCompilation.deprecatedRuntimeConfigurationName)
|
|
||||||
val runtimeElementsConfiguration = project.configurations.getByName(target.runtimeElementsConfigurationName)
|
|
||||||
addJar(runtimeConfiguration, jarArtifact)
|
|
||||||
addJar(runtimeElementsConfiguration, jarArtifact)
|
|
||||||
// TODO Check Gradle's special split into variants for classes & resources -- do we need that too?
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun addJar(configuration: Configuration, jarArtifact: PublishArtifact) {
|
|
||||||
val publications = configuration.outgoing
|
|
||||||
|
|
||||||
// Configure an implicit variant
|
|
||||||
publications.artifacts.add(jarArtifact)
|
|
||||||
publications.attributes.attribute(ArtifactAttributes.ARTIFACT_FORMAT, ArtifactTypeDefinition.JAR_TYPE)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun configureTest(target: KotlinTarget) {
|
|
||||||
val testCompilation = target.compilations.getByName(KotlinCompilation.TEST_COMPILATION_NAME) as? KotlinCompilationToRunnableFiles
|
val testCompilation = target.compilations.getByName(KotlinCompilation.TEST_COMPILATION_NAME) as? KotlinCompilationToRunnableFiles
|
||||||
?: return // Otherwise, there is no runtime classpath
|
?: return // Otherwise, there is no runtime classpath
|
||||||
|
|
||||||
@@ -151,7 +116,7 @@ open class KotlinTargetConfigurator(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun configureResourceProcessing(
|
protected fun configureResourceProcessing(
|
||||||
compilation: KotlinCompilationWithResources,
|
compilation: KotlinCompilationWithResources,
|
||||||
resourceSet: FileCollection
|
resourceSet: FileCollection
|
||||||
) {
|
) {
|
||||||
@@ -168,7 +133,7 @@ open class KotlinTargetConfigurator(
|
|||||||
resourcesTask.from(resourceSet)
|
resourcesTask.from(resourceSet)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createLifecycleTask(compilation: KotlinCompilation) {
|
protected fun createLifecycleTask(compilation: KotlinCompilation) {
|
||||||
val project = compilation.target.project
|
val project = compilation.target.project
|
||||||
|
|
||||||
(compilation.output.classesDirs as ConfigurableFileCollection).from(project.files().builtBy(compilation.compileAllTaskName))
|
(compilation.output.classesDirs as ConfigurableFileCollection).from(project.files().builtBy(compilation.compileAllTaskName))
|
||||||
@@ -186,7 +151,7 @@ open class KotlinTargetConfigurator(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun defineConfigurationsForTarget(target: KotlinOnlyTarget<*>) {
|
protected fun defineConfigurationsForTarget(target: KotlinTargetType) {
|
||||||
val project = target.project
|
val project = target.project
|
||||||
|
|
||||||
val configurations = project.configurations
|
val configurations = project.configurations
|
||||||
@@ -243,7 +208,7 @@ open class KotlinTargetConfigurator(
|
|||||||
defaultConfiguration.extendsFrom(runtimeElementsConfiguration).usesPlatformOf(target)
|
defaultConfiguration.extendsFrom(runtimeElementsConfiguration).usesPlatformOf(target)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun configureBuild(target: KotlinOnlyTarget<*>) {
|
protected fun configureBuild(target: KotlinTargetType) {
|
||||||
val project = target.project
|
val project = target.project
|
||||||
val testCompilation = target.compilations.getByName(KotlinCompilation.TEST_COMPILATION_NAME)
|
val testCompilation = target.compilations.getByName(KotlinCompilation.TEST_COMPILATION_NAME)
|
||||||
project.tasks.maybeCreate(buildNeededTaskName, DefaultTask::class.java).apply {
|
project.tasks.maybeCreate(buildNeededTaskName, DefaultTask::class.java).apply {
|
||||||
@@ -279,14 +244,6 @@ open class KotlinTargetConfigurator(
|
|||||||
task.dependsOn(configuration.getTaskDependencyFromProjectDependency(useDependedOn, otherProjectTaskName))
|
task.dependsOn(configuration.getTaskDependencyFromProjectDependency(useDependedOn, otherProjectTaskName))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setCompatibilityOfAbstractCompileTasks(project: Project) = with (project) {
|
|
||||||
tasks.withType(AbstractKotlinCompile::class.java).all {
|
|
||||||
// Workaround: these are input properties and should not hold null values:
|
|
||||||
it.targetCompatibility = ""
|
|
||||||
it.sourceCompatibility = ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val buildNeededTaskName = "buildAllNeeded"
|
const val buildNeededTaskName = "buildAllNeeded"
|
||||||
const val buildDependentTaskName = "buildAllDependents"
|
const val buildDependentTaskName = "buildAllDependents"
|
||||||
@@ -363,14 +320,260 @@ open class KotlinTargetConfigurator(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val KotlinCompilation.deprecatedCompileConfigurationName: String
|
|
||||||
|
internal val KotlinCompilation.deprecatedCompileConfigurationName: String
|
||||||
get() = disambiguateName("compile")
|
get() = disambiguateName("compile")
|
||||||
|
|
||||||
private val KotlinCompilationToRunnableFiles.deprecatedRuntimeConfigurationName: String
|
internal val KotlinCompilationToRunnableFiles.deprecatedRuntimeConfigurationName: String
|
||||||
get() = disambiguateName("runtime")
|
get() = disambiguateName("runtime")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
open class KotlinTargetConfigurator<KotlinCompilationType: KotlinCompilation>(
|
||||||
|
buildOutputCleanupRegistry: BuildOutputCleanupRegistry
|
||||||
|
) : AbstractKotlinTargetConfigurator<KotlinOnlyTarget<KotlinCompilationType>>(buildOutputCleanupRegistry) {
|
||||||
|
|
||||||
|
override fun configureTarget(
|
||||||
|
target: KotlinOnlyTarget<KotlinCompilationType>
|
||||||
|
) {
|
||||||
|
super.configureTarget(target)
|
||||||
|
setCompatibilityOfAbstractCompileTasks(target.project)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun configureArchivesAndComponent(target: KotlinOnlyTarget<KotlinCompilationType>) {
|
||||||
|
val project = target.project
|
||||||
|
|
||||||
|
val mainCompilation = target.compilations.getByName(KotlinCompilation.MAIN_COMPILATION_NAME)
|
||||||
|
|
||||||
|
val jar = project.tasks.create(target.artifactsTaskName, Jar::class.java)
|
||||||
|
jar.description = "Assembles a jar archive containing the main classes."
|
||||||
|
jar.group = BasePlugin.BUILD_GROUP
|
||||||
|
jar.from(mainCompilation.output)
|
||||||
|
|
||||||
|
val apiElementsConfiguration = project.configurations.getByName(target.apiElementsConfigurationName)
|
||||||
|
|
||||||
|
target.disambiguationClassifier?.let { jar.classifier = it }
|
||||||
|
|
||||||
|
// Workaround: adding the artifact during configuration seems to interfere with the Java plugin, which results into missing
|
||||||
|
// task dependency 'assemble -> jar' if the Java plugin is applied after this steps
|
||||||
|
project.afterEvaluate {
|
||||||
|
project.artifacts.add(Dependency.ARCHIVES_CONFIGURATION, jar) { jarArtifact ->
|
||||||
|
jarArtifact.builtBy(jar)
|
||||||
|
jarArtifact.type = ArtifactTypeDefinition.JAR_TYPE
|
||||||
|
|
||||||
|
addJar(apiElementsConfiguration, jarArtifact)
|
||||||
|
|
||||||
|
if (mainCompilation is KotlinCompilationToRunnableFiles) {
|
||||||
|
val runtimeConfiguration = project.configurations.getByName(mainCompilation.deprecatedRuntimeConfigurationName)
|
||||||
|
val runtimeElementsConfiguration = project.configurations.getByName(target.runtimeElementsConfigurationName)
|
||||||
|
addJar(runtimeConfiguration, jarArtifact)
|
||||||
|
addJar(runtimeElementsConfiguration, jarArtifact)
|
||||||
|
// TODO Check Gradle's special split into variants for classes & resources -- do we need that too?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun addJar(configuration: Configuration, jarArtifact: PublishArtifact) {
|
||||||
|
val publications = configuration.outgoing
|
||||||
|
|
||||||
|
// Configure an implicit variant
|
||||||
|
publications.artifacts.add(jarArtifact)
|
||||||
|
publications.attributes.attribute(ArtifactAttributes.ARTIFACT_FORMAT, ArtifactTypeDefinition.JAR_TYPE)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setCompatibilityOfAbstractCompileTasks(project: Project) = with (project) {
|
||||||
|
tasks.withType(AbstractKotlinCompile::class.java).all {
|
||||||
|
// Workaround: these are input properties and should not hold null values:
|
||||||
|
it.targetCompatibility = ""
|
||||||
|
it.sourceCompatibility = ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
open class KotlinNativeTargetConfigurator(
|
||||||
|
buildOutputCleanupRegistry: BuildOutputCleanupRegistry
|
||||||
|
) : AbstractKotlinTargetConfigurator<KotlinNativeTarget>(buildOutputCleanupRegistry) {
|
||||||
|
|
||||||
|
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 Project.createTestTask(compilation: KotlinNativeCompilation, testExecutableLinkTask: KotlinNativeCompile) {
|
||||||
|
val taskName = lowerCamelCaseName("run", compilation.name, compilation.target.name)
|
||||||
|
val testTask = tasks.create(taskName, RunTestExecutable::class.java).apply {
|
||||||
|
group = LifecycleBasePlugin.VERIFICATION_GROUP
|
||||||
|
description = "Executes Kotlin/Native unit tests from the '${compilation.name}' compilation " +
|
||||||
|
"for target '${compilation.platformType.name}'"
|
||||||
|
|
||||||
|
val testExecutableProperty = testExecutableLinkTask.outputFile
|
||||||
|
executable = testExecutableProperty.get().absolutePath
|
||||||
|
// TODO: Provide a normal test path!
|
||||||
|
outputDir = project.layout.buildDirectory.dir("test-results").get().asFile
|
||||||
|
|
||||||
|
onlyIf { testExecutableProperty.get().exists() }
|
||||||
|
inputs.file(testExecutableProperty)
|
||||||
|
dependsOn(testExecutableLinkTask)
|
||||||
|
dependsOnCompilerDownloading()
|
||||||
|
}
|
||||||
|
tasks.maybeCreate(LifecycleBasePlugin.CHECK_TASK_NAME).apply {
|
||||||
|
dependsOn(testTask)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun Project.createBinaryLinkTasks(compilation: KotlinNativeCompilation) = whenEvaluated {
|
||||||
|
val konanTarget = compilation.target.konanTarget
|
||||||
|
val buildTypes = compilation.buildTypes
|
||||||
|
val availableOutputKinds = compilation.outputKinds.filter { it.availableFor(konanTarget) }
|
||||||
|
val linkAll = project.tasks.maybeCreate(compilation.linkAllTaskName)
|
||||||
|
|
||||||
|
for (buildType in compilation.buildTypes) {
|
||||||
|
for (kind in availableOutputKinds) {
|
||||||
|
val compilerOutputKind = kind.compilerOutputKind
|
||||||
|
|
||||||
|
val compilationSuffix = compilation.name
|
||||||
|
val buildTypeSuffix = createDimensionSuffix(buildType.name, buildTypes)
|
||||||
|
val targetSuffix = compilation.target.name
|
||||||
|
val kindSuffix = kind.taskNameClassifier
|
||||||
|
val taskName = lowerCamelCaseName("link", compilationSuffix, buildTypeSuffix, kindSuffix, targetSuffix)
|
||||||
|
|
||||||
|
val linkTask = project.tasks.create(
|
||||||
|
taskName,
|
||||||
|
KotlinNativeCompile::class.java
|
||||||
|
).apply {
|
||||||
|
this.compilation = compilation
|
||||||
|
outputKind = compilerOutputKind
|
||||||
|
group = BasePlugin.BUILD_GROUP
|
||||||
|
description = "Links ${kind.description} from the '${compilation.name}' " +
|
||||||
|
"compilation for target '${compilation.platformType.name}'"
|
||||||
|
|
||||||
|
optimized = buildType.optimized
|
||||||
|
debuggable = buildType.debuggable
|
||||||
|
|
||||||
|
if (outputKind == CompilerOutputKind.FRAMEWORK) {
|
||||||
|
outputs.dir(outputFile)
|
||||||
|
} else {
|
||||||
|
outputs.file(outputFile)
|
||||||
|
}
|
||||||
|
|
||||||
|
outputFile.set(provider {
|
||||||
|
val targetSubDirectory = compilation.target.disambiguationClassifier?.let { "$it/" }.orEmpty()
|
||||||
|
val buildTypeSubDirectory = buildType.name.toLowerCase()
|
||||||
|
val compilationName = compilation.compilationName
|
||||||
|
val prefix = compilerOutputKind.prefix(konanTarget)
|
||||||
|
val suffix = compilerOutputKind.suffix(konanTarget)
|
||||||
|
var filename = "$prefix$compilationName$suffix"
|
||||||
|
if (outputKind == CompilerOutputKind.FRAMEWORK) {
|
||||||
|
filename = filename.replace('-', '_')
|
||||||
|
}
|
||||||
|
File(project.buildDir, "bin/$targetSubDirectory$compilationName/$buildTypeSubDirectory/$filename")
|
||||||
|
})
|
||||||
|
|
||||||
|
dependsOnCompilerDownloading()
|
||||||
|
linkAll.dependsOn(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (compilation.isTestCompilation &&
|
||||||
|
buildType == NativeBuildType.DEBUG &&
|
||||||
|
konanTarget == HostManager.host
|
||||||
|
) {
|
||||||
|
createTestTask(compilation, linkTask)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun Project.createKlibPublishableArtifact(compilation: KotlinNativeCompilation, compileTask: KotlinNativeCompile) {
|
||||||
|
val apiElements = configurations.getByName(compilation.target.apiElementsConfigurationName)
|
||||||
|
val klibArtifact = DefaultPublishArtifact(
|
||||||
|
compilation.name,
|
||||||
|
"klib",
|
||||||
|
"klib",
|
||||||
|
null,
|
||||||
|
Date(),
|
||||||
|
compileTask.outputFile.get(),
|
||||||
|
compileTask
|
||||||
|
)
|
||||||
|
compilation.target.disambiguationClassifier?.let { klibArtifact.classifier = it }
|
||||||
|
project.extensions.getByType(DefaultArtifactPublicationSet::class.java).addCandidate(klibArtifact)
|
||||||
|
|
||||||
|
with(apiElements.outgoing) {
|
||||||
|
artifacts.add(klibArtifact)
|
||||||
|
attributes.attribute(ArtifactAttributes.ARTIFACT_FORMAT, NativeArtifactFormat.KLIB)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun Project.createKlibCompilationTask(compilation: KotlinNativeCompilation) {
|
||||||
|
val compileTask = tasks.create(
|
||||||
|
compilation.compileKotlinTaskName,
|
||||||
|
KotlinNativeCompile::class.java
|
||||||
|
).apply {
|
||||||
|
this.compilation = compilation
|
||||||
|
outputKind = CompilerOutputKind.LIBRARY
|
||||||
|
group = BasePlugin.BUILD_GROUP
|
||||||
|
description = "Compiles a klibrary from the '${compilation.name}' " +
|
||||||
|
"compilation for target '${compilation.platformType.name}'"
|
||||||
|
|
||||||
|
outputs.file(outputFile)
|
||||||
|
outputFile.set(provider {
|
||||||
|
val targetSubDirectory = compilation.target.disambiguationClassifier?.let { "$it/" }.orEmpty()
|
||||||
|
val classifier = compilation.target.disambiguationClassifier?.let { "-$it" }.orEmpty()
|
||||||
|
val compilationName = compilation.compilationName
|
||||||
|
val klibName = if (compilation.name == KotlinCompilation.MAIN_COMPILATION_NAME)
|
||||||
|
project.name
|
||||||
|
else
|
||||||
|
compilationName
|
||||||
|
File(project.buildDir, "classes/kotlin/$targetSubDirectory$compilationName/$klibName$classifier.klib")
|
||||||
|
})
|
||||||
|
|
||||||
|
dependsOnCompilerDownloading()
|
||||||
|
compilation.output.tryAddClassesDir {
|
||||||
|
project.files(this.outputFile).builtBy(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
project.tasks.getByName(compilation.compileAllTaskName).dependsOn(compileTask)
|
||||||
|
|
||||||
|
if (compilation.compilationName == KotlinCompilation.MAIN_COMPILATION_NAME) {
|
||||||
|
project.tasks.getByName(compilation.target.artifactsTaskName).apply {
|
||||||
|
dependsOn(compileTask)
|
||||||
|
dependsOn(compilation.linkAllTaskName)
|
||||||
|
}
|
||||||
|
project.tasks.getByName(LifecycleBasePlugin.ASSEMBLE_TASK_NAME).apply {
|
||||||
|
dependsOn(compileTask)
|
||||||
|
dependsOn(compilation.linkAllTaskName)
|
||||||
|
}
|
||||||
|
createKlibPublishableArtifact(compilation, compileTask)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun configureArchivesAndComponent(target: KotlinNativeTarget) = with(target.project) {
|
||||||
|
if (!HostManager().isEnabled(target.konanTarget)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.create(target.artifactsTaskName)
|
||||||
|
target.compilations.all {
|
||||||
|
createKlibCompilationTask(it)
|
||||||
|
createBinaryLinkTasks(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun Task.dependsOnCompilerDownloading() =
|
||||||
|
dependsOn(KonanCompilerDownloadTask.KONAN_DOWNLOAD_TASK_NAME)
|
||||||
|
|
||||||
|
object NativeArtifactFormat {
|
||||||
|
const val KLIB = "org.jerbrains.kotlin.klib"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
internal fun Project.usageByName(usageName: String): Usage =
|
internal fun Project.usageByName(usageName: String): Usage =
|
||||||
if (isGradleVersionAtLeast(4, 0)) {
|
if (isGradleVersionAtLeast(4, 0)) {
|
||||||
// `project.objects` is an API introduced in Gradle 4.0
|
// `project.objects` is an API introduced in Gradle 4.0
|
||||||
@@ -383,5 +586,9 @@ internal fun Project.usageByName(usageName: String): Usage =
|
|||||||
|
|
||||||
fun Configuration.usesPlatformOf(target: KotlinTarget): Configuration {
|
fun Configuration.usesPlatformOf(target: KotlinTarget): Configuration {
|
||||||
attributes.attribute(KotlinPlatformType.attribute, target.platformType)
|
attributes.attribute(KotlinPlatformType.attribute, target.platformType)
|
||||||
|
// TODO: Provide an universal way to copy attributes from the target.
|
||||||
|
if (target is KotlinNativeTarget) {
|
||||||
|
attributes.attribute(KotlinNativeTarget.konanTargetAttribute, target.konanTarget.name)
|
||||||
|
}
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
+21
-9
@@ -3,15 +3,6 @@
|
|||||||
* that can be found in the license/LICENSE.txt file.
|
* that can be found in the license/LICENSE.txt file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
|
||||||
* that can be found in the license/LICENSE.txt file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
|
||||||
* that can be found in the license/LICENSE.txt file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.gradle.plugin.mpp
|
package org.jetbrains.kotlin.gradle.plugin.mpp
|
||||||
|
|
||||||
@@ -82,4 +73,25 @@ class KotlinJsCompilationFactory(
|
|||||||
|
|
||||||
override fun create(name: String): KotlinJsCompilation =
|
override fun create(name: String): KotlinJsCompilation =
|
||||||
KotlinJsCompilation(target, name, target.createCompilationOutput(name))
|
KotlinJsCompilation(target, name, target.createCompilationOutput(name))
|
||||||
|
}
|
||||||
|
|
||||||
|
class KotlinNativeCompilationFactory(
|
||||||
|
val project: Project,
|
||||||
|
val target: KotlinNativeTarget
|
||||||
|
) : KotlinCompilationFactory<KotlinNativeCompilation> {
|
||||||
|
|
||||||
|
override val itemClass: Class<KotlinNativeCompilation>
|
||||||
|
get() = KotlinNativeCompilation::class.java
|
||||||
|
|
||||||
|
override fun create(name: String): KotlinNativeCompilation =
|
||||||
|
KotlinNativeCompilation(target, name, target.createCompilationOutput(name)).apply {
|
||||||
|
if (name == KotlinCompilation.TEST_COMPILATION_NAME) {
|
||||||
|
outputKinds = mutableListOf(NativeOutputKind.EXECUTABLE)
|
||||||
|
buildTypes = mutableListOf(NativeBuildType.DEBUG)
|
||||||
|
isTestCompilation = true
|
||||||
|
} else {
|
||||||
|
buildTypes = mutableListOf(NativeBuildType.DEBUG, NativeBuildType.RELEASE)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
-10
@@ -3,16 +3,6 @@
|
|||||||
* that can be found in the license/LICENSE.txt file.
|
* that can be found in the license/LICENSE.txt file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
|
||||||
* that can be found in the license/LICENSE.txt file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
|
||||||
* that can be found in the license/LICENSE.txt file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.gradle.plugin.mpp
|
package org.jetbrains.kotlin.gradle.plugin.mpp
|
||||||
|
|
||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
|
|||||||
+4
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
|
|||||||
import org.jetbrains.kotlin.gradle.dsl.kotlinExtension
|
import org.jetbrains.kotlin.gradle.dsl.kotlinExtension
|
||||||
import org.jetbrains.kotlin.gradle.plugin.*
|
import org.jetbrains.kotlin.gradle.plugin.*
|
||||||
import org.jetbrains.kotlin.gradle.plugin.source.KotlinSourceSet
|
import org.jetbrains.kotlin.gradle.plugin.source.KotlinSourceSet
|
||||||
|
import org.jetbrains.kotlin.konan.target.HostManager
|
||||||
|
|
||||||
internal val Project.multiplatformExtension get(): KotlinMultiplatformExtension? =
|
internal val Project.multiplatformExtension get(): KotlinMultiplatformExtension? =
|
||||||
project.extensions.getByName("kotlin") as KotlinMultiplatformExtension
|
project.extensions.getByName("kotlin") as KotlinMultiplatformExtension
|
||||||
@@ -86,6 +87,9 @@ class KotlinMultiplatformPlugin(
|
|||||||
add(KotlinJsTargetPreset(project, instantiator, fileResolver, buildOutputCleanupRegistry, kotlinPluginVersion))
|
add(KotlinJsTargetPreset(project, instantiator, fileResolver, buildOutputCleanupRegistry, kotlinPluginVersion))
|
||||||
add(KotlinAndroidTargetPreset(project, kotlinPluginVersion))
|
add(KotlinAndroidTargetPreset(project, kotlinPluginVersion))
|
||||||
add(KotlinJvmWithJavaTargetPreset(project, kotlinPluginVersion))
|
add(KotlinJvmWithJavaTargetPreset(project, kotlinPluginVersion))
|
||||||
|
HostManager().targets.forEach { _, target ->
|
||||||
|
add(KotlinNativeTargetPreset(target.presetName, project, target, buildOutputCleanupRegistry))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+6
@@ -33,6 +33,12 @@ class KotlinSoftwareComponent(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// At the moment all KN artifacts have JAVA_API usage.
|
||||||
|
// TODO: Replace it with a specific usage
|
||||||
|
object NativeUsage {
|
||||||
|
const val KOTLIN_KLIB = "kotlin-klib"
|
||||||
|
}
|
||||||
|
|
||||||
internal class KotlinPlatformUsageContext(
|
internal class KotlinPlatformUsageContext(
|
||||||
val project: Project,
|
val project: Project,
|
||||||
val kotlinTarget: KotlinTarget,
|
val kotlinTarget: KotlinTarget,
|
||||||
|
|||||||
+48
@@ -0,0 +1,48 @@
|
|||||||
|
package org.jetbrains.kotlin.gradle.plugin.mpp
|
||||||
|
|
||||||
|
import org.gradle.api.Named
|
||||||
|
import org.gradle.api.attributes.Usage
|
||||||
|
import org.jetbrains.kotlin.konan.target.CompilerOutputKind
|
||||||
|
import org.jetbrains.kotlin.konan.target.Family
|
||||||
|
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||||
|
|
||||||
|
object KotlinNativeUsage {
|
||||||
|
const val KLIB = "kotlin-native-klib"
|
||||||
|
const val FRAMEWORK = "kotlin-native-framework"
|
||||||
|
}
|
||||||
|
|
||||||
|
enum class NativeBuildType(val optimized: Boolean, val debuggable: Boolean): Named {
|
||||||
|
RELEASE(true, false),
|
||||||
|
DEBUG(false, true);
|
||||||
|
|
||||||
|
override fun getName(): String = name.toLowerCase()
|
||||||
|
}
|
||||||
|
|
||||||
|
enum class NativeOutputKind(
|
||||||
|
val compilerOutputKind: CompilerOutputKind,
|
||||||
|
val taskNameClassifier: String,
|
||||||
|
val description: String = taskNameClassifier,
|
||||||
|
val additionalCompilerFlags: List<String> = emptyList(),
|
||||||
|
val runtimeUsageName: String? = null,
|
||||||
|
val linkUsageName: String? = null,
|
||||||
|
val publishable: Boolean = true
|
||||||
|
) {
|
||||||
|
EXECUTABLE(
|
||||||
|
CompilerOutputKind.PROGRAM,
|
||||||
|
"executable",
|
||||||
|
description = "an executable",
|
||||||
|
runtimeUsageName = Usage.NATIVE_RUNTIME
|
||||||
|
),
|
||||||
|
FRAMEWORK(
|
||||||
|
CompilerOutputKind.FRAMEWORK,
|
||||||
|
"framework",
|
||||||
|
description = "an Objective-C framework",
|
||||||
|
linkUsageName = KotlinNativeUsage.FRAMEWORK,
|
||||||
|
publishable = false
|
||||||
|
) {
|
||||||
|
override fun availableFor(target: KonanTarget) =
|
||||||
|
target.family == Family.OSX || target.family == Family.IOS
|
||||||
|
};
|
||||||
|
|
||||||
|
open fun availableFor(target: KonanTarget) = true
|
||||||
|
}
|
||||||
+75
-13
@@ -3,16 +3,6 @@
|
|||||||
* that can be found in the license/LICENSE.txt file.
|
* that can be found in the license/LICENSE.txt file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
|
||||||
* that can be found in the license/LICENSE.txt file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
|
||||||
* that can be found in the license/LICENSE.txt file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.gradle.plugin.mpp
|
package org.jetbrains.kotlin.gradle.plugin.mpp
|
||||||
|
|
||||||
import groovy.lang.Closure
|
import groovy.lang.Closure
|
||||||
@@ -59,21 +49,30 @@ internal class DefaultKotlinDependencyHandler(
|
|||||||
}
|
}
|
||||||
|
|
||||||
abstract class AbstractKotlinCompilation(
|
abstract class AbstractKotlinCompilation(
|
||||||
final override val target: KotlinTarget,
|
target: KotlinTarget,
|
||||||
override val compilationName: String
|
override val compilationName: String
|
||||||
) : KotlinCompilation, HasKotlinDependencies {
|
) : KotlinCompilation, HasKotlinDependencies {
|
||||||
|
|
||||||
|
// Don't declare this property in the constructor to avoid NPE
|
||||||
|
// when an overriding property of a subclass is accessed instead.
|
||||||
|
override val target: KotlinTarget = target
|
||||||
|
|
||||||
private val attributeContainer = HierarchyAttributeContainer(target.attributes)
|
private val attributeContainer = HierarchyAttributeContainer(target.attributes)
|
||||||
|
|
||||||
override fun getAttributes(): AttributeContainer = attributeContainer
|
override fun getAttributes(): AttributeContainer = attributeContainer
|
||||||
|
|
||||||
override val kotlinSourceSets: MutableSet<KotlinSourceSet> = mutableSetOf()
|
override val kotlinSourceSets: MutableSet<KotlinSourceSet> = mutableSetOf()
|
||||||
|
|
||||||
|
open fun addSourcesToCompileTask(sourceSet: KotlinSourceSet) {
|
||||||
|
(target.project.tasks.getByName(compileKotlinTaskName) as AbstractKotlinCompile<*>).source(sourceSet.kotlin)
|
||||||
|
}
|
||||||
|
|
||||||
override fun source(sourceSet: KotlinSourceSet) {
|
override fun source(sourceSet: KotlinSourceSet) {
|
||||||
if (kotlinSourceSets.add(sourceSet)) {
|
if (kotlinSourceSets.add(sourceSet)) {
|
||||||
with(target.project) {
|
with(target.project) {
|
||||||
whenEvaluated {
|
whenEvaluated {
|
||||||
sourceSet.getSourceSetHierarchy().forEach { sourceSet ->
|
sourceSet.getSourceSetHierarchy().forEach { sourceSet ->
|
||||||
(target.project.tasks.getByName(compileKotlinTaskName) as AbstractKotlinCompile<*>).source(sourceSet.kotlin)
|
addSourcesToCompileTask(sourceSet)
|
||||||
|
|
||||||
// Use `forced = false` since `api`, `implementation`, and `compileOnly` may be missing in some cases like
|
// Use `forced = false` since `api`, `implementation`, and `compileOnly` may be missing in some cases like
|
||||||
// old Java & Android projects:
|
// old Java & Android projects:
|
||||||
@@ -242,4 +241,67 @@ class KotlinCommonCompilation(
|
|||||||
target: KotlinTarget,
|
target: KotlinTarget,
|
||||||
name: String,
|
name: String,
|
||||||
override val output: SourceSetOutput
|
override val output: SourceSetOutput
|
||||||
) : AbstractKotlinCompilation(target, name)
|
) : AbstractKotlinCompilation(target, name)
|
||||||
|
|
||||||
|
class KotlinNativeCompilation(
|
||||||
|
override val target: KotlinNativeTarget,
|
||||||
|
name: String,
|
||||||
|
override val output: SourceSetOutput
|
||||||
|
) : AbstractKotlinCompilation(target, name) {
|
||||||
|
|
||||||
|
// A FileCollection containing source files from all source sets used by this compilation
|
||||||
|
// (taking into account dependencies between source sets). Used by both compilation
|
||||||
|
// and linking tasks.
|
||||||
|
// TODO: Move into the compilation task when the linking task does klib linking instead of compilation.
|
||||||
|
internal var allSources: FileCollection = target.project.files()
|
||||||
|
|
||||||
|
val linkAllTaskName: String
|
||||||
|
get() = lowerCamelCaseName(
|
||||||
|
"link",
|
||||||
|
compilationName.takeIf { it != "main" }.orEmpty(),
|
||||||
|
target.disambiguationClassifier
|
||||||
|
)
|
||||||
|
|
||||||
|
var isTestCompilation = false
|
||||||
|
|
||||||
|
// Native-specific DSL.
|
||||||
|
val extraOpts = mutableListOf<String>()
|
||||||
|
|
||||||
|
fun extraOpts(vararg values: Any) = extraOpts(values.toList())
|
||||||
|
fun extraOpts(values: List<Any>) {
|
||||||
|
extraOpts.addAll(values.map { it.toString() })
|
||||||
|
}
|
||||||
|
|
||||||
|
var buildTypes = mutableListOf<NativeBuildType>()
|
||||||
|
var outputKinds = mutableListOf<NativeOutputKind>()
|
||||||
|
|
||||||
|
// Naming
|
||||||
|
|
||||||
|
override val compileDependencyConfigurationName: String
|
||||||
|
get() = lowerCamelCaseName(
|
||||||
|
target.disambiguationClassifier,
|
||||||
|
compilationName.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME }.orEmpty(),
|
||||||
|
"compileKlibraries"
|
||||||
|
)
|
||||||
|
|
||||||
|
override val compileAllTaskName: String
|
||||||
|
get() = lowerCamelCaseName(
|
||||||
|
target.disambiguationClassifier,
|
||||||
|
compilationName.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME }.orEmpty(),
|
||||||
|
"klibrary"
|
||||||
|
)
|
||||||
|
|
||||||
|
override fun addSourcesToCompileTask(sourceSet: KotlinSourceSet) {
|
||||||
|
allSources += sourceSet.kotlin
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Can we do it better?
|
||||||
|
companion object {
|
||||||
|
val DEBUG = NativeBuildType.DEBUG
|
||||||
|
val RELEASE = NativeBuildType.RELEASE
|
||||||
|
|
||||||
|
val EXECUTABLE = NativeOutputKind.EXECUTABLE
|
||||||
|
val FRAMEWORK = NativeOutputKind.FRAMEWORK
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+47
-3
@@ -10,9 +10,14 @@ import org.gradle.api.internal.file.FileResolver
|
|||||||
import org.gradle.api.plugins.JavaPlugin
|
import org.gradle.api.plugins.JavaPlugin
|
||||||
import org.gradle.internal.cleanup.BuildOutputCleanupRegistry
|
import org.gradle.internal.cleanup.BuildOutputCleanupRegistry
|
||||||
import org.gradle.internal.reflect.Instantiator
|
import org.gradle.internal.reflect.Instantiator
|
||||||
|
import org.jetbrains.kotlin.compilerRunner.*
|
||||||
import org.jetbrains.kotlin.gradle.plugin.*
|
import org.jetbrains.kotlin.gradle.plugin.*
|
||||||
import org.jetbrains.kotlin.gradle.tasks.AndroidTasksProvider
|
import org.jetbrains.kotlin.gradle.tasks.AndroidTasksProvider
|
||||||
|
import org.jetbrains.kotlin.gradle.tasks.KonanCompilerDownloadTask
|
||||||
|
import org.jetbrains.kotlin.gradle.tasks.KonanCompilerDownloadTask.Companion.KONAN_DOWNLOAD_TASK_NAME
|
||||||
import org.jetbrains.kotlin.gradle.tasks.KotlinTasksProvider
|
import org.jetbrains.kotlin.gradle.tasks.KotlinTasksProvider
|
||||||
|
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
|
||||||
|
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||||
|
|
||||||
abstract class KotlinOnlyTargetPreset<T : KotlinCompilation>(
|
abstract class KotlinOnlyTargetPreset<T : KotlinCompilation>(
|
||||||
protected val project: Project,
|
protected val project: Project,
|
||||||
@@ -31,7 +36,7 @@ abstract class KotlinOnlyTargetPreset<T : KotlinCompilation>(
|
|||||||
compilations = project.container(compilationFactory.itemClass, compilationFactory)
|
compilations = project.container(compilationFactory.itemClass, compilationFactory)
|
||||||
}
|
}
|
||||||
|
|
||||||
KotlinTargetConfigurator(buildOutputCleanupRegistry).configureTarget(result)
|
KotlinTargetConfigurator<T>(buildOutputCleanupRegistry).configureTarget(result)
|
||||||
|
|
||||||
result.compilations.all { compilation ->
|
result.compilations.all { compilation ->
|
||||||
buildCompilationProcessor(compilation).run()
|
buildCompilationProcessor(compilation).run()
|
||||||
@@ -184,7 +189,7 @@ class KotlinJvmWithJavaTargetPreset(
|
|||||||
|
|
||||||
target.compilations.all { compilation ->
|
target.compilations.all { compilation ->
|
||||||
// Set up dependency resolution using platforms:
|
// Set up dependency resolution using platforms:
|
||||||
KotlinTargetConfigurator.defineConfigurationsForCompilation(compilation, target, project.configurations)
|
AbstractKotlinTargetConfigurator.defineConfigurationsForCompilation(compilation, target, project.configurations)
|
||||||
}
|
}
|
||||||
|
|
||||||
target.compilations.getByName("test").run {
|
target.compilations.getByName("test").run {
|
||||||
@@ -200,4 +205,43 @@ class KotlinJvmWithJavaTargetPreset(
|
|||||||
companion object {
|
companion object {
|
||||||
const val PRESET_NAME = "jvmWithJava"
|
const val PRESET_NAME = "jvmWithJava"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class KotlinNativeTargetPreset(
|
||||||
|
private val name: String,
|
||||||
|
val project: Project,
|
||||||
|
val konanTarget: KonanTarget,
|
||||||
|
private val buildOutputCleanupRegistry: BuildOutputCleanupRegistry
|
||||||
|
) : KotlinTargetPreset<KotlinNativeTarget> {
|
||||||
|
|
||||||
|
override fun getName(): String = name
|
||||||
|
|
||||||
|
private fun createCompilerDownloadingTask() = with(project) {
|
||||||
|
if (!hasProperty(KotlinNativeProjectProperty.KONAN_HOME)) {
|
||||||
|
setProperty(KotlinNativeProjectProperty.KONAN_HOME, KonanCompilerDownloadTask.compilerDirectory)
|
||||||
|
setProperty(KotlinNativeProjectProperty.DOWNLOAD_COMPILER, true)
|
||||||
|
}
|
||||||
|
tasks.maybeCreate(KONAN_DOWNLOAD_TASK_NAME, KonanCompilerDownloadTask::class.java)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createTarget(name: String): KotlinNativeTarget {
|
||||||
|
val result = KotlinNativeTarget(project, konanTarget).apply {
|
||||||
|
targetName = name
|
||||||
|
disambiguationClassifier = name
|
||||||
|
|
||||||
|
val compilationFactory = KotlinNativeCompilationFactory(project, this)
|
||||||
|
compilations = project.container(compilationFactory.itemClass, compilationFactory)
|
||||||
|
}
|
||||||
|
|
||||||
|
createCompilerDownloadingTask()
|
||||||
|
KotlinNativeTargetConfigurator(buildOutputCleanupRegistry).configureTarget(result)
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal val KonanTarget.presetName: String
|
||||||
|
get() = when(this) {
|
||||||
|
KonanTarget.ANDROID_ARM32 -> "androidNativeArm32"
|
||||||
|
KonanTarget.ANDROID_ARM64 -> "androidNativeArm64"
|
||||||
|
else -> lowerCamelCaseName(*this.name.split('_').toTypedArray())
|
||||||
|
}
|
||||||
|
|||||||
+24
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.gradle.plugin.mpp
|
|||||||
import org.gradle.api.NamedDomainObjectContainer
|
import org.gradle.api.NamedDomainObjectContainer
|
||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
import org.gradle.api.artifacts.Dependency
|
import org.gradle.api.artifacts.Dependency
|
||||||
|
import org.gradle.api.attributes.Attribute
|
||||||
import org.gradle.api.attributes.AttributeContainer
|
import org.gradle.api.attributes.AttributeContainer
|
||||||
import org.gradle.api.internal.component.UsageContext
|
import org.gradle.api.internal.component.UsageContext
|
||||||
import org.gradle.api.plugins.JavaPlugin
|
import org.gradle.api.plugins.JavaPlugin
|
||||||
@@ -15,6 +16,7 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinCompilationToRunnableFiles
|
|||||||
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
|
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
|
||||||
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
|
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
|
||||||
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
|
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
|
||||||
|
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||||
|
|
||||||
abstract class AbstractKotlinTarget (
|
abstract class AbstractKotlinTarget (
|
||||||
override val project: Project
|
override val project: Project
|
||||||
@@ -118,3 +120,25 @@ open class KotlinOnlyTarget<T : KotlinCompilation>(
|
|||||||
override var disambiguationClassifier: String? = null
|
override var disambiguationClassifier: String? = null
|
||||||
internal set
|
internal set
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class KotlinNativeTarget(
|
||||||
|
project: Project,
|
||||||
|
val konanTarget: KonanTarget
|
||||||
|
) : KotlinOnlyTarget<KotlinNativeCompilation>(project, KotlinPlatformType.native) {
|
||||||
|
|
||||||
|
init {
|
||||||
|
attributes.attribute(konanTargetAttribute, konanTarget.name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Should binary files be output of a target or a compilation?
|
||||||
|
override val artifactsTaskName: String
|
||||||
|
get() = disambiguateName("link")
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val konanTargetAttribute = Attribute.of(
|
||||||
|
"org.jetbrains.kotlin.native.target",
|
||||||
|
String::class.java
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
+238
@@ -0,0 +1,238 @@
|
|||||||
|
package org.jetbrains.kotlin.gradle.tasks
|
||||||
|
|
||||||
|
import org.gradle.api.DefaultTask
|
||||||
|
import org.gradle.api.artifacts.repositories.ArtifactRepository
|
||||||
|
import org.gradle.api.artifacts.repositories.IvyPatternRepositoryLayout
|
||||||
|
import org.gradle.api.file.FileCollection
|
||||||
|
import org.gradle.api.file.FileTree
|
||||||
|
import org.gradle.api.provider.Property
|
||||||
|
import org.gradle.api.tasks.*
|
||||||
|
import org.jetbrains.kotlin.compilerRunner.*
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeCompilation
|
||||||
|
import org.jetbrains.kotlin.konan.KonanVersion
|
||||||
|
import org.jetbrains.kotlin.konan.KonanVersionImpl
|
||||||
|
import org.jetbrains.kotlin.konan.MetaVersion
|
||||||
|
import org.jetbrains.kotlin.konan.target.CompilerOutputKind
|
||||||
|
import org.jetbrains.kotlin.konan.target.HostManager
|
||||||
|
import org.jetbrains.kotlin.konan.util.DependencyDirectories
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
// TODO: It's just temporary tasks used while KN isn't integrated with Big Kotlin compilation infrastructure.
|
||||||
|
|
||||||
|
open class KotlinNativeCompile : DefaultTask() {
|
||||||
|
|
||||||
|
init {
|
||||||
|
super.dependsOn(KonanCompilerDownloadTask.KONAN_DOWNLOAD_TASK_NAME)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Internal
|
||||||
|
lateinit var compilation: KotlinNativeCompilation
|
||||||
|
|
||||||
|
// region inputs/outputs
|
||||||
|
@Input
|
||||||
|
lateinit var outputKind: CompilerOutputKind
|
||||||
|
|
||||||
|
// Inputs and outputs
|
||||||
|
|
||||||
|
val sources: FileCollection
|
||||||
|
@InputFiles
|
||||||
|
@SkipWhenEmpty
|
||||||
|
get() = compilation.allSources
|
||||||
|
|
||||||
|
val libraries: FileCollection
|
||||||
|
@InputFiles get() = compilation.compileDependencyFiles.filter {
|
||||||
|
it.extension == "klib"
|
||||||
|
}
|
||||||
|
|
||||||
|
@Input
|
||||||
|
var optimized = false
|
||||||
|
@Input
|
||||||
|
var debuggable = true
|
||||||
|
|
||||||
|
val processTests
|
||||||
|
@Input get() = compilation.isTestCompilation
|
||||||
|
|
||||||
|
val target: String
|
||||||
|
@Input get() = compilation.target.konanTarget.name
|
||||||
|
|
||||||
|
val additionalCompilerOptions: Collection<String>
|
||||||
|
@Input get() = compilation.extraOpts
|
||||||
|
|
||||||
|
|
||||||
|
val outputFile: Property<File> = project.objects.property(File::class.java)
|
||||||
|
|
||||||
|
// endregion
|
||||||
|
|
||||||
|
// region Useful extensions
|
||||||
|
internal fun MutableList<String>.addArg(parameter: String, value: String) {
|
||||||
|
add(parameter)
|
||||||
|
add(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun MutableList<String>.addArgs(parameter: String, values: Iterable<String>) {
|
||||||
|
values.forEach {
|
||||||
|
addArg(parameter, it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun MutableList<String>.addArgIfNotNull(parameter: String, value: String?) {
|
||||||
|
if (value != null) {
|
||||||
|
addArg(parameter, value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun MutableList<String>.addKey(key: String, enabled: Boolean) {
|
||||||
|
if (enabled) {
|
||||||
|
add(key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun MutableList<String>.addFileArgs(parameter: String, values: FileCollection) {
|
||||||
|
values.files.forEach {
|
||||||
|
addArg(parameter, it.canonicalPath)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun MutableList<String>.addFileArgs(parameter: String, values: Collection<FileCollection>) {
|
||||||
|
values.forEach {
|
||||||
|
addFileArgs(parameter, it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun MutableList<String>.addListArg(parameter: String, values: List<String>) {
|
||||||
|
if (values.isNotEmpty()) {
|
||||||
|
addArg(parameter, values.joinToString(separator = " "))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// endregion
|
||||||
|
|
||||||
|
@TaskAction
|
||||||
|
fun compile() {
|
||||||
|
val output = outputFile.get()
|
||||||
|
output.parentFile.mkdirs()
|
||||||
|
|
||||||
|
val args = mutableListOf<String>().apply {
|
||||||
|
addArg("-o", outputFile.get().absolutePath)
|
||||||
|
addKey("-opt", optimized)
|
||||||
|
addKey("-g", debuggable)
|
||||||
|
addKey("-ea", debuggable)
|
||||||
|
addKey("-tr", processTests)
|
||||||
|
|
||||||
|
addArg("-target", target)
|
||||||
|
addArg("-p", outputKind.name.toLowerCase())
|
||||||
|
|
||||||
|
add("-Xmulti-platform")
|
||||||
|
|
||||||
|
addAll(additionalCompilerOptions)
|
||||||
|
|
||||||
|
libraries.files.forEach { library ->
|
||||||
|
library.parent?.let { addArg("-r", it) }
|
||||||
|
addArg("-l", library.nameWithoutExtension)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Filter only kt files?
|
||||||
|
addAll(sources.files.map { it.absolutePath })
|
||||||
|
}
|
||||||
|
|
||||||
|
KonanCompilerRunner(project).run(args)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
open class KonanCompilerDownloadTask : DefaultTask() {
|
||||||
|
|
||||||
|
internal companion object {
|
||||||
|
|
||||||
|
val simpleOsName: String = HostManager.simpleOsName()
|
||||||
|
|
||||||
|
val compilerDirectory: File
|
||||||
|
get() = DependencyDirectories.localKonanDir.resolve("kotlin-native-$simpleOsName-$compilerVersion")
|
||||||
|
|
||||||
|
// TODO: Support project property for Kotlin/Native compiler version
|
||||||
|
val compilerVersion: KonanVersion = KonanVersionImpl(MetaVersion.RELEASE, 0, 8, 2)
|
||||||
|
|
||||||
|
internal const val BASE_DOWNLOAD_URL = "https://download.jetbrains.com/kotlin/native/builds"
|
||||||
|
const val KONAN_DOWNLOAD_TASK_NAME = "checkNativeCompiler"
|
||||||
|
}
|
||||||
|
|
||||||
|
private val useZip = HostManager.hostIsMingw
|
||||||
|
|
||||||
|
private val archiveExtension
|
||||||
|
get() = if (useZip) {
|
||||||
|
"zip"
|
||||||
|
} else {
|
||||||
|
"tar.gz"
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun archiveFileTree(archive: File): FileTree =
|
||||||
|
if (useZip) {
|
||||||
|
project.zipTree(archive)
|
||||||
|
} else {
|
||||||
|
project.tarTree(archive)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setupRepo(url: String): ArtifactRepository {
|
||||||
|
return project.repositories.ivy { repo ->
|
||||||
|
repo.setUrl(url)
|
||||||
|
repo.layout("pattern") {
|
||||||
|
val layout = it as IvyPatternRepositoryLayout
|
||||||
|
layout.artifact("[artifact]-[revision].[ext]")
|
||||||
|
}
|
||||||
|
repo.metadataSources {
|
||||||
|
it.artifact()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun removeRepo(repo: ArtifactRepository) {
|
||||||
|
project.repositories.remove(repo)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun downloadAndExtract() {
|
||||||
|
val versionString = compilerVersion.toString()
|
||||||
|
|
||||||
|
val url = buildString {
|
||||||
|
append("$BASE_DOWNLOAD_URL/")
|
||||||
|
append(if (compilerVersion.meta == MetaVersion.DEV) "dev/" else "releases/")
|
||||||
|
append("$versionString/")
|
||||||
|
append(simpleOsName)
|
||||||
|
}
|
||||||
|
|
||||||
|
val repo = setupRepo(url)
|
||||||
|
|
||||||
|
val compilerDependency = project.dependencies.create(
|
||||||
|
mapOf(
|
||||||
|
"name" to "kotlin-native-$simpleOsName",
|
||||||
|
"version" to versionString,
|
||||||
|
"ext" to archiveExtension
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
val configuration = project.configurations.detachedConfiguration(compilerDependency)
|
||||||
|
val archive = configuration.files.single()
|
||||||
|
|
||||||
|
logger.info("Use Kotlin/Native compiler archive: ${archive.absolutePath}")
|
||||||
|
logger.lifecycle("Unpack Kotlin/Native compiler (version $versionString)...")
|
||||||
|
project.copy {
|
||||||
|
it.from(archiveFileTree(archive))
|
||||||
|
it.into(DependencyDirectories.localKonanDir)
|
||||||
|
}
|
||||||
|
|
||||||
|
removeRepo(repo)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@TaskAction
|
||||||
|
fun checkCompiler() {
|
||||||
|
if (!project.hasProperty(KotlinNativeProjectProperty.DOWNLOAD_COMPILER)) {
|
||||||
|
val konanHome = project.getProperty(KotlinNativeProjectProperty.KONAN_HOME)
|
||||||
|
logger.info("Use a user-defined compiler path: $konanHome")
|
||||||
|
} else {
|
||||||
|
if (!compilerDirectory.exists()) {
|
||||||
|
downloadAndExtract()
|
||||||
|
}
|
||||||
|
logger.info("Use Kotlin/Native distribution: $compilerDirectory")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -49,6 +49,7 @@ include ":kotlin-build-common",
|
|||||||
":js:js.translator",
|
":js:js.translator",
|
||||||
":js:js.dce",
|
":js:js.dce",
|
||||||
":js:js.tests",
|
":js:js.tests",
|
||||||
|
":konan:konan-utils",
|
||||||
":jps-plugin",
|
":jps-plugin",
|
||||||
":kotlin-jps-plugin",
|
":kotlin-jps-plugin",
|
||||||
":core:descriptors",
|
":core:descriptors",
|
||||||
@@ -231,6 +232,7 @@ project(':compiler:ir.psi2ir').projectDir = "$rootDir/compiler/ir/ir.psi2ir" as
|
|||||||
project(':compiler:ir.ir2cfg').projectDir = "$rootDir/compiler/ir/ir.ir2cfg" as File
|
project(':compiler:ir.ir2cfg').projectDir = "$rootDir/compiler/ir/ir.ir2cfg" as File
|
||||||
project(':compiler:ir.backend.common').projectDir = "$rootDir/compiler/ir/backend.common" as File
|
project(':compiler:ir.backend.common').projectDir = "$rootDir/compiler/ir/backend.common" as File
|
||||||
project(':compiler:backend.js').projectDir = "$rootDir/compiler/ir/backend.js" as File
|
project(':compiler:backend.js').projectDir = "$rootDir/compiler/ir/backend.js" as File
|
||||||
|
project(':konan:konan-utils').projectDir = "$rootDir/konan/utils" as File
|
||||||
project(':kotlin-jps-plugin').projectDir = "$rootDir/prepare/jps-plugin" as File
|
project(':kotlin-jps-plugin').projectDir = "$rootDir/prepare/jps-plugin" as File
|
||||||
project(':idea:idea-android-output-parser').projectDir = "$rootDir/idea/idea-android/idea-android-output-parser" as File
|
project(':idea:idea-android-output-parser').projectDir = "$rootDir/idea/idea-android/idea-android-output-parser" as File
|
||||||
project(':plugins:android-extensions-compiler').projectDir = "$rootDir/plugins/android-extensions/android-extensions-compiler" as File
|
project(':plugins:android-extensions-compiler').projectDir = "$rootDir/plugins/android-extensions/android-extensions-compiler" as File
|
||||||
|
|||||||
Reference in New Issue
Block a user