Different extensions (and KonanTarget communalization). (#665)

This commit is contained in:
alexander-gorshenev
2017-06-19 12:45:57 +03:00
committed by Nikolay Igotti
parent c57ad51fc7
commit d3c24bb387
51 changed files with 419 additions and 245 deletions
+1 -1
View File
@@ -88,7 +88,7 @@ cinterop execution (see the `dumpParameters` task in `samles/csvparser/build.gra
// Directory for output artifact (default: build/konan/bin/<artifactName>). // Directory for output artifact (default: build/konan/bin/<artifactName>).
outputDir 'path/to/output/dir' outputDir 'path/to/output/dir'
// *.kt.bc library for linking. // *.klib library for linking.
library project.file('path/to/library') library project.file('path/to/library')
// naitve library for linking. // naitve library for linking.
+6 -6
View File
@@ -24,12 +24,12 @@ Build the dependencies and the compiler (see `README.md`).
Prepare stubs for the system sockets library: Prepare stubs for the system sockets library:
cd samples/socket cd samples/socket
../../dist/bin/cinterop -def sockets.def -o sockets.kt.bc ../../dist/bin/cinterop -def sockets.def -o sockets
Compile the echo server: Compile the echo server:
../../dist/bin/kotlinc EchoServer.kt -library sockets.kt.bc \ ../../dist/bin/kotlinc EchoServer.kt -library sockets \
-o EchoServer.kexe -o EchoServer
This whole process is automated in `build.sh` script, which also support cross-compilation This whole process is automated in `build.sh` script, which also support cross-compilation
to supported cross-targets with `TARGET=raspberrypi ./build.sh` (`cross_dist` target must to supported cross-targets with `TARGET=raspberrypi ./build.sh` (`cross_dist` target must
@@ -57,10 +57,10 @@ Structurally it's a simple property file, looking like this:
Then run `cinterop` tool with something like (note that for host libraries not included Then run `cinterop` tool with something like (note that for host libraries not included
in sysroot search paths for headers may be needed): in sysroot search paths for headers may be needed):
cinterop -def zlib.def -copt -I/opt/local/include -o zlib.kt.bc cinterop -def zlib.def -copt -I/opt/local/include -o zlib
This command will produce `zlib.kt.bc` compiled library and This command will produce `zlib.klib` compiled library and
`zlib.kt.bc-build/kotlin` directory containing Kotlin source code for the library. `zlib-build/kotlin` directory containing Kotlin source code for the library.
If behavior for certain platform shall be modified, one may use format like If behavior for certain platform shall be modified, one may use format like
`compilerOpts.osx` or `compilerOpts.linux` to provide platform-specific values `compilerOpts.osx` or `compilerOpts.linux` to provide platform-specific values
+1 -1
View File
@@ -49,7 +49,7 @@ See the samples coming with the distribution.
Download _Kotlin/Native_ distribution and unpack it. You can run command line compiler with Download _Kotlin/Native_ distribution and unpack it. You can run command line compiler with
bin/kotlinc <some_file>.kt <dir_with_kt_files> -o <executable>.kexe bin/kotlinc <some_file>.kt <dir_with_kt_files> -o <program_name>
During the first run it will download all the external dependencies, such as LLVM. During the first run it will download all the external dependencies, such as LLVM.
+5 -1
View File
@@ -57,7 +57,10 @@ sourceSets {
srcDir 'compiler/ir/backend.native/src/' srcDir 'compiler/ir/backend.native/src/'
srcDir 'build/renamed/source/proto/compiler/java' srcDir 'build/renamed/source/proto/compiler/java'
} }
kotlin.srcDir 'compiler/ir/backend.native/src/' kotlin {
srcDir 'compiler/ir/backend.native/src/'
srcDir "${rootProject.projectDir}/shared/src/main/kotlin"
}
} }
cli_bc { cli_bc {
java.srcDir 'cli.bc/src' java.srcDir 'cli.bc/src'
@@ -130,6 +133,7 @@ dependencies {
compilerCompile kotlinCompilerModule compilerCompile kotlinCompilerModule
compilerCompile kotlinNativeInterop['llvm'].configuration compilerCompile kotlinNativeInterop['llvm'].configuration
compilerCompile kotlinNativeInterop['hash'].configuration compilerCompile kotlinNativeInterop['hash'].configuration
compilerCompile project(':shared')
cli_bcCompile "org.jetbrains.kotlin:kotlin-runtime:$kotlin_version" cli_bcCompile "org.jetbrains.kotlin:kotlin-runtime:$kotlin_version"
cli_bcCompile sourceSets.compiler.output cli_bcCompile sourceSets.compiler.output
@@ -18,10 +18,7 @@ package org.jetbrains.kotlin.cli.bc
import com.intellij.openapi.Disposable import com.intellij.openapi.Disposable
import org.jetbrains.kotlin.backend.konan.* import org.jetbrains.kotlin.backend.konan.*
import org.jetbrains.kotlin.backend.konan.CompilerOutputKind.*
import org.jetbrains.kotlin.backend.konan.util.profile import org.jetbrains.kotlin.backend.konan.util.profile
import org.jetbrains.kotlin.backend.konan.util.suffixIfNot
import org.jetbrains.kotlin.backend.konan.util.removeSuffixIfPresent
import org.jetbrains.kotlin.cli.common.CLICompiler import org.jetbrains.kotlin.cli.common.CLICompiler
import org.jetbrains.kotlin.cli.common.CLITool import org.jetbrains.kotlin.cli.common.CLITool
import org.jetbrains.kotlin.cli.common.ExitCode import org.jetbrains.kotlin.cli.common.ExitCode
@@ -31,15 +28,16 @@ import org.jetbrains.kotlin.config.CommonConfigurationKeys
import org.jetbrains.kotlin.config.CompilerConfiguration import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.config.Services import org.jetbrains.kotlin.config.Services
import org.jetbrains.kotlin.config.addKotlinSourceRoots import org.jetbrains.kotlin.config.addKotlinSourceRoots
import org.jetbrains.kotlin.konan.target.*
import java.util.* import java.util.*
import kotlin.reflect.KFunction import kotlin.reflect.KFunction
// TODO: Don't use reflection? // TODO: Don't use reflection?
private fun maybeExecuteHelper(configuration: CompilerConfiguration) { private fun maybeExecuteHelper(targetName: String) {
try { try {
val kClass = Class.forName("org.jetbrains.kotlin.konan.Helper0").kotlin val kClass = Class.forName("org.jetbrains.kotlin.konan.Helper0").kotlin
val ctor = kClass.constructors.single() as KFunction<Runnable> val ctor = kClass.constructors.single() as KFunction<Runnable>
val distribution = Distribution(configuration) val distribution = Distribution(TargetManager(targetName))
val result = ctor.call( val result = ctor.call(
distribution.dependenciesDir, distribution.dependenciesDir,
distribution.properties.properties, distribution.properties.properties,
@@ -109,18 +107,10 @@ class K2Native : CLICompiler<K2NativeCompilerArguments>() {
// TODO: Collect all the explicit file names into an object // TODO: Collect all the explicit file names into an object
// and teach the compiler to work with temporaries and -save-temps. // and teach the compiler to work with temporaries and -save-temps.
arguments.outputName ?.let { put(OUTPUT, it) }
val outputKind = CompilerOutputKind.valueOf( val outputKind = CompilerOutputKind.valueOf(
(arguments.produce ?: "program").toUpperCase()) (arguments.produce ?: "program").toUpperCase())
put(PRODUCE, outputKind) put(PRODUCE, outputKind)
val suffix = outputKind.suffix
val output = arguments.outputFile?.removeSuffixIfPresent(suffix)
?: outputKind.name.toLowerCase()
put(OUTPUT_NAME, output)
put(OUTPUT_FILE, output.suffixIfNot(outputKind.suffix))
// This is a decision we could change
put(CommonConfigurationKeys.MODULE_NAME, output)
put(ABI_VERSION, 1) put(ABI_VERSION, 1)
arguments.mainPackage ?.let{ put(ENTRY, it) } arguments.mainPackage ?.let{ put(ENTRY, it) }
@@ -154,7 +144,7 @@ class K2Native : CLICompiler<K2NativeCompilerArguments>() {
} }
} }
maybeExecuteHelper(configuration) maybeExecuteHelper(arguments.target ?: "host")
} }
override fun createArguments(): K2NativeCompilerArguments { override fun createArguments(): K2NativeCompilerArguments {
@@ -54,13 +54,13 @@ class K2NativeCompilerArguments : CommonCompilerArguments() {
@field:Argument(value = "-opt", description = "Enable optimizations during compilation") @field:Argument(value = "-opt", description = "Enable optimizations during compilation")
@JvmField var optimization: Boolean = false @JvmField var optimization: Boolean = false
@field:Argument(value = "-output", shortName = "-o", valueDescription = "<path>", description = "Output file path") @field:Argument(value = "-output", shortName = "-o", valueDescription = "<name>", description = "Output name")
@JvmField var outputFile: String? = null @JvmField var outputName: String? = null
@field:Argument(value = "-entry", shortName = "-e", valueDescription = "<name>", description = "Qualified entry point name") @field:Argument(value = "-entry", shortName = "-e", valueDescription = "<name>", description = "Qualified entry point name")
@JvmField var mainPackage: String? = null @JvmField var mainPackage: String? = null
@field:Argument(value = "-produce", shortName = "-p", valueDescription = "{program|library|bitcode}", description = "Produce either .kexe, .klib or a .bc file.") @field:Argument(value = "-produce", shortName = "-p", valueDescription = "{program|library|bitcode}", description = "Specify output file kind")
@JvmField var produce: String? = null @JvmField var produce: String? = null
@field:Argument(value = "-properties", valueDescription = "<path>", description = "Override standard 'konan.properties' location") @field:Argument(value = "-properties", valueDescription = "<path>", description = "Override standard 'konan.properties' location")
@@ -16,16 +16,17 @@
package org.jetbrains.kotlin.backend.konan package org.jetbrains.kotlin.backend.konan
import org.jetbrains.kotlin.config.CompilerConfiguration
import java.io.File import java.io.File
import org.jetbrains.kotlin.konan.target.*
class Distribution(val config: CompilerConfiguration) { class Distribution(val targetManager: TargetManager,
val propertyFileOverride: String? = null,
val runtimeFileOverride: String? = null) {
val targetManager = TargetManager(config) val targetName = targetManager.targetName
val target = targetManager.currentName val hostSuffix = targetManager.hostSuffix
val hostSuffix = targetManager.hostSuffix() val hostTargetSuffix = targetManager.hostTargetSuffix
val hostTargetSuffix = targetManager.hostTargetSuffix() val targetSuffix = targetManager.targetSuffix
val targetSuffix = targetManager.targetSuffix()
private fun findUserHome() = File(System.getProperty("user.home")).absolutePath private fun findUserHome() = File(System.getProperty("user.home")).absolutePath
val userHome = findUserHome() val userHome = findUserHome()
@@ -38,8 +39,7 @@ class Distribution(val config: CompilerConfiguration) {
} }
val konanHome = findKonanHome() val konanHome = findKonanHome()
val propertyFile = config.get(KonanConfigKeys.PROPERTY_FILE) val propertyFile = propertyFileOverride ?: "$konanHome/konan/konan.properties"
?: "$konanHome/konan/konan.properties"
val properties = KonanProperties(propertyFile) val properties = KonanProperties(propertyFile)
val klib = "$konanHome/klib" val klib = "$konanHome/klib"
@@ -48,8 +48,7 @@ class Distribution(val config: CompilerConfiguration) {
val dependencies = properties.propertyList("dependencies.$hostTargetSuffix") val dependencies = properties.propertyList("dependencies.$hostTargetSuffix")
val stdlib = "$klib/stdlib" val stdlib = "$klib/stdlib"
val runtime = config.get(KonanConfigKeys.RUNTIME_FILE) val runtime = runtimeFileOverride ?: "$stdlib/targets/${targetName}/native/runtime.bc"
?: "$stdlib/targets/$target/native/runtime.bc"
val llvmHome = "$dependenciesDir/${properties.propertyString("llvmHome.$hostSuffix")}" val llvmHome = "$dependenciesDir/${properties.propertyString("llvmHome.$hostSuffix")}"
val hostSysRoot = "$dependenciesDir/${properties.propertyString("targetSysRoot.$hostSuffix")}" val hostSysRoot = "$dependenciesDir/${properties.propertyString("targetSysRoot.$hostSuffix")}"
@@ -21,18 +21,39 @@ import org.jetbrains.kotlin.backend.konan.library.KonanLibraryReader
import org.jetbrains.kotlin.backend.konan.library.SplitLibraryReader import org.jetbrains.kotlin.backend.konan.library.SplitLibraryReader
import org.jetbrains.kotlin.backend.konan.library.KonanLibrarySearchPathResolver import org.jetbrains.kotlin.backend.konan.library.KonanLibrarySearchPathResolver
import org.jetbrains.kotlin.backend.konan.util.profile import org.jetbrains.kotlin.backend.konan.util.profile
import org.jetbrains.kotlin.backend.konan.util.suffixIfNot
import org.jetbrains.kotlin.backend.konan.util.removeSuffixIfPresent
import org.jetbrains.kotlin.config.CommonConfigurationKeys import org.jetbrains.kotlin.config.CommonConfigurationKeys
import org.jetbrains.kotlin.config.CompilerConfiguration import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
import org.jetbrains.kotlin.backend.konan.util.File import org.jetbrains.kotlin.backend.konan.util.File
import org.jetbrains.kotlin.konan.target.*
import org.jetbrains.kotlin.konan.target.TargetManager.*
import org.jetbrains.kotlin.konan.target.CompilerOutputKind.*
class KonanConfig(val project: Project, val configuration: CompilerConfiguration) { class KonanConfig(val project: Project, val configuration: CompilerConfiguration) {
val moduleId: String internal val targetManager = TargetManager(
get() = configuration.getNotNull(CommonConfigurationKeys.MODULE_NAME) configuration.get(KonanConfigKeys.TARGET))
internal val targetManager = TargetManager(configuration) init {
internal val distribution = Distribution(configuration) val target = targetManager.target
if (!target.enabled) {
error("Target $target is not available on the ${TargetManager.host} host")
}
}
internal val distribution = Distribution(targetManager,
configuration.get(KonanConfigKeys.PROPERTY_FILE),
configuration.get(KonanConfigKeys.RUNTIME_FILE))
private val produce = configuration.get(KonanConfigKeys.PRODUCE)!!
private val suffix = produce.suffix(targetManager.target)
val outputName = configuration.get(KonanConfigKeys.OUTPUT)?.removeSuffixIfPresent(suffix) ?: produce.name.toLowerCase()
val outputFile = outputName.suffixIfNot(produce.suffix(targetManager.target))
val moduleId: String
// This is a decision we could change
get() = outputName
private val libraryNames: List<String> private val libraryNames: List<String>
get() { get() {
@@ -51,7 +72,7 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration
internal val libraries: List<KonanLibraryReader> by lazy { internal val libraries: List<KonanLibraryReader> by lazy {
val currentAbiVersion = configuration.get(KonanConfigKeys.ABI_VERSION)!! val currentAbiVersion = configuration.get(KonanConfigKeys.ABI_VERSION)!!
val target = targetManager.currentName val target = targetManager.targetName
// Here we have chosen a particular KonanLibraryReader implementation. // Here we have chosen a particular KonanLibraryReader implementation.
librariesFound.map{it -> SplitLibraryReader(it, currentAbiVersion, target)} librariesFound.map{it -> SplitLibraryReader(it, currentAbiVersion, target)}
} }
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.backend.konan
import org.jetbrains.kotlin.config.CompilerConfigurationKey import org.jetbrains.kotlin.config.CompilerConfigurationKey
import org.jetbrains.kotlin.serialization.js.ModuleKind import org.jetbrains.kotlin.serialization.js.ModuleKind
import org.jetbrains.kotlin.konan.target.CompilerOutputKind
class KonanConfigKeys { class KonanConfigKeys {
companion object { companion object {
@@ -56,9 +57,7 @@ class KonanConfigKeys {
= CompilerConfigurationKey.create("don't the library into a klib file") = CompilerConfigurationKey.create("don't the library into a klib file")
val OPTIMIZATION: CompilerConfigurationKey<Boolean> val OPTIMIZATION: CompilerConfigurationKey<Boolean>
= CompilerConfigurationKey.create("optimized compilation") = CompilerConfigurationKey.create("optimized compilation")
val OUTPUT_FILE: CompilerConfigurationKey<String> val OUTPUT: CompilerConfigurationKey<String>
= CompilerConfigurationKey.create("final executable file path")
val OUTPUT_NAME: CompilerConfigurationKey<String>
= CompilerConfigurationKey.create("program or library name") = CompilerConfigurationKey.create("program or library name")
val PRINT_BITCODE: CompilerConfigurationKey<Boolean> val PRINT_BITCODE: CompilerConfigurationKey<Boolean>
= CompilerConfigurationKey.create("print bitcode") = CompilerConfigurationKey.create("print bitcode")
@@ -95,8 +94,3 @@ class KonanConfigKeys {
} }
} }
enum class CompilerOutputKind(val suffix: String) {
PROGRAM(".kexe"),
LIBRARY(".klib"),
BITCODE(".bc")
}
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.backend.konan.ir.DeserializerDriver
import org.jetbrains.kotlin.backend.konan.ir.KonanSymbols import org.jetbrains.kotlin.backend.konan.ir.KonanSymbols
import org.jetbrains.kotlin.backend.konan.ir.ModuleIndex import org.jetbrains.kotlin.backend.konan.ir.ModuleIndex
import org.jetbrains.kotlin.backend.konan.llvm.emitLLVM import org.jetbrains.kotlin.backend.konan.llvm.emitLLVM
import org.jetbrains.kotlin.backend.konan.llvm.produceOutput
import org.jetbrains.kotlin.backend.konan.serialization.KonanSerializationUtil import org.jetbrains.kotlin.backend.konan.serialization.KonanSerializationUtil
import org.jetbrains.kotlin.backend.konan.serialization.markBackingFields import org.jetbrains.kotlin.backend.konan.serialization.markBackingFields
import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport
@@ -108,6 +109,7 @@ public fun runTopLevelPhases(konanConfig: KonanConfig, environment: KotlinCoreEn
} }
phaser.phase(KonanPhase.BITCODE) { phaser.phase(KonanPhase.BITCODE) {
emitLLVM(context) emitLLVM(context)
produceOutput(context)
} }
// We always verify bitcode to prevent hard to debug bugs. // We always verify bitcode to prevent hard to debug bugs.
context.verifyBitCode() context.verifyBitCode()
@@ -17,6 +17,7 @@
package org.jetbrains.kotlin.backend.konan package org.jetbrains.kotlin.backend.konan
import org.jetbrains.kotlin.backend.konan.util.* import org.jetbrains.kotlin.backend.konan.util.*
import org.jetbrains.kotlin.konan.target.CompilerOutputKind
enum class KonanPhase(val description: String, enum class KonanPhase(val description: String,
vararg prerequisite: KonanPhase, vararg prerequisite: KonanPhase,
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.backend.konan
import java.io.File import java.io.File
import java.lang.ProcessBuilder import java.lang.ProcessBuilder
import java.lang.ProcessBuilder.Redirect import java.lang.ProcessBuilder.Redirect
import org.jetbrains.kotlin.konan.target.*
typealias BitcodeFile = String typealias BitcodeFile = String
typealias ObjectFile = String typealias ObjectFile = String
@@ -186,7 +187,7 @@ internal class LinkStage(val context: Context) {
private val distribution = context.config.distribution private val distribution = context.config.distribution
val platform = when (context.config.targetManager.current) { val platform = when (context.config.targetManager.target) {
KonanTarget.LINUX, KonanTarget.RASPBERRYPI -> KonanTarget.LINUX, KonanTarget.RASPBERRYPI ->
LinuxBasedPlatform(distribution) LinuxBasedPlatform(distribution)
KonanTarget.MACBOOK, KonanTarget.IPHONE, KonanTarget.IPHONE_SIM -> KonanTarget.MACBOOK, KonanTarget.IPHONE, KonanTarget.IPHONE_SIM ->
@@ -196,7 +197,7 @@ internal class LinkStage(val context: Context) {
KonanTarget.MINGW -> KonanTarget.MINGW ->
MingwPlatform(distribution) MingwPlatform(distribution)
else -> else ->
error("Unexpected target platform: ${context.config.targetManager.current}") error("Unexpected target platform: ${context.config.targetManager.target}")
} }
val optimize = config.get(KonanConfigKeys.OPTIMIZATION) ?: false val optimize = config.get(KonanConfigKeys.OPTIMIZATION) ?: false
@@ -251,7 +252,7 @@ internal class LinkStage(val context: Context) {
get() = if (nomain) emptyList() else platform.entrySelector get() = if (nomain) emptyList() else platform.entrySelector
fun link(objectFiles: List<ObjectFile>): ExecutableFile { fun link(objectFiles: List<ObjectFile>): ExecutableFile {
val executable = config.get(KonanConfigKeys.OUTPUT_FILE)!! val executable = context.config.outputFile
val linkCommand = platform.linkCommand(objectFiles, executable, optimize, config.getBoolean(KonanConfigKeys.DEBUG)) + val linkCommand = platform.linkCommand(objectFiles, executable, optimize, config.getBoolean(KonanConfigKeys.DEBUG)) +
distribution.libffi + distribution.libffi +
asLinkerArgs(config.getNotNull(KonanConfigKeys.LINKER_ARGS)) + asLinkerArgs(config.getNotNull(KonanConfigKeys.LINKER_ARGS)) +
@@ -19,7 +19,6 @@ package org.jetbrains.kotlin.backend.konan.library
import llvm.LLVMModuleRef import llvm.LLVMModuleRef
import llvm.LLVMWriteBitcodeToFile import llvm.LLVMWriteBitcodeToFile
import org.jetbrains.kotlin.backend.konan.KonanConfigKeys import org.jetbrains.kotlin.backend.konan.KonanConfigKeys
import org.jetbrains.kotlin.backend.konan.TargetManager
import org.jetbrains.kotlin.backend.konan.serialization.Base64 import org.jetbrains.kotlin.backend.konan.serialization.Base64
import org.jetbrains.kotlin.backend.konan.serialization.deserializeModule import org.jetbrains.kotlin.backend.konan.serialization.deserializeModule
import org.jetbrains.kotlin.backend.konan.util.File import org.jetbrains.kotlin.backend.konan.util.File
@@ -20,7 +20,7 @@ package org.jetbrains.kotlin.backend.konan.llvm
import kotlinx.cinterop.* import kotlinx.cinterop.*
import llvm.* import llvm.*
import org.jetbrains.kotlin.backend.konan.Context import org.jetbrains.kotlin.backend.konan.Context
import org.jetbrains.kotlin.backend.konan.KonanTarget import org.jetbrains.kotlin.konan.target.KonanTarget
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor
@@ -154,7 +154,7 @@ internal class CodeGenerator(override val context: Context) : ContextUtils {
get() { get() {
return slotCount > 1 || localAllocs > 0 || return slotCount > 1 || localAllocs > 0 ||
// Prevent empty cleanup on mingw to workaround LLVM bug: // Prevent empty cleanup on mingw to workaround LLVM bug:
context.config.targetManager.current == KonanTarget.MINGW context.config.targetManager.target == KonanTarget.MINGW
} }
private fun releaseVars() { private fun releaseVars() {
@@ -19,7 +19,7 @@ package org.jetbrains.kotlin.backend.konan.llvm
import kotlinx.cinterop.* import kotlinx.cinterop.*
import llvm.* import llvm.*
import org.jetbrains.kotlin.backend.konan.Context import org.jetbrains.kotlin.backend.konan.Context
import org.jetbrains.kotlin.backend.konan.KonanTarget import org.jetbrains.kotlin.konan.target.KonanTarget
import org.jetbrains.kotlin.backend.konan.hash.GlobalHash import org.jetbrains.kotlin.backend.konan.hash.GlobalHash
import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
@@ -259,7 +259,7 @@ internal class Llvm(val context: Context, val llvmModule: LLVMModuleRef) {
val throwExceptionFunction = importRtFunction("ThrowException") val throwExceptionFunction = importRtFunction("ThrowException")
val appendToInitalizersTail = importRtFunction("AppendToInitializersTail") val appendToInitalizersTail = importRtFunction("AppendToInitializersTail")
private val personalityFunctionName = when (context.config.targetManager.current) { private val personalityFunctionName = when (context.config.targetManager.target) {
KonanTarget.MINGW -> "__gxx_personality_seh0" KonanTarget.MINGW -> "__gxx_personality_seh0"
else -> "__gxx_personality_v0" else -> "__gxx_personality_v0"
} }
@@ -22,7 +22,6 @@ import llvm.*
import org.jetbrains.kotlin.backend.konan.Context import org.jetbrains.kotlin.backend.konan.Context
import org.jetbrains.kotlin.backend.konan.KonanConfigKeys import org.jetbrains.kotlin.backend.konan.KonanConfigKeys
import org.jetbrains.kotlin.backend.konan.KonanVersion import org.jetbrains.kotlin.backend.konan.KonanVersion
import org.jetbrains.kotlin.backend.konan.TargetManager
import org.jetbrains.kotlin.backend.konan.util.File import org.jetbrains.kotlin.backend.konan.util.File
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor
@@ -103,7 +102,7 @@ internal fun String?.toFileAndFolder():FileAndFolder {
internal fun generateDebugInfoHeader(context: Context) { internal fun generateDebugInfoHeader(context: Context) {
if (context.shouldContainDebugInfo()) { if (context.shouldContainDebugInfo()) {
val path = context.config.configuration.get(KonanConfigKeys.OUTPUT_FILE)!! val path = context.config.outputFile
.toFileAndFolder() .toFileAndFolder()
context.debugInfo.module = DICreateModule( context.debugInfo.module = DICreateModule(
@@ -16,13 +16,13 @@
package org.jetbrains.kotlin.backend.konan.llvm package org.jetbrains.kotlin.backend.konan.llvm
import org.jetbrains.kotlin.backend.konan.CompilerOutputKind
import org.jetbrains.kotlin.backend.konan.Context import org.jetbrains.kotlin.backend.konan.Context
import org.jetbrains.kotlin.backend.konan.KonanConfigKeys import org.jetbrains.kotlin.backend.konan.KonanConfigKeys
import org.jetbrains.kotlin.backend.konan.descriptors.isArray import org.jetbrains.kotlin.backend.konan.descriptors.isArray
import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.konan.target.CompilerOutputKind
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
@@ -23,7 +23,6 @@ import org.jetbrains.kotlin.backend.common.descriptors.isSuspend
import org.jetbrains.kotlin.backend.common.ir.ir2string import org.jetbrains.kotlin.backend.common.ir.ir2string
import org.jetbrains.kotlin.backend.konan.Context import org.jetbrains.kotlin.backend.konan.Context
import org.jetbrains.kotlin.backend.konan.KonanConfigKeys import org.jetbrains.kotlin.backend.konan.KonanConfigKeys
import org.jetbrains.kotlin.backend.konan.CompilerOutputKind
import org.jetbrains.kotlin.backend.konan.KonanPhase import org.jetbrains.kotlin.backend.konan.KonanPhase
import org.jetbrains.kotlin.backend.konan.library.LinkData import org.jetbrains.kotlin.backend.konan.library.LinkData
import org.jetbrains.kotlin.backend.konan.PhaseManager import org.jetbrains.kotlin.backend.konan.PhaseManager
@@ -43,6 +42,7 @@ import org.jetbrains.kotlin.ir.util.getArguments
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
import org.jetbrains.kotlin.ir.visitors.acceptVoid import org.jetbrains.kotlin.ir.visitors.acceptVoid
import org.jetbrains.kotlin.konan.target.CompilerOutputKind
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
@@ -85,65 +85,65 @@ internal fun emitLLVM(context: Context) {
if (context.shouldContainDebugInfo()) { if (context.shouldContainDebugInfo()) {
DIFinalize(context.debugInfo.builder) DIFinalize(context.debugInfo.builder)
} }
when (config.get(KonanConfigKeys.PRODUCE)) {
CompilerOutputKind.PROGRAM -> {
val program = config.get(KonanConfigKeys.OUTPUT_NAME)!!
val output = "${program}.kt.bc"
context.bitcodeFileName = output
phaser.phase(KonanPhase.BITCODE_LINKER) {
for (library in context.config.nativeLibraries) {
val libraryModule = parseBitcodeFile(library)
val failed = LLVMLinkModules2(llvmModule, libraryModule)
if (failed != 0) {
throw Error("failed to link $library") // TODO: retrieve error message from LLVM.
}
}
}
LLVMWriteBitcodeToFile(llvmModule, output)
}
CompilerOutputKind.LIBRARY -> {
val libraryName = config.get(KonanConfigKeys.OUTPUT_NAME)!!
val nopack = config.getBoolean(KonanConfigKeys.NOPACK)
val targetName = context.config.targetManager.currentName
val library = buildLibrary(
phaser,
context.config.nativeLibraries,
context.serializedLinkData!!,
targetName,
libraryName,
llvmModule,
nopack)
context.library = library
context.bitcodeFileName = library.mainBitcodeFileName
}
CompilerOutputKind.BITCODE -> {
val output = config.get(KonanConfigKeys.OUTPUT_FILE)!!
context.bitcodeFileName = output
LLVMWriteBitcodeToFile(llvmModule, output)
}
}
} }
internal fun buildLibrary(phaser: PhaseManager, natives: List<String>, linkData: LinkData, target: String, output: String, llvmModule: LLVMModuleRef, nopack: Boolean): KonanLibraryWriter { internal fun produceOutput(context: Context) {
val llvmModule = context.llvmModule!!
val config = context.config.configuration
when (config.get(KonanConfigKeys.PRODUCE)) {
CompilerOutputKind.PROGRAM -> {
val program = context.config.outputName
val output = "${program}.kt.bc"
context.bitcodeFileName = output
PhaseManager(context).phase(KonanPhase.BITCODE_LINKER) {
for (library in context.config.nativeLibraries) {
val libraryModule = parseBitcodeFile(library)
val failed = LLVMLinkModules2(llvmModule, libraryModule)
if (failed != 0) {
throw Error("failed to link $library") // TODO: retrieve error message from LLVM.
}
}
}
LLVMWriteBitcodeToFile(llvmModule, output)
}
CompilerOutputKind.LIBRARY -> {
val libraryName = context.config.outputName
val nopack = config.getBoolean(KonanConfigKeys.NOPACK)
val targetName = context.config.targetManager.targetName
val library = buildLibrary(
context.config.nativeLibraries,
context.serializedLinkData!!,
targetName,
libraryName,
llvmModule,
nopack)
context.library = library
context.bitcodeFileName = library.mainBitcodeFileName
}
CompilerOutputKind.BITCODE -> {
val output = context.config.outputFile
context.bitcodeFileName = output
LLVMWriteBitcodeToFile(llvmModule, output)
}
}
}
internal fun buildLibrary(natives: List<String>, linkData: LinkData, target: String, output: String, llvmModule: LLVMModuleRef, nopack: Boolean): KonanLibraryWriter {
// TODO: May be we need a factory? // TODO: May be we need a factory?
//val library = KtBcLibraryWriter(output, llvmModule) //val library = KtBcLibraryWriter(output, llvmModule)
val library = SplitLibraryWriter(output, target, nopack) val library = SplitLibraryWriter(output, target, nopack)
library.addKotlinBitcode(llvmModule) library.addKotlinBitcode(llvmModule)
library.addLinkData(linkData) library.addLinkData(linkData)
phaser.phase(KonanPhase.BITCODE_LINKER) { natives.forEach {
natives.forEach { library.addNativeBitcode(it)
library.addNativeBitcode(it)
}
} }
library.commit() library.commit()
+1 -1
View File
@@ -1093,7 +1093,7 @@ task intrinsic(type: RunKonanTest) {
/* /*
Disabled until we extract the classes that should be Disabled until we extract the classes that should be
always present from stdlib.kt.bc into a separate binary. always present from stdlib into a separate binary.
task link(type: LinkKonanTest) { task link(type: LinkKonanTest) {
goldValue = "0\n" goldValue = "0\n"
+4 -10
View File
@@ -14,14 +14,8 @@
* limitations under the License. * limitations under the License.
*/ */
apply plugin: 'groovy' allprojects {
repositories {
repositories { mavenCentral()
mavenCentral() }
}
dependencies {
compile gradleApi()
compile localGroovy()
compile group: 'com.ullink.slack', name: 'simpleslackapi', version: '0.6.0'
} }
+34
View File
@@ -0,0 +1,34 @@
/*
* Copyright 2010-2017 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.
*/
apply plugin: 'groovy'
buildscript {
repositories {
mavenCentral()
}
}
dependencies {
compile gradleApi()
compile localGroovy()
compile group: 'com.ullink.slack', name: 'simpleslackapi', version: '0.6.0'
compile project(':shared')
}
rootProject.dependencies {
runtime project(path)
}
@@ -22,6 +22,7 @@ import org.gradle.api.tasks.JavaExec
import org.gradle.api.tasks.ParallelizableTask import org.gradle.api.tasks.ParallelizableTask
import org.gradle.api.tasks.TaskAction import org.gradle.api.tasks.TaskAction
import org.gradle.process.ExecResult import org.gradle.process.ExecResult
import org.jetbrains.kotlin.konan.target.*
abstract class KonanTest extends JavaExec { abstract class KonanTest extends JavaExec {
protected String source protected String source
@@ -208,7 +209,9 @@ fun handleExceptionContinuation(x: (Throwable) -> Unit): Continuation<Any?> = ob
void executeTest() { void executeTest() {
createOutputDirectory() createOutputDirectory()
def program = buildExePath() def program = buildExePath()
def exe = "${program}.kexe" def targetManager = new TargetManager(project.testTarget)
def suffix = targetManager.programSuffix
def exe = "$program$suffix"
compileTest(buildCompileList(), program) compileTest(buildCompileList(), program)
+18
View File
@@ -0,0 +1,18 @@
/*
* Copyright 2010-2017 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.
*/
include 'shared'
include 'plugins'
+46
View File
@@ -0,0 +1,46 @@
/*
* Copyright 2010-2017 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.
*/
buildscript {
ext {
gradleProperties = new Properties()
gradleProperties.load(new FileInputStream("$projectDir/../../gradle.properties"))
kotlin_version = gradleProperties."kotlin_version"
}
repositories {
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
apply plugin: 'kotlin'
compileKotlin {
// We reuse the source code from the Project in buildSrc.
source "$projectDir/../../shared"
}
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
}
rootProject.dependencies {
runtime project(path)
}
@@ -6,7 +6,7 @@ import java.util.Properties
import org.jetbrains.kotlin.backend.konan.library.SplitLibraryReader import org.jetbrains.kotlin.backend.konan.library.SplitLibraryReader
import org.jetbrains.kotlin.backend.konan.util.File import org.jetbrains.kotlin.backend.konan.util.File
import org.jetbrains.kotlin.backend.konan.util.copyTo import org.jetbrains.kotlin.backend.konan.util.copyTo
import org.jetbrains.kotlin.backend.konan.TargetManager import org.jetbrains.kotlin.konan.target.TargetManager
fun printUsage() { fun printUsage() {
println("Usage: klib <command> <library> <options>") println("Usage: klib <command> <library> <options>")
@@ -113,7 +113,7 @@ fun main(args: Array<String>) {
val command = Command(args) val command = Command(args)
val targetManager = TargetManager(command.options["target"]?.last()) val targetManager = TargetManager(command.options["target"]?.last())
val target = targetManager.currentName val target = targetManager.targetName
val repository = command.options["repository"]?.last() val repository = command.options["repository"]?.last()
val repositoryList = repository ?.let { listOf(it) } ?: emptyList() val repositoryList = repository ?.let { listOf(it) } ?: emptyList()
+3 -3
View File
@@ -25,9 +25,9 @@ mkdir -p $DIR/build/bin
$DIR/buildCpp.sh $DIR/buildCpp.sh
cinterop -def $DIR/src/main/c_interop/MessageChannel.def -copt "-I$DIR/src/main/cpp" -target $TARGET \ cinterop -def $DIR/src/main/c_interop/MessageChannel.def -copt "-I$DIR/src/main/cpp" -target $TARGET \
-o $DIR/build/c_interop/MessageChannel.kt.bc || exit 1 -o $DIR/build/c_interop/MessageChannel || exit 1
konanc $DIR/src/main/kotlin/Concurrent.kt -library $DIR/build/c_interop/MessageChannel.kt.bc \ konanc $DIR/src/main/kotlin/Concurrent.kt -library $DIR/build/c_interop/MessageChannel \
-nativelibrary $DIR/build/clang/MessageChannel.bc -o $DIR/build/bin/Concurrent.kexe || exit 1 -nativelibrary $DIR/build/clang/MessageChannel.bc -o $DIR/build/bin/Concurrent || exit 1
echo "Artifact path is $DIR/build/bin/Concurrent.kexe" echo "Artifact path is $DIR/build/bin/Concurrent.kexe"
+3 -3
View File
@@ -22,9 +22,9 @@ COMPILER_ARGS=${!var} # add -opt for an optimized build.
mkdir -p $DIR/build/c_interop/ mkdir -p $DIR/build/c_interop/
mkdir -p $DIR/build/bin/ mkdir -p $DIR/build/bin/
cinterop -def $DIR/src/main/c_interop/stdio.def -compilerOpts "$CFLAGS" -target $TARGET -o $DIR/build/c_interop/stdio.kt.bc || exit 1 cinterop -def $DIR/src/main/c_interop/stdio.def -compilerOpts "$CFLAGS" -target $TARGET -o $DIR/build/c_interop/stdio || exit 1
konanc $COMPILER_ARGS -target $TARGET $DIR/src/main/kotlin/CsvParser.kt -library $DIR/build/c_interop/stdio.kt.bc \ konanc $COMPILER_ARGS -target $TARGET $DIR/src/main/kotlin/CsvParser.kt -library $DIR/build/c_interop/stdio \
-o $DIR/build/bin/CsvParser.kexe || exit 1 -o $DIR/build/bin/CsvParser || exit 1
echo "Artifact path is ./build/bin/CsvParser.kexe" echo "Artifact path is ./build/bin/CsvParser.kexe"
+3 -3
View File
@@ -27,9 +27,9 @@ mkdir -p $DIR/build/c_interop/
mkdir -p $DIR/build/bin/ mkdir -p $DIR/build/bin/
cinterop -compilerOpts $CFLAGS -def $DIR/src/main/c_interop/libgit2.def -target $TARGET \ cinterop -compilerOpts $CFLAGS -def $DIR/src/main/c_interop/libgit2.def -target $TARGET \
-o $DIR/build/c_interop/libgit2.kt.bc || exit 1 -o $DIR/build/c_interop/libgit2 || exit 1
konanc -target $TARGET $DIR/src/main/kotlin -library $DIR/build/c_interop/libgit2.kt.bc -linkerOpts "$LINKER_ARGS" \ konanc -target $TARGET $DIR/src/main/kotlin -library $DIR/build/c_interop/libgit2 -linkerOpts "$LINKER_ARGS" \
-o $DIR/build/bin/GitChurn.kexe || exit 1 -o $DIR/build/bin/GitChurn || exit 1
echo "Artifact path is ./build/bin/GitChurn.kexe" echo "Artifact path is ./build/bin/GitChurn.kexe"
+3 -3
View File
@@ -31,9 +31,9 @@ echo "Generating GTK stubs, may take few mins depending on the hardware..."
cinterop -J-Xmx8g -copt $IPREFIX/atk-1.0 -compilerOpts $IPREFIX/gdk-pixbuf-2.0 -copt $IPREFIX/cairo -copt $IPREFIX/pango-1.0 \ cinterop -J-Xmx8g -copt $IPREFIX/atk-1.0 -compilerOpts $IPREFIX/gdk-pixbuf-2.0 -copt $IPREFIX/cairo -copt $IPREFIX/pango-1.0 \
-copt -I/opt/local/lib/glib-2.0/include -copt -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -copt -I/usr/local/lib/glib-2.0/include \ -copt -I/opt/local/lib/glib-2.0/include -copt -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -copt -I/usr/local/lib/glib-2.0/include \
-copt $IPREFIX/gtk-3.0 -copt $IPREFIX/glib-2.0 -def $DIR/src/main/c_interop/gtk3.def \ -copt $IPREFIX/gtk-3.0 -copt $IPREFIX/glib-2.0 -def $DIR/src/main/c_interop/gtk3.def \
-target $TARGET -o $DIR/build/c_interop/gtk3.bc || exit 1 -target $TARGET -o $DIR/build/c_interop/gtk3 || exit 1
konanc -target $TARGET $DIR/src/main/kotlin -library $DIR/build/c_interop/gtk3.bc -linkerOpts "$LINKER_ARGS" \ konanc -target $TARGET $DIR/src/main/kotlin -library $DIR/build/c_interop/gtk3.bc -linkerOpts "$LINKER_ARGS" \
-o $DIR/build/bin/Gtk3Demo.kexe || exit 1 -o $DIR/build/bin/Gtk3Demo || exit 1
echo "Artifact path is ./build/bin/Gtk3Demo.kexe" echo "Artifact path is ./build/bin/Gtk3Demo.kexe"
+3 -3
View File
@@ -27,9 +27,9 @@ mkdir -p $DIR/build/c_interop/
mkdir -p $DIR/build/bin/ mkdir -p $DIR/build/bin/
cinterop -compilerOpts "$CFLAGS" -compilerOpts -I$DIR -compilerOpts -I/usr/include -def $DIR/src/main/c_interop/libcurl.def -target $TARGET \ cinterop -compilerOpts "$CFLAGS" -compilerOpts -I$DIR -compilerOpts -I/usr/include -def $DIR/src/main/c_interop/libcurl.def -target $TARGET \
-o $DIR/build/c_interop/libcurl.bc || exit 1 -o $DIR/build/c_interop/libcurl || exit 1
konanc -target $TARGET $DIR/src/main/kotlin -library $DIR/build/c_interop/libcurl.bc -linkerOpts "$LINKER_ARGS" \ konanc -target $TARGET $DIR/src/main/kotlin -library $DIR/build/c_interop/libcurl -linkerOpts "$LINKER_ARGS" \
-o $DIR/build/bin/Curl.kexe || exit 1 -o $DIR/build/bin/Curl || exit 1
echo "Artifact path is ./build/bin/Curl.kexe" echo "Artifact path is ./build/bin/Curl.kexe"
+3 -3
View File
@@ -22,9 +22,9 @@ mkdir -p $DIR/build/c_interop/
mkdir -p $DIR/build/bin/ mkdir -p $DIR/build/bin/
cinterop -def $DIR/src/main/c_interop/sockets.def -copt "$CFLAGS" -target $TARGET \ cinterop -def $DIR/src/main/c_interop/sockets.def -copt "$CFLAGS" -target $TARGET \
-o $DIR/build/c_interop/sockets.kt.bc || exit 1 -o $DIR/build/c_interop/sockets || exit 1
konanc $COMPILER_ARGS -target $TARGET $DIR/src/main/kotlin/EchoServer.kt \ konanc $COMPILER_ARGS -target $TARGET $DIR/src/main/kotlin/EchoServer.kt \
-library $DIR/build/c_interop/sockets.kt.bc -o $DIR/build/bin/EchoServer.kexe || exit 1 -library $DIR/build/c_interop/sockets -o $DIR/build/bin/EchoServer || exit 1
echo "Artifact path is ./build/bin/EchoServer.kexe" echo "Artifact path is ./build/bin/EchoServer.kexe"
+3 -3
View File
@@ -25,9 +25,9 @@ mkdir -p $DIR/build/c_interop/
mkdir -p $DIR/build/bin/ mkdir -p $DIR/build/bin/
cinterop -def $DIR/src/main/c_interop/opengl.def -target $TARGET \ cinterop -def $DIR/src/main/c_interop/opengl.def -target $TARGET \
-o $DIR/build/c_interop/opengl.kt.bc || exit 1 -o $DIR/build/c_interop/opengl || exit 1
konanc -target $TARGET $DIR/src/main/kotlin/OpenGlTeapot.kt -library $DIR/build/c_interop/opengl.kt.bc \ konanc -target $TARGET $DIR/src/main/kotlin/OpenGlTeapot.kt -library $DIR/build/c_interop/opengl \
-linkerOpts "$LINKER_ARGS" -o $DIR/build/bin/OpenGlTeapot.kexe || exit 1 -linkerOpts "$LINKER_ARGS" -o $DIR/build/bin/OpenGlTeapot || exit 1
echo "Artifact path is ./build/bin/OpenGlTeapot.kexe" echo "Artifact path is ./build/bin/OpenGlTeapot.kexe"
+4 -4
View File
@@ -22,10 +22,10 @@ mkdir -p $DIR/build/c_interop/
mkdir -p $DIR/build/bin/ mkdir -p $DIR/build/bin/
cinterop -def $DIR/src/main/c_interop/sockets.def -copt "$CFLAGS" -target $TARGET \ cinterop -def $DIR/src/main/c_interop/sockets.def -copt "$CFLAGS" -target $TARGET \
-o $DIR/build/c_interop/sockets.kt.bc || exit 1 -o $DIR/build/c_interop/sockets || exit 1
konanc $COMPILER_ARGS -target $TARGET $DIR/src/main/kotlin/EchoServer.kt \ konanc $COMPILER_ARGS -target $TARGET $DIR/src/main/kotlin/EchoServer.kt \
-library $DIR/build/c_interop/sockets.kt.bc \ -library $DIR/build/c_interop/sockets \
-o $DIR/build/bin/EchoServer.kexe || exit 1 -o $DIR/build/bin/EchoServer || exit 1
echo "Artifact path is ./build/bin/EchoServer.kexe" echo "Artifact path is ./build/bin/EchoServer.kexe"
+3 -3
View File
@@ -30,11 +30,11 @@ mkdir -p $DIR/build/c_interop/
mkdir -p $DIR/build/bin/ mkdir -p $DIR/build/bin/
cinterop -def $DIR/src/main/c_interop/tensorflow.def -compilerOpts "$CFLAGS" -target $TARGET \ cinterop -def $DIR/src/main/c_interop/tensorflow.def -compilerOpts "$CFLAGS" -target $TARGET \
-o $DIR/build/c_interop/tensorflow.kt.bc || exit 1 -o $DIR/build/c_interop/tensorflow || exit 1
konanc $COMPILER_ARGS -target $TARGET $DIR/src/main/kotlin/HelloTensorflow.kt \ konanc $COMPILER_ARGS -target $TARGET $DIR/src/main/kotlin/HelloTensorflow.kt \
-library $DIR/build/c_interop/tensorflow.kt.bc \ -library $DIR/build/c_interop/tensorflow \
-o $DIR/build/bin/HelloTensorflow.kexe \ -o $DIR/build/bin/HelloTensorflow \
-linkerOpts "-L$TF_TARGET_DIRECTORY/lib -ltensorflow" || exit 1 -linkerOpts "-L$TF_TARGET_DIRECTORY/lib -ltensorflow" || exit 1
echo "Note: You may need to specify LD_LIBRARY_PATH or DYLD_LIBRARY_PATH env variables to $TF_TARGET_DIRECTORY/lib if the TensorFlow dynamic library cannot be found." echo "Note: You may need to specify LD_LIBRARY_PATH or DYLD_LIBRARY_PATH env variables to $TF_TARGET_DIRECTORY/lib if the TensorFlow dynamic library cannot be found."
-1
View File
@@ -15,6 +15,5 @@ rem Windows build requires Windows Resource Compiler in paths.
call windres "%DIR%\Tetris.rc" -O coff -o "%DIR%\Tetris.res" || exit /b call windres "%DIR%\Tetris.rc" -O coff -o "%DIR%\Tetris.res" || exit /b
call konanc -target "%TARGET%" "%DIR%\src\main\kotlin\Tetris.kt" -library sdl -linkerOpts "%LFLAGS%" -opt -o Tetris || exit /b call konanc -target "%TARGET%" "%DIR%\src\main\kotlin\Tetris.kt" -library sdl -linkerOpts "%LFLAGS%" -opt -o Tetris || exit /b
copy Tetris.kexe Tetris.exe
copy %MINGW%\bin\SDL2.dll SDL2.dll copy %MINGW%\bin\SDL2.dll SDL2.dll
copy src\main\resources\tetris_all.bmp tetris_all.bmp copy src\main\resources\tetris_all.bmp tetris_all.bmp
+3 -3
View File
@@ -45,11 +45,11 @@ COMPILER_ARGS=${!var} # add -opt for an optimized build.
mkdir -p $DIR/build/c_interop/ mkdir -p $DIR/build/c_interop/
mkdir -p $DIR/build/bin/ mkdir -p $DIR/build/bin/
cinterop -def $DIR/src/main/c_interop/sdl.def -compilerOpts "$CFLAGS" -target $TARGET -o $DIR/build/c_interop/sdl.kt.bc || exit 1 cinterop -def $DIR/src/main/c_interop/sdl.def -compilerOpts "$CFLAGS" -target $TARGET -o $DIR/build/c_interop/sdl || exit 1
konanc $COMPILER_ARGS -target $TARGET $DIR/src/main/kotlin/Tetris.kt \ konanc $COMPILER_ARGS -target $TARGET $DIR/src/main/kotlin/Tetris.kt \
-library $DIR/build/c_interop/sdl.kt.bc -linkerOpts "$LINKER_ARGS" \ -library $DIR/build/c_interop/sdl -linkerOpts "$LINKER_ARGS" \
-o $DIR/build/bin/Tetris.kexe || exit 1 -o $DIR/build/bin/Tetris || exit 1
cp -R $DIR/src/main/resources/ $DIR/build/bin/ cp -R $DIR/src/main/resources/ $DIR/build/bin/
-2
View File
@@ -8,5 +8,3 @@ set "LFLAGS=-Wl,--subsystem,windows"
call cinterop -def "%DIR%\src\main\c_interop\win32.def" -target "%TARGET%" -o win32 || exit /b call cinterop -def "%DIR%\src\main\c_interop\win32.def" -target "%TARGET%" -o win32 || exit /b
call konanc -target "%TARGET%" "%DIR%\src\main\kotlin\MessageBox.kt" -library win32 -linkerOpts "%LFLAGS%" -opt -o MessageBox || exit /b call konanc -target "%TARGET%" "%DIR%\src\main\kotlin\MessageBox.kt" -library win32 -linkerOpts "%LFLAGS%" -opt -o MessageBox || exit /b
copy MessageBox.kexe MessageBox.exe
+1
View File
@@ -24,6 +24,7 @@ include ':backend.native'
include ':runtime' include ':runtime'
include ':common' include ':common'
include ':backend.native:tests' include ':backend.native:tests'
include ':shared'
include ':tools:helpers' include ':tools:helpers'
include ':tools:kotlin-native-gradle-plugin' include ':tools:kotlin-native-gradle-plugin'
include ':utilities' include ':utilities'
+31
View File
@@ -0,0 +1,31 @@
/*
* Copyright 2010-2017 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.
*/
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
apply plugin: 'kotlin'
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
}
@@ -14,27 +14,38 @@
* limitations under the License. * limitations under the License.
*/ */
package org.jetbrains.kotlin.backend.konan package org.jetbrains.kotlin.konan.target
import org.jetbrains.kotlin.config.CompilerConfiguration enum class KonanTarget(val targetSuffix: String, val programSuffix: String, var enabled: Boolean = false) {
ANDROID_ARM32("android_arm32", "so"),
ANDROID_ARM64("android_arm64", "so"),
IPHONE("ios", "kexe"),
IPHONE_SIM("ios_sim", "kexe"),
LINUX("linux", "kexe"),
MINGW("mingw", "exe"),
MACBOOK("osx", "kexe"),
RASPBERRYPI("raspberrypi", "kexe")
}
enum class KonanTarget(val suffix: String, var enabled: Boolean = false) { enum class CompilerOutputKind {
ANDROID_ARM32("android_arm32"), PROGRAM {
ANDROID_ARM64("android_arm64"), override fun suffix(target: KonanTarget?) = ".${target!!.programSuffix}"
IPHONE("ios"), },
IPHONE_SIM("ios_sim"), LIBRARY {
LINUX("linux"), override fun suffix(target: KonanTarget?) = ".klib"
MINGW("mingw"), } ,
MACBOOK("osx"), BITCODE {
RASPBERRYPI("raspberrypi") override fun suffix(target: KonanTarget?) = ".bc"
};
abstract fun suffix(target: KonanTarget? = null): String
} }
class TargetManager(val userRequest: String? = null) { class TargetManager(val userRequest: String? = null) {
constructor(config: CompilerConfiguration) : this(config.get(KonanConfigKeys.TARGET))
val targets = KonanTarget.values().associate{ it.name.toLowerCase() to it } val targets = KonanTarget.values().associate{ it.name.toLowerCase() to it }
val current = determineCurrent() val target = determineCurrent()
val currentName val targetName
get() = current.name.toLowerCase() get() = target.name.toLowerCase()
init { init {
when (host) { when (host) {
@@ -57,10 +68,6 @@ class TargetManager(val userRequest: String? = null) {
else -> else ->
error("Unknown host platform: $host") error("Unknown host platform: $host")
} }
if (!current.enabled) {
error("Target $current is not available on the current host")
}
} }
fun known(name: String): String { fun known(name: String): String {
@@ -71,9 +78,9 @@ class TargetManager(val userRequest: String? = null) {
} }
fun list() { fun list() {
targets.forEach { key, target -> targets.forEach { key, it ->
if (target.enabled) { if (it.enabled) {
val isDefault = if (target == current) "(default)" else "" val isDefault = if (it == target) "(default)" else ""
println(String.format("%1$-30s%2$-10s", "$key:", "$isDefault")) println(String.format("%1$-30s%2$-10s", "$key:", "$isDefault"))
} }
} }
@@ -87,10 +94,12 @@ class TargetManager(val userRequest: String? = null) {
} }
} }
fun hostSuffix() = host.suffix val hostSuffix get() = host.targetSuffix
fun hostTargetSuffix() = val hostTargetSuffix get() =
if (current == host) host.suffix else "${host.suffix}-${current.suffix}" if (target == host) host.targetSuffix else "${host.targetSuffix}-${target.targetSuffix}"
fun targetSuffix() = current.suffix val targetSuffix get() = target.targetSuffix
val programSuffix get() = CompilerOutputKind.PROGRAM.suffix(target)
companion object { companion object {
fun host_os(): String { fun host_os(): String {
@@ -103,6 +112,11 @@ class TargetManager(val userRequest: String? = null) {
} }
} }
fun simpleOsName(): String {
val hostOs = host_os()
return if (hostOs == "osx") "macos" else hostOs
}
fun host_arch(): String { fun host_arch(): String {
val javaArch = System.getProperty("os.arch") val javaArch = System.getProperty("os.arch")
return when (javaArch) { return when (javaArch) {
@@ -48,6 +48,7 @@ repositories {
evaluationDependsOn(':tools:helpers') evaluationDependsOn(':tools:helpers')
dependencies { dependencies {
compile project(':shared')
compile project(':tools:helpers') compile project(':tools:helpers')
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
compile gradleApi() compile gradleApi()
@@ -57,6 +58,7 @@ jar {
dependsOn(':tools:helpers:jar') dependsOn(':tools:helpers:jar')
dependsOn(':cross_dist') dependsOn(':cross_dist')
from (rootProject.findProject(':tools:helpers').sourceSets.main.output) from (rootProject.findProject(':tools:helpers').sourceSets.main.output)
from (rootProject.findProject(':shared').sourceSets.main.output)
} }
task deleteDist(type: Delete) { task deleteDist(type: Delete) {
@@ -67,7 +67,7 @@ import java.io.File
// TODO: form groups for tasks // TODO: form groups for tasks
// TODO: Make the task class nested for config with properties accessible for outer users. // TODO: Make the task class nested for config with properties accessible for outer users.
open class KonanCompileTask: DefaultTask() { open class KonanCompileTask: KonanTargetableTask() {
companion object { companion object {
const val COMPILER_MAIN = "org.jetbrains.kotlin.cli.bc.K2NativeKt" const val COMPILER_MAIN = "org.jetbrains.kotlin.cli.bc.K2NativeKt"
@@ -89,13 +89,17 @@ open class KonanCompileTask: DefaultTask() {
internal fun init(artifactName: String) { internal fun init(artifactName: String) {
dependsOn(project.konanCompilerDownloadTask) dependsOn(project.konanCompilerDownloadTask)
this.artifactName = artifactName this.artifactName = artifactName
outputDir = project.file("${project.konanCompilerOutputDir}/$artifactName") outputDir = project.file("${project.konanCompilerOutputDir}")
} }
private val artifactSuffix = mapOf("program" to "kexe", "library" to "klib", "bitcode" to "bc") val artifactNamePath: String
get() = "${outputDir.absolutePath}/$artifactName"
val artifactSuffix: String
get() = produceSuffix(produce)
val artifactPath: String val artifactPath: String
get() = "${outputDir.absolutePath}/$artifactName.${artifactSuffix[produce]}" get() = "$artifactNamePath$artifactSuffix"
// Other compilation parameters ------------------------------------------- // Other compilation parameters -------------------------------------------
@@ -119,8 +123,6 @@ open class KonanCompileTask: DefaultTask() {
@Input var enableAssertions = false @Input var enableAssertions = false
internal set internal set
@Optional @Input var target : String? = null
internal set
@Optional @Input var languageVersion : String? = null @Optional @Input var languageVersion : String? = null
internal set internal set
@Optional @Input var apiVersion : String? = null @Optional @Input var apiVersion : String? = null
@@ -133,7 +135,7 @@ open class KonanCompileTask: DefaultTask() {
// Task action ------------------------------------------------------------ // Task action ------------------------------------------------------------
protected fun buildArgs() = mutableListOf<String>().apply { protected fun buildArgs() = mutableListOf<String>().apply {
addArg("-output", artifactPath) addArg("-output", artifactNamePath)
addFileArgs("-library", libraries) addFileArgs("-library", libraries)
addFileArgs("-nativelibrary", nativeLibraries) addFileArgs("-nativelibrary", nativeLibraries)
@@ -219,7 +221,7 @@ open class KonanCompileConfig(
compilationTask.dependsOn(generateStubsTask) compilationTask.dependsOn(generateStubsTask)
linkerOpts(generateStubsTask.linkerOpts) linkerOpts(generateStubsTask.linkerOpts)
library(compileStubsTask.artifactPath) library(compileStubsTask.artifactNamePath)
nativeLibraries(project.fileTree(generateStubsTask.libsDir).apply { nativeLibraries(project.fileTree(generateStubsTask.libsDir).apply {
builtBy(generateStubsTask) builtBy(generateStubsTask)
include("**/*.bc") include("**/*.bc")
@@ -20,6 +20,7 @@ import org.gradle.api.DefaultTask
import org.gradle.api.GradleScriptException import org.gradle.api.GradleScriptException
import org.gradle.api.tasks.TaskAction import org.gradle.api.tasks.TaskAction
import org.jetbrains.kotlin.konan.DependencyDownloader import org.jetbrains.kotlin.konan.DependencyDownloader
import org.jetbrains.kotlin.konan.target.*
import java.io.File import java.io.File
open class KonanCompilerDownloadTask : DefaultTask() { open class KonanCompilerDownloadTask : DefaultTask() {
@@ -28,16 +29,6 @@ open class KonanCompilerDownloadTask : DefaultTask() {
internal const val DOWNLOAD_URL = "http://download.jetbrains.com/kotlin/native" internal const val DOWNLOAD_URL = "http://download.jetbrains.com/kotlin/native"
internal val KONAN_PARENT_DIR = "${System.getProperty("user.home")}/.konan" internal val KONAN_PARENT_DIR = "${System.getProperty("user.home")}/.konan"
internal fun simpleOsName(): String {
val osName = System.getProperty("os.name")
return when {
osName == "Mac OS X" -> "macos"
osName == "Linux" -> "linux"
osName.startsWith("Windows") -> "windows"
else -> throw IllegalStateException("Unsupported platform: $osName")
}
}
} }
@TaskAction @TaskAction
@@ -55,4 +46,4 @@ open class KonanCompilerDownloadTask : DefaultTask() {
throw GradleScriptException("Cannot download Kotlin Native compiler", e) throw GradleScriptException("Cannot download Kotlin Native compiler", e)
} }
} }
} }
@@ -43,7 +43,7 @@ import java.io.File
* } * }
*/ */
open class KonanInteropTask: DefaultTask() { open class KonanInteropTask: KonanTargetableTask() {
internal companion object { internal companion object {
const val INTEROP_MAIN = "org.jetbrains.kotlin.native.interop.gen.jvm.MainKt" const val INTEROP_MAIN = "org.jetbrains.kotlin.native.interop.gen.jvm.MainKt"
@@ -61,7 +61,6 @@ open class KonanInteropTask: DefaultTask() {
internal val C_INTEROP_DIR_PATH: String internal val C_INTEROP_DIR_PATH: String
get() = "${project.projectDir}/src/main/c_interop" get() = "${project.projectDir}/src/main/c_interop"
// Output directories ----------------------------------------------------- // Output directories -----------------------------------------------------
/** Directory with autogenerated interop stubs (*.kt) */ /** Directory with autogenerated interop stubs (*.kt) */
@@ -76,11 +75,10 @@ open class KonanInteropTask: DefaultTask() {
@Optional @InputFile var defFile: File? = null @Optional @InputFile var defFile: File? = null
internal set internal set
@Optional @Input var target: String? = null
internal set
@Optional @Input var pkg: String? = null @Optional @Input var pkg: String? = null
internal set internal set
@Input lateinit var libName: String @Input lateinit var libName: String
@Optional @Input var linker: String? = null @Optional @Input var linker: String? = null
internal set internal set
@@ -104,9 +102,8 @@ open class KonanInteropTask: DefaultTask() {
classpath = project.fileTree(INTEROP_CLASSPATH).apply { include("*.jar") } classpath = project.fileTree(INTEROP_CLASSPATH).apply { include("*.jar") }
jvmArgs(INTEROP_JVM_ARGS) jvmArgs(INTEROP_JVM_ARGS)
environment("LIBCLANG_DISABLE_CRASH_RECOVERY", "1") environment("LIBCLANG_DISABLE_CRASH_RECOVERY", "1")
// TODO: remove this hack. // TODO: remove this hack.
if (KonanCompilerDownloadTask.simpleOsName() == "windows") { if (project.host == "mingw") {
environment("PATH", "${project.konanHome}\\dependencies\\msys2-mingw-w64-x86_64-gcc-6.3.0-clang-llvm-3.9.1-windows-x86-64\\bin;${System.getenv("PATH")}") environment("PATH", "${project.konanHome}\\dependencies\\msys2-mingw-w64-x86_64-gcc-6.3.0-clang-llvm-3.9.1-windows-x86-64\\bin;${System.getenv("PATH")}")
} }
@@ -57,28 +57,29 @@ internal val Project.konanCompilerDownloadTask get() = tasks.getByName(KonanPlu
internal val Project.konanVersion internal val Project.konanVersion
get() = findProperty(KonanPlugin.KONAN_VERSION_PROPERTY_NAME) as String? ?: KonanPlugin.DEFAULT_KONAN_VERSION get() = findProperty(KonanPlugin.KONAN_VERSION_PROPERTY_NAME) as String? ?: KonanPlugin.DEFAULT_KONAN_VERSION
internal fun Project.isTargetSupported(target: String?): Boolean { internal fun Project.targetIsRequested(target: String?): Boolean {
val targets = extensions.extraProperties.get(KonanPlugin.KONAN_BUILD_TARGETS).toString().trim().split(' ') val targets = extensions.extraProperties.get(KonanPlugin.KONAN_BUILD_TARGETS).toString().trim().split(' ')
if (targets.contains("all")) {
return target?.isSupported() ?: true return (targets.contains(target) ||
} else { targets.contains("all") ||
return target == null || targets.contains(target) target == null)
}
} }
internal val Project.supportedCompileTasks: TaskCollection<KonanCompileTask> internal fun Project.targetIsSupportedAndRequested(task: KonanTargetableTask)
get() { = task.targetIsSupported && this.targetIsRequested(task.target)
return project.tasks.withType(KonanCompileTask::class.java).matching { isTargetSupported(it.target) } internal val Project.supportedCompileTasks: TaskCollection<KonanCompileTask>
get() = project.tasks.withType(KonanCompileTask::class.java).matching {
targetIsSupportedAndRequested(it)
} }
internal val Project.supportedInteropTasks: TaskCollection<KonanInteropTask> internal val Project.supportedInteropTasks: TaskCollection<KonanInteropTask>
get() { get() = project.tasks.withType(KonanInteropTask::class.java).matching {
return project.tasks.withType(KonanInteropTask::class.java).matching { isTargetSupported(it.target) } targetIsSupportedAndRequested(it)
} }
internal fun Project.konanCompilerName(): String = internal fun Project.konanCompilerName(): String =
"kotlin-native-${KonanCompilerDownloadTask.simpleOsName()}-${this.konanVersion}" "kotlin-native-${project.simpleOsName}-${this.konanVersion}"
internal fun Project.konanCompilerDownloadDir(): String = internal fun Project.konanCompilerDownloadDir(): String =
KonanCompilerDownloadTask.KONAN_PARENT_DIR + "/" + project.konanCompilerName() KonanCompilerDownloadTask.KONAN_PARENT_DIR + "/" + project.konanCompilerName()
@@ -177,17 +178,6 @@ internal fun dumpProperties(task: Task) {
} }
} }
private fun String.isSupported(): Boolean {
val os = KonanCompilerDownloadTask.simpleOsName()
return when (os) {
"macos" -> this == "macbook" || this == "iphone"
"linux" -> this == "linux" || this == "raspberrypi"
"windows" -> this == "mingw"
else -> false
}
}
class KonanPlugin @Inject constructor(private val registry: ToolingModelBuilderRegistry) class KonanPlugin @Inject constructor(private val registry: ToolingModelBuilderRegistry)
: Plugin<ProjectInternal> { : Plugin<ProjectInternal> {
@@ -230,14 +220,8 @@ class KonanPlugin @Inject constructor(private val registry: ToolingModelBuilderR
if (!project.extensions.extraProperties.has(KonanPlugin.KONAN_HOME_PROPERTY_NAME)) { if (!project.extensions.extraProperties.has(KonanPlugin.KONAN_HOME_PROPERTY_NAME)) {
project.extensions.extraProperties.set(KonanPlugin.KONAN_HOME_PROPERTY_NAME, project.konanCompilerDownloadDir()) project.extensions.extraProperties.set(KonanPlugin.KONAN_HOME_PROPERTY_NAME, project.konanCompilerDownloadDir())
} }
val hostTarget = when (KonanCompilerDownloadTask.simpleOsName()) {
"macos" -> "macbook"
"linux" -> "linux"
"windows" -> "mingw"
else -> throw IllegalStateException("Unsupported platform")
}
if (!project.extensions.extraProperties.has(KonanPlugin.KONAN_BUILD_TARGETS)) { if (!project.extensions.extraProperties.has(KonanPlugin.KONAN_BUILD_TARGETS)) {
project.extensions.extraProperties.set(KonanPlugin.KONAN_BUILD_TARGETS, hostTarget) project.extensions.extraProperties.set(KonanPlugin.KONAN_BUILD_TARGETS, project.host)
} }
getTask(project, "build").apply { getTask(project, "build").apply {
dependsOn(project.supportedCompileTasks) dependsOn(project.supportedCompileTasks)
@@ -246,8 +230,8 @@ class KonanPlugin @Inject constructor(private val registry: ToolingModelBuilderR
getOrCreateTask(project, "run").apply { getOrCreateTask(project, "run").apply {
dependsOn(getTask(project, "build")) dependsOn(getTask(project, "build"))
doLast { doLast {
for (task in project.tasks.withType(KonanCompileTask::class.java).matching { it.target?.equals(hostTarget) ?: true}) { for (task in project.tasks.withType(KonanCompileTask::class.java).matching { !it.isCrossCompile}) {
if (task.artifactPath.endsWith("kexe")) { if (task?.produce == "program") {
project.exec { project.exec {
with(it) { with(it) {
commandLine(task.artifactPath) commandLine(task.artifactPath)
@@ -0,0 +1,50 @@
/*
* Copyright 2010-2017 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
import org.gradle.api.DefaultTask
import org.gradle.api.Project
import org.gradle.api.internal.project.ProjectInternal
import org.gradle.api.tasks.*
import org.jetbrains.kotlin.konan.target.*
import org.jetbrains.kotlin.konan.target.KonanTarget.*
abstract class KonanTargetableTask: DefaultTask() {
@Optional @Input var target : String? = null
internal set
internal val targetManager: TargetManager by lazy {
TargetManager(target ?: "host")
}
val targetIsSupported: Boolean
get() = targetManager.target.enabled
val isCrossCompile: Boolean
get() = (targetManager.target != TargetManager.host)
fun produceSuffix(produce: String): String
= CompilerOutputKind.valueOf(produce.toUpperCase())
.suffix(targetManager.target)
}
internal val Project.host
get() = TargetManager.host.name.toLowerCase()
internal val Project.simpleOsName
get() = TargetManager.simpleOsName()