diff --git a/GRADLE_PLUGIN.md b/GRADLE_PLUGIN.md index 5199b2e86ce..fdc5b647f5b 100644 --- a/GRADLE_PLUGIN.md +++ b/GRADLE_PLUGIN.md @@ -88,7 +88,7 @@ cinterop execution (see the `dumpParameters` task in `samles/csvparser/build.gra // Directory for output artifact (default: build/konan/bin/). outputDir 'path/to/output/dir' - // *.kt.bc library for linking. + // *.klib library for linking. library project.file('path/to/library') // naitve library for linking. diff --git a/INTEROP.md b/INTEROP.md index 91f9d6e2083..859c3dd5864 100644 --- a/INTEROP.md +++ b/INTEROP.md @@ -24,12 +24,12 @@ Build the dependencies and the compiler (see `README.md`). Prepare stubs for the system sockets library: 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: - ../../dist/bin/kotlinc EchoServer.kt -library sockets.kt.bc \ - -o EchoServer.kexe + ../../dist/bin/kotlinc EchoServer.kt -library sockets \ + -o EchoServer 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 @@ -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 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 -`zlib.kt.bc-build/kotlin` directory containing Kotlin source code for the library. +This command will produce `zlib.klib` compiled library and +`zlib-build/kotlin` directory containing Kotlin source code for the library. If behavior for certain platform shall be modified, one may use format like `compilerOpts.osx` or `compilerOpts.linux` to provide platform-specific values diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 270d7f7f999..c10348b9549 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -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 - bin/kotlinc .kt -o .kexe + bin/kotlinc .kt -o During the first run it will download all the external dependencies, such as LLVM. diff --git a/backend.native/build.gradle b/backend.native/build.gradle index f3e89f8b56f..1ce8f5cfef0 100644 --- a/backend.native/build.gradle +++ b/backend.native/build.gradle @@ -57,7 +57,10 @@ sourceSets { srcDir 'compiler/ir/backend.native/src/' 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 { java.srcDir 'cli.bc/src' @@ -130,6 +133,7 @@ dependencies { compilerCompile kotlinCompilerModule compilerCompile kotlinNativeInterop['llvm'].configuration compilerCompile kotlinNativeInterop['hash'].configuration + compilerCompile project(':shared') cli_bcCompile "org.jetbrains.kotlin:kotlin-runtime:$kotlin_version" cli_bcCompile sourceSets.compiler.output diff --git a/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2Native.kt b/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2Native.kt index d0b328c2038..02b9430f113 100644 --- a/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2Native.kt +++ b/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2Native.kt @@ -18,10 +18,7 @@ package org.jetbrains.kotlin.cli.bc import com.intellij.openapi.Disposable 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.suffixIfNot -import org.jetbrains.kotlin.backend.konan.util.removeSuffixIfPresent import org.jetbrains.kotlin.cli.common.CLICompiler import org.jetbrains.kotlin.cli.common.CLITool 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.Services import org.jetbrains.kotlin.config.addKotlinSourceRoots +import org.jetbrains.kotlin.konan.target.* import java.util.* import kotlin.reflect.KFunction // TODO: Don't use reflection? -private fun maybeExecuteHelper(configuration: CompilerConfiguration) { +private fun maybeExecuteHelper(targetName: String) { try { val kClass = Class.forName("org.jetbrains.kotlin.konan.Helper0").kotlin val ctor = kClass.constructors.single() as KFunction - val distribution = Distribution(configuration) + val distribution = Distribution(TargetManager(targetName)) val result = ctor.call( distribution.dependenciesDir, distribution.properties.properties, @@ -109,18 +107,10 @@ class K2Native : CLICompiler() { // TODO: Collect all the explicit file names into an object // and teach the compiler to work with temporaries and -save-temps. + arguments.outputName ?.let { put(OUTPUT, it) } val outputKind = CompilerOutputKind.valueOf( (arguments.produce ?: "program").toUpperCase()) - 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) arguments.mainPackage ?.let{ put(ENTRY, it) } @@ -154,7 +144,7 @@ class K2Native : CLICompiler() { } } - maybeExecuteHelper(configuration) + maybeExecuteHelper(arguments.target ?: "host") } override fun createArguments(): K2NativeCompilerArguments { diff --git a/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2NativeCompilerArguments.kt b/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2NativeCompilerArguments.kt index 8a059ba4367..34185131d47 100644 --- a/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2NativeCompilerArguments.kt +++ b/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2NativeCompilerArguments.kt @@ -54,13 +54,13 @@ class K2NativeCompilerArguments : CommonCompilerArguments() { @field:Argument(value = "-opt", description = "Enable optimizations during compilation") @JvmField var optimization: Boolean = false - @field:Argument(value = "-output", shortName = "-o", valueDescription = "", description = "Output file path") - @JvmField var outputFile: String? = null + @field:Argument(value = "-output", shortName = "-o", valueDescription = "", description = "Output name") + @JvmField var outputName: String? = null @field:Argument(value = "-entry", shortName = "-e", valueDescription = "", description = "Qualified entry point name") @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 @field:Argument(value = "-properties", valueDescription = "", description = "Override standard 'konan.properties' location") diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Distribution.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Distribution.kt index 741d3d7a4a9..f3634f2f315 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Distribution.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Distribution.kt @@ -16,16 +16,17 @@ package org.jetbrains.kotlin.backend.konan -import org.jetbrains.kotlin.config.CompilerConfiguration 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 target = targetManager.currentName - val hostSuffix = targetManager.hostSuffix() - val hostTargetSuffix = targetManager.hostTargetSuffix() - val targetSuffix = targetManager.targetSuffix() + val targetName = targetManager.targetName + val hostSuffix = targetManager.hostSuffix + val hostTargetSuffix = targetManager.hostTargetSuffix + val targetSuffix = targetManager.targetSuffix private fun findUserHome() = File(System.getProperty("user.home")).absolutePath val userHome = findUserHome() @@ -38,8 +39,7 @@ class Distribution(val config: CompilerConfiguration) { } val konanHome = findKonanHome() - val propertyFile = config.get(KonanConfigKeys.PROPERTY_FILE) - ?: "$konanHome/konan/konan.properties" + val propertyFile = propertyFileOverride ?: "$konanHome/konan/konan.properties" val properties = KonanProperties(propertyFile) val klib = "$konanHome/klib" @@ -48,8 +48,7 @@ class Distribution(val config: CompilerConfiguration) { val dependencies = properties.propertyList("dependencies.$hostTargetSuffix") val stdlib = "$klib/stdlib" - val runtime = config.get(KonanConfigKeys.RUNTIME_FILE) - ?: "$stdlib/targets/$target/native/runtime.bc" + val runtime = runtimeFileOverride ?: "$stdlib/targets/${targetName}/native/runtime.bc" val llvmHome = "$dependenciesDir/${properties.propertyString("llvmHome.$hostSuffix")}" val hostSysRoot = "$dependenciesDir/${properties.propertyString("targetSysRoot.$hostSuffix")}" diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfig.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfig.kt index 5c4cfb7a83b..9a548639421 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfig.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfig.kt @@ -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.KonanLibrarySearchPathResolver 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.CompilerConfiguration import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl 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) { - val moduleId: String - get() = configuration.getNotNull(CommonConfigurationKeys.MODULE_NAME) + internal val targetManager = TargetManager( + configuration.get(KonanConfigKeys.TARGET)) + + init { + 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)) - internal val targetManager = TargetManager(configuration) - internal val distribution = Distribution(configuration) + val moduleId: String + // This is a decision we could change + get() = outputName private val libraryNames: List get() { @@ -51,7 +72,7 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration internal val libraries: List by lazy { val currentAbiVersion = configuration.get(KonanConfigKeys.ABI_VERSION)!! - val target = targetManager.currentName + val target = targetManager.targetName // Here we have chosen a particular KonanLibraryReader implementation. librariesFound.map{it -> SplitLibraryReader(it, currentAbiVersion, target)} } diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfigurationKeys.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfigurationKeys.kt index 0d35facb701..24c0a37e408 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfigurationKeys.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfigurationKeys.kt @@ -18,6 +18,7 @@ package org.jetbrains.kotlin.backend.konan import org.jetbrains.kotlin.config.CompilerConfigurationKey import org.jetbrains.kotlin.serialization.js.ModuleKind +import org.jetbrains.kotlin.konan.target.CompilerOutputKind class KonanConfigKeys { companion object { @@ -56,9 +57,7 @@ class KonanConfigKeys { = CompilerConfigurationKey.create("don't the library into a klib file") val OPTIMIZATION: CompilerConfigurationKey = CompilerConfigurationKey.create("optimized compilation") - val OUTPUT_FILE: CompilerConfigurationKey - = CompilerConfigurationKey.create("final executable file path") - val OUTPUT_NAME: CompilerConfigurationKey + val OUTPUT: CompilerConfigurationKey = CompilerConfigurationKey.create("program or library name") val PRINT_BITCODE: CompilerConfigurationKey = CompilerConfigurationKey.create("print bitcode") @@ -95,8 +94,3 @@ class KonanConfigKeys { } } -enum class CompilerOutputKind(val suffix: String) { - PROGRAM(".kexe"), - LIBRARY(".klib"), - BITCODE(".bc") -} diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanDriver.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanDriver.kt index a64a9ca7246..c0350b16c3b 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanDriver.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanDriver.kt @@ -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.ModuleIndex 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.markBackingFields import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport @@ -108,6 +109,7 @@ public fun runTopLevelPhases(konanConfig: KonanConfig, environment: KotlinCoreEn } phaser.phase(KonanPhase.BITCODE) { emitLLVM(context) + produceOutput(context) } // We always verify bitcode to prevent hard to debug bugs. context.verifyBitCode() diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanPhases.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanPhases.kt index 9094809f22a..6000cd9f1ab 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanPhases.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanPhases.kt @@ -17,6 +17,7 @@ package org.jetbrains.kotlin.backend.konan import org.jetbrains.kotlin.backend.konan.util.* +import org.jetbrains.kotlin.konan.target.CompilerOutputKind enum class KonanPhase(val description: String, vararg prerequisite: KonanPhase, diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/LinkStage.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/LinkStage.kt index f3c0d1f1615..2e233548ef9 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/LinkStage.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/LinkStage.kt @@ -19,6 +19,7 @@ package org.jetbrains.kotlin.backend.konan import java.io.File import java.lang.ProcessBuilder import java.lang.ProcessBuilder.Redirect +import org.jetbrains.kotlin.konan.target.* typealias BitcodeFile = String typealias ObjectFile = String @@ -186,7 +187,7 @@ internal class LinkStage(val context: Context) { private val distribution = context.config.distribution - val platform = when (context.config.targetManager.current) { + val platform = when (context.config.targetManager.target) { KonanTarget.LINUX, KonanTarget.RASPBERRYPI -> LinuxBasedPlatform(distribution) KonanTarget.MACBOOK, KonanTarget.IPHONE, KonanTarget.IPHONE_SIM -> @@ -196,7 +197,7 @@ internal class LinkStage(val context: Context) { KonanTarget.MINGW -> MingwPlatform(distribution) else -> - error("Unexpected target platform: ${context.config.targetManager.current}") + error("Unexpected target platform: ${context.config.targetManager.target}") } val optimize = config.get(KonanConfigKeys.OPTIMIZATION) ?: false @@ -251,7 +252,7 @@ internal class LinkStage(val context: Context) { get() = if (nomain) emptyList() else platform.entrySelector fun link(objectFiles: List): ExecutableFile { - val executable = config.get(KonanConfigKeys.OUTPUT_FILE)!! + val executable = context.config.outputFile val linkCommand = platform.linkCommand(objectFiles, executable, optimize, config.getBoolean(KonanConfigKeys.DEBUG)) + distribution.libffi + asLinkerArgs(config.getNotNull(KonanConfigKeys.LINKER_ARGS)) + diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/library/KonanLibrary.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/library/KonanLibrary.kt index 0620a06ae6b..8922de5da95 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/library/KonanLibrary.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/library/KonanLibrary.kt @@ -19,7 +19,6 @@ package org.jetbrains.kotlin.backend.konan.library import llvm.LLVMModuleRef import llvm.LLVMWriteBitcodeToFile 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.deserializeModule import org.jetbrains.kotlin.backend.konan.util.File diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt index 0b429e49819..30b4eb790f2 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt @@ -20,7 +20,7 @@ package org.jetbrains.kotlin.backend.konan.llvm import kotlinx.cinterop.* import llvm.* 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.ClassDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor @@ -154,7 +154,7 @@ internal class CodeGenerator(override val context: Context) : ContextUtils { get() { return slotCount > 1 || localAllocs > 0 || // Prevent empty cleanup on mingw to workaround LLVM bug: - context.config.targetManager.current == KonanTarget.MINGW + context.config.targetManager.target == KonanTarget.MINGW } private fun releaseVars() { diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/ContextUtils.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/ContextUtils.kt index 852ffb15ee1..e81e06bb8e1 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/ContextUtils.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/ContextUtils.kt @@ -19,7 +19,7 @@ package org.jetbrains.kotlin.backend.konan.llvm import kotlinx.cinterop.* import llvm.* 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.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor @@ -259,7 +259,7 @@ internal class Llvm(val context: Context, val llvmModule: LLVMModuleRef) { val throwExceptionFunction = importRtFunction("ThrowException") 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" else -> "__gxx_personality_v0" } diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/DebugUtils.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/DebugUtils.kt index ed166f52697..5ff3ee37d38 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/DebugUtils.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/DebugUtils.kt @@ -22,7 +22,6 @@ import llvm.* import org.jetbrains.kotlin.backend.konan.Context import org.jetbrains.kotlin.backend.konan.KonanConfigKeys 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.builtins.KotlinBuiltIns import org.jetbrains.kotlin.descriptors.FunctionDescriptor @@ -103,7 +102,7 @@ internal fun String?.toFileAndFolder():FileAndFolder { internal fun generateDebugInfoHeader(context: Context) { if (context.shouldContainDebugInfo()) { - val path = context.config.configuration.get(KonanConfigKeys.OUTPUT_FILE)!! + val path = context.config.outputFile .toFileAndFolder() context.debugInfo.module = DICreateModule( diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/EntryPoint.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/EntryPoint.kt index 181e566a2b4..60908d8f645 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/EntryPoint.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/EntryPoint.kt @@ -16,13 +16,13 @@ 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.KonanConfigKeys import org.jetbrains.kotlin.backend.konan.descriptors.isArray import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor 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.Name import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt index eb0e4794873..e02eff458d4 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt @@ -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.konan.Context 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.library.LinkData 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.acceptChildrenVoid import org.jetbrains.kotlin.ir.visitors.acceptVoid +import org.jetbrains.kotlin.konan.target.CompilerOutputKind import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe @@ -85,65 +85,65 @@ internal fun emitLLVM(context: Context) { if (context.shouldContainDebugInfo()) { 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. - } +} + +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 = 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) + LLVMWriteBitcodeToFile(llvmModule, output) + } + CompilerOutputKind.LIBRARY -> { + val libraryName = context.config.outputName + val nopack = config.getBoolean(KonanConfigKeys.NOPACK) + val targetName = context.config.targetManager.targetName - context.library = library + val library = buildLibrary( + context.config.nativeLibraries, + context.serializedLinkData!!, + targetName, + libraryName, + llvmModule, + nopack) - context.bitcodeFileName = library.mainBitcodeFileName - } - CompilerOutputKind.BITCODE -> { - val output = config.get(KonanConfigKeys.OUTPUT_FILE)!! - context.bitcodeFileName = output - LLVMWriteBitcodeToFile(llvmModule, output) - } + context.library = library + context.bitcodeFileName = library.mainBitcodeFileName + } + CompilerOutputKind.BITCODE -> { + val output = context.config.outputFile + context.bitcodeFileName = output + LLVMWriteBitcodeToFile(llvmModule, output) } + } } -internal fun buildLibrary(phaser: PhaseManager, natives: List, linkData: LinkData, target: String, output: String, llvmModule: LLVMModuleRef, nopack: Boolean): KonanLibraryWriter { +internal fun buildLibrary(natives: List, linkData: LinkData, target: String, output: String, llvmModule: LLVMModuleRef, nopack: Boolean): KonanLibraryWriter { // TODO: May be we need a factory? //val library = KtBcLibraryWriter(output, llvmModule) val library = SplitLibraryWriter(output, target, nopack) library.addKotlinBitcode(llvmModule) - library.addLinkData(linkData) - phaser.phase(KonanPhase.BITCODE_LINKER) { - natives.forEach { - library.addNativeBitcode(it) - } + natives.forEach { + library.addNativeBitcode(it) } library.commit() diff --git a/backend.native/tests/build.gradle b/backend.native/tests/build.gradle index 4054a0319ab..53d1196c8f7 100644 --- a/backend.native/tests/build.gradle +++ b/backend.native/tests/build.gradle @@ -1093,7 +1093,7 @@ task intrinsic(type: RunKonanTest) { /* 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) { goldValue = "0\n" diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle index 1e11815ff25..da943b4dfa0 100644 --- a/buildSrc/build.gradle +++ b/buildSrc/build.gradle @@ -14,14 +14,8 @@ * limitations under the License. */ -apply plugin: 'groovy' - -repositories { - mavenCentral() -} - -dependencies { - compile gradleApi() - compile localGroovy() - compile group: 'com.ullink.slack', name: 'simpleslackapi', version: '0.6.0' +allprojects { + repositories { + mavenCentral() + } } diff --git a/buildSrc/plugins/build.gradle b/buildSrc/plugins/build.gradle new file mode 100644 index 00000000000..4a0c7807142 --- /dev/null +++ b/buildSrc/plugins/build.gradle @@ -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) +} diff --git a/buildSrc/src/main/groovy/org/jetbrains/kotlin/CompileToBitcode.groovy b/buildSrc/plugins/src/main/groovy/org/jetbrains/kotlin/CompileToBitcode.groovy similarity index 100% rename from buildSrc/src/main/groovy/org/jetbrains/kotlin/CompileToBitcode.groovy rename to buildSrc/plugins/src/main/groovy/org/jetbrains/kotlin/CompileToBitcode.groovy diff --git a/buildSrc/src/main/groovy/org/jetbrains/kotlin/ExecClang.groovy b/buildSrc/plugins/src/main/groovy/org/jetbrains/kotlin/ExecClang.groovy similarity index 100% rename from buildSrc/src/main/groovy/org/jetbrains/kotlin/ExecClang.groovy rename to buildSrc/plugins/src/main/groovy/org/jetbrains/kotlin/ExecClang.groovy diff --git a/buildSrc/src/main/groovy/org/jetbrains/kotlin/ExecRemote.groovy b/buildSrc/plugins/src/main/groovy/org/jetbrains/kotlin/ExecRemote.groovy similarity index 100% rename from buildSrc/src/main/groovy/org/jetbrains/kotlin/ExecRemote.groovy rename to buildSrc/plugins/src/main/groovy/org/jetbrains/kotlin/ExecRemote.groovy diff --git a/buildSrc/src/main/groovy/org/jetbrains/kotlin/KonanTest.groovy b/buildSrc/plugins/src/main/groovy/org/jetbrains/kotlin/KonanTest.groovy similarity index 99% rename from buildSrc/src/main/groovy/org/jetbrains/kotlin/KonanTest.groovy rename to buildSrc/plugins/src/main/groovy/org/jetbrains/kotlin/KonanTest.groovy index eefe68a8ba4..4483cd0055b 100644 --- a/buildSrc/src/main/groovy/org/jetbrains/kotlin/KonanTest.groovy +++ b/buildSrc/plugins/src/main/groovy/org/jetbrains/kotlin/KonanTest.groovy @@ -22,6 +22,7 @@ import org.gradle.api.tasks.JavaExec import org.gradle.api.tasks.ParallelizableTask import org.gradle.api.tasks.TaskAction import org.gradle.process.ExecResult +import org.jetbrains.kotlin.konan.target.* abstract class KonanTest extends JavaExec { protected String source @@ -208,7 +209,9 @@ fun handleExceptionContinuation(x: (Throwable) -> Unit): Continuation = ob void executeTest() { createOutputDirectory() def program = buildExePath() - def exe = "${program}.kexe" + def targetManager = new TargetManager(project.testTarget) + def suffix = targetManager.programSuffix + def exe = "$program$suffix" compileTest(buildCompileList(), program) diff --git a/buildSrc/src/main/groovy/org/jetbrains/kotlin/NativeInteropPlugin.groovy b/buildSrc/plugins/src/main/groovy/org/jetbrains/kotlin/NativeInteropPlugin.groovy similarity index 100% rename from buildSrc/src/main/groovy/org/jetbrains/kotlin/NativeInteropPlugin.groovy rename to buildSrc/plugins/src/main/groovy/org/jetbrains/kotlin/NativeInteropPlugin.groovy diff --git a/buildSrc/src/main/groovy/org/jetbrains/kotlin/Reporter.groovy b/buildSrc/plugins/src/main/groovy/org/jetbrains/kotlin/Reporter.groovy similarity index 100% rename from buildSrc/src/main/groovy/org/jetbrains/kotlin/Reporter.groovy rename to buildSrc/plugins/src/main/groovy/org/jetbrains/kotlin/Reporter.groovy diff --git a/buildSrc/settings.gradle b/buildSrc/settings.gradle new file mode 100644 index 00000000000..0076197d555 --- /dev/null +++ b/buildSrc/settings.gradle @@ -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' diff --git a/buildSrc/shared/build.gradle b/buildSrc/shared/build.gradle new file mode 100644 index 00000000000..2d510ed86df --- /dev/null +++ b/buildSrc/shared/build.gradle @@ -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) +} diff --git a/klib/src/main/kotlin/org/jetbrains/kotlin/cli/klib/main.kt b/klib/src/main/kotlin/org/jetbrains/kotlin/cli/klib/main.kt index 29003d092fa..74832470cdc 100644 --- a/klib/src/main/kotlin/org/jetbrains/kotlin/cli/klib/main.kt +++ b/klib/src/main/kotlin/org/jetbrains/kotlin/cli/klib/main.kt @@ -6,7 +6,7 @@ import java.util.Properties import org.jetbrains.kotlin.backend.konan.library.SplitLibraryReader import org.jetbrains.kotlin.backend.konan.util.File import org.jetbrains.kotlin.backend.konan.util.copyTo -import org.jetbrains.kotlin.backend.konan.TargetManager +import org.jetbrains.kotlin.konan.target.TargetManager fun printUsage() { println("Usage: klib ") @@ -113,7 +113,7 @@ fun main(args: Array) { val command = Command(args) val targetManager = TargetManager(command.options["target"]?.last()) - val target = targetManager.currentName + val target = targetManager.targetName val repository = command.options["repository"]?.last() val repositoryList = repository ?.let { listOf(it) } ?: emptyList() diff --git a/samples/concurrent/build.sh b/samples/concurrent/build.sh index fc1f2d9bd0b..4d734bc4176 100755 --- a/samples/concurrent/build.sh +++ b/samples/concurrent/build.sh @@ -25,9 +25,9 @@ mkdir -p $DIR/build/bin $DIR/buildCpp.sh 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 \ - -nativelibrary $DIR/build/clang/MessageChannel.bc -o $DIR/build/bin/Concurrent.kexe || exit 1 +konanc $DIR/src/main/kotlin/Concurrent.kt -library $DIR/build/c_interop/MessageChannel \ + -nativelibrary $DIR/build/clang/MessageChannel.bc -o $DIR/build/bin/Concurrent || exit 1 echo "Artifact path is $DIR/build/bin/Concurrent.kexe" diff --git a/samples/csvparser/build.sh b/samples/csvparser/build.sh index bfe08f2082a..cf15acf8d0c 100755 --- a/samples/csvparser/build.sh +++ b/samples/csvparser/build.sh @@ -22,9 +22,9 @@ COMPILER_ARGS=${!var} # add -opt for an optimized build. mkdir -p $DIR/build/c_interop/ 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 \ - -o $DIR/build/bin/CsvParser.kexe || exit 1 +konanc $COMPILER_ARGS -target $TARGET $DIR/src/main/kotlin/CsvParser.kt -library $DIR/build/c_interop/stdio \ + -o $DIR/build/bin/CsvParser || exit 1 echo "Artifact path is ./build/bin/CsvParser.kexe" diff --git a/samples/gitchurn/build.sh b/samples/gitchurn/build.sh index d5e7d526d96..c85f1af2b87 100755 --- a/samples/gitchurn/build.sh +++ b/samples/gitchurn/build.sh @@ -27,9 +27,9 @@ mkdir -p $DIR/build/c_interop/ mkdir -p $DIR/build/bin/ 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" \ - -o $DIR/build/bin/GitChurn.kexe || exit 1 +konanc -target $TARGET $DIR/src/main/kotlin -library $DIR/build/c_interop/libgit2 -linkerOpts "$LINKER_ARGS" \ + -o $DIR/build/bin/GitChurn || exit 1 echo "Artifact path is ./build/bin/GitChurn.kexe" diff --git a/samples/gtk/build.sh b/samples/gtk/build.sh index 88c019149b1..7baec68dad5 100755 --- a/samples/gtk/build.sh +++ b/samples/gtk/build.sh @@ -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 \ -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 \ - -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" \ - -o $DIR/build/bin/Gtk3Demo.kexe || exit 1 + -o $DIR/build/bin/Gtk3Demo || exit 1 -echo "Artifact path is ./build/bin/Gtk3Demo.kexe" \ No newline at end of file +echo "Artifact path is ./build/bin/Gtk3Demo.kexe" diff --git a/samples/libcurl/build.sh b/samples/libcurl/build.sh index 7ed9d3bfa99..4aa95f50812 100755 --- a/samples/libcurl/build.sh +++ b/samples/libcurl/build.sh @@ -27,9 +27,9 @@ mkdir -p $DIR/build/c_interop/ 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 \ - -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" \ - -o $DIR/build/bin/Curl.kexe || exit 1 +konanc -target $TARGET $DIR/src/main/kotlin -library $DIR/build/c_interop/libcurl -linkerOpts "$LINKER_ARGS" \ + -o $DIR/build/bin/Curl || exit 1 echo "Artifact path is ./build/bin/Curl.kexe" diff --git a/samples/nonBlockingEchoServer/build.sh b/samples/nonBlockingEchoServer/build.sh index a5ed9cf90f0..5b1c53d876d 100755 --- a/samples/nonBlockingEchoServer/build.sh +++ b/samples/nonBlockingEchoServer/build.sh @@ -22,9 +22,9 @@ mkdir -p $DIR/build/c_interop/ mkdir -p $DIR/build/bin/ 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 \ - -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" \ No newline at end of file +echo "Artifact path is ./build/bin/EchoServer.kexe" diff --git a/samples/opengl/build.sh b/samples/opengl/build.sh index 8b6743abb68..e2c85c30f36 100755 --- a/samples/opengl/build.sh +++ b/samples/opengl/build.sh @@ -25,9 +25,9 @@ mkdir -p $DIR/build/c_interop/ mkdir -p $DIR/build/bin/ 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 \ - -linkerOpts "$LINKER_ARGS" -o $DIR/build/bin/OpenGlTeapot.kexe || exit 1 +konanc -target $TARGET $DIR/src/main/kotlin/OpenGlTeapot.kt -library $DIR/build/c_interop/opengl \ + -linkerOpts "$LINKER_ARGS" -o $DIR/build/bin/OpenGlTeapot || exit 1 echo "Artifact path is ./build/bin/OpenGlTeapot.kexe" diff --git a/samples/socket/build.sh b/samples/socket/build.sh index e34f5406427..0bb7fe48e38 100755 --- a/samples/socket/build.sh +++ b/samples/socket/build.sh @@ -22,10 +22,10 @@ mkdir -p $DIR/build/c_interop/ mkdir -p $DIR/build/bin/ 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 \ - -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" \ No newline at end of file +echo "Artifact path is ./build/bin/EchoServer.kexe" diff --git a/samples/tensorflow/build.sh b/samples/tensorflow/build.sh index 9b977f81253..c04aa1a671f 100755 --- a/samples/tensorflow/build.sh +++ b/samples/tensorflow/build.sh @@ -30,11 +30,11 @@ mkdir -p $DIR/build/c_interop/ mkdir -p $DIR/build/bin/ 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 \ - -library $DIR/build/c_interop/tensorflow.kt.bc \ - -o $DIR/build/bin/HelloTensorflow.kexe \ + -library $DIR/build/c_interop/tensorflow \ + -o $DIR/build/bin/HelloTensorflow \ -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." diff --git a/samples/tetris/build.bat b/samples/tetris/build.bat index 1a438a10da2..dc685ef7181 100644 --- a/samples/tetris/build.bat +++ b/samples/tetris/build.bat @@ -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 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 src\main\resources\tetris_all.bmp tetris_all.bmp diff --git a/samples/tetris/build.sh b/samples/tetris/build.sh index 49ea30a7968..48a14f78c08 100755 --- a/samples/tetris/build.sh +++ b/samples/tetris/build.sh @@ -45,11 +45,11 @@ COMPILER_ARGS=${!var} # add -opt for an optimized build. mkdir -p $DIR/build/c_interop/ 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 \ - -library $DIR/build/c_interop/sdl.kt.bc -linkerOpts "$LINKER_ARGS" \ - -o $DIR/build/bin/Tetris.kexe || exit 1 + -library $DIR/build/c_interop/sdl -linkerOpts "$LINKER_ARGS" \ + -o $DIR/build/bin/Tetris || exit 1 cp -R $DIR/src/main/resources/ $DIR/build/bin/ diff --git a/samples/win32/build.bat b/samples/win32/build.bat index b31cfb5a7da..c53f3f570cd 100644 --- a/samples/win32/build.bat +++ b/samples/win32/build.bat @@ -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 konanc -target "%TARGET%" "%DIR%\src\main\kotlin\MessageBox.kt" -library win32 -linkerOpts "%LFLAGS%" -opt -o MessageBox || exit /b - -copy MessageBox.kexe MessageBox.exe diff --git a/settings.gradle b/settings.gradle index f6ae4714819..2433157663a 100644 --- a/settings.gradle +++ b/settings.gradle @@ -24,6 +24,7 @@ include ':backend.native' include ':runtime' include ':common' include ':backend.native:tests' +include ':shared' include ':tools:helpers' include ':tools:kotlin-native-gradle-plugin' include ':utilities' diff --git a/shared/build.gradle b/shared/build.gradle new file mode 100644 index 00000000000..83688959f5a --- /dev/null +++ b/shared/build.gradle @@ -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" +} diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanTarget.kt b/shared/src/main/kotlin/org/jetbrains/kotlin/konan/target/KonanTarget.kt similarity index 68% rename from backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanTarget.kt rename to shared/src/main/kotlin/org/jetbrains/kotlin/konan/target/KonanTarget.kt index a1770ffa597..ea473189f5d 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanTarget.kt +++ b/shared/src/main/kotlin/org/jetbrains/kotlin/konan/target/KonanTarget.kt @@ -14,27 +14,38 @@ * limitations under the License. */ -package org.jetbrains.kotlin.backend.konan - -import org.jetbrains.kotlin.config.CompilerConfiguration - -enum class KonanTarget(val suffix: String, var enabled: Boolean = false) { - ANDROID_ARM32("android_arm32"), - ANDROID_ARM64("android_arm64"), - IPHONE("ios"), - IPHONE_SIM("ios_sim"), - LINUX("linux"), - MINGW("mingw"), - MACBOOK("osx"), - RASPBERRYPI("raspberrypi") +package org.jetbrains.kotlin.konan.target + +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 CompilerOutputKind { + PROGRAM { + override fun suffix(target: KonanTarget?) = ".${target!!.programSuffix}" + }, + LIBRARY { + override fun suffix(target: KonanTarget?) = ".klib" + } , + BITCODE { + override fun suffix(target: KonanTarget?) = ".bc" + }; + + abstract fun suffix(target: KonanTarget? = null): String } 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 current = determineCurrent() - val currentName - get() = current.name.toLowerCase() + val target = determineCurrent() + val targetName + get() = target.name.toLowerCase() init { when (host) { @@ -57,10 +68,6 @@ class TargetManager(val userRequest: String? = null) { else -> error("Unknown host platform: $host") } - - if (!current.enabled) { - error("Target $current is not available on the current host") - } } fun known(name: String): String { @@ -71,9 +78,9 @@ class TargetManager(val userRequest: String? = null) { } fun list() { - targets.forEach { key, target -> - if (target.enabled) { - val isDefault = if (target == current) "(default)" else "" + targets.forEach { key, it -> + if (it.enabled) { + val isDefault = if (it == target) "(default)" else "" println(String.format("%1$-30s%2$-10s", "$key:", "$isDefault")) } } @@ -87,10 +94,12 @@ class TargetManager(val userRequest: String? = null) { } } - fun hostSuffix() = host.suffix - fun hostTargetSuffix() = - if (current == host) host.suffix else "${host.suffix}-${current.suffix}" - fun targetSuffix() = current.suffix + val hostSuffix get() = host.targetSuffix + val hostTargetSuffix get() = + if (target == host) host.targetSuffix else "${host.targetSuffix}-${target.targetSuffix}" + val targetSuffix get() = target.targetSuffix + + val programSuffix get() = CompilerOutputKind.PROGRAM.suffix(target) companion object { 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 { val javaArch = System.getProperty("os.arch") return when (javaArch) { diff --git a/tools/kotlin-native-gradle-plugin/build.gradle b/tools/kotlin-native-gradle-plugin/build.gradle index b8dd80e1a7c..22793a64ce9 100644 --- a/tools/kotlin-native-gradle-plugin/build.gradle +++ b/tools/kotlin-native-gradle-plugin/build.gradle @@ -48,6 +48,7 @@ repositories { evaluationDependsOn(':tools:helpers') dependencies { + compile project(':shared') compile project(':tools:helpers') compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" compile gradleApi() @@ -57,6 +58,7 @@ jar { dependsOn(':tools:helpers:jar') dependsOn(':cross_dist') from (rootProject.findProject(':tools:helpers').sourceSets.main.output) + from (rootProject.findProject(':shared').sourceSets.main.output) } task deleteDist(type: Delete) { diff --git a/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanCompileTask.kt b/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanCompileTask.kt index cd9b1b471d1..9fd9cd7e87f 100644 --- a/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanCompileTask.kt +++ b/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanCompileTask.kt @@ -67,7 +67,7 @@ import java.io.File // TODO: form groups for tasks // TODO: Make the task class nested for config with properties accessible for outer users. -open class KonanCompileTask: DefaultTask() { +open class KonanCompileTask: KonanTargetableTask() { companion object { const val COMPILER_MAIN = "org.jetbrains.kotlin.cli.bc.K2NativeKt" @@ -89,13 +89,17 @@ open class KonanCompileTask: DefaultTask() { internal fun init(artifactName: String) { dependsOn(project.konanCompilerDownloadTask) 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 - get() = "${outputDir.absolutePath}/$artifactName.${artifactSuffix[produce]}" + get() = "$artifactNamePath$artifactSuffix" // Other compilation parameters ------------------------------------------- @@ -119,8 +123,6 @@ open class KonanCompileTask: DefaultTask() { @Input var enableAssertions = false internal set - @Optional @Input var target : String? = null - internal set @Optional @Input var languageVersion : String? = null internal set @Optional @Input var apiVersion : String? = null @@ -133,7 +135,7 @@ open class KonanCompileTask: DefaultTask() { // Task action ------------------------------------------------------------ protected fun buildArgs() = mutableListOf().apply { - addArg("-output", artifactPath) + addArg("-output", artifactNamePath) addFileArgs("-library", libraries) addFileArgs("-nativelibrary", nativeLibraries) @@ -219,7 +221,7 @@ open class KonanCompileConfig( compilationTask.dependsOn(generateStubsTask) linkerOpts(generateStubsTask.linkerOpts) - library(compileStubsTask.artifactPath) + library(compileStubsTask.artifactNamePath) nativeLibraries(project.fileTree(generateStubsTask.libsDir).apply { builtBy(generateStubsTask) include("**/*.bc") diff --git a/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanCompilerDownloadTask.kt b/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanCompilerDownloadTask.kt index d5af67e012c..308eaf20e33 100644 --- a/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanCompilerDownloadTask.kt +++ b/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanCompilerDownloadTask.kt @@ -20,6 +20,7 @@ import org.gradle.api.DefaultTask import org.gradle.api.GradleScriptException import org.gradle.api.tasks.TaskAction import org.jetbrains.kotlin.konan.DependencyDownloader +import org.jetbrains.kotlin.konan.target.* import java.io.File open class KonanCompilerDownloadTask : DefaultTask() { @@ -28,16 +29,6 @@ open class KonanCompilerDownloadTask : DefaultTask() { internal const val DOWNLOAD_URL = "http://download.jetbrains.com/kotlin/native" 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 @@ -55,4 +46,4 @@ open class KonanCompilerDownloadTask : DefaultTask() { throw GradleScriptException("Cannot download Kotlin Native compiler", e) } } -} \ No newline at end of file +} diff --git a/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanInteropTask.kt b/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanInteropTask.kt index 2f8251ab8ce..6ef8d98ead4 100644 --- a/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanInteropTask.kt +++ b/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanInteropTask.kt @@ -43,7 +43,7 @@ import java.io.File * } */ -open class KonanInteropTask: DefaultTask() { +open class KonanInteropTask: KonanTargetableTask() { internal companion object { 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 get() = "${project.projectDir}/src/main/c_interop" - // Output directories ----------------------------------------------------- /** Directory with autogenerated interop stubs (*.kt) */ @@ -76,11 +75,10 @@ open class KonanInteropTask: DefaultTask() { @Optional @InputFile var defFile: File? = null internal set - @Optional @Input var target: String? = null - internal set @Optional @Input var pkg: String? = null - internal set + internal set @Input lateinit var libName: String + @Optional @Input var linker: String? = null internal set @@ -104,9 +102,8 @@ open class KonanInteropTask: DefaultTask() { classpath = project.fileTree(INTEROP_CLASSPATH).apply { include("*.jar") } jvmArgs(INTEROP_JVM_ARGS) environment("LIBCLANG_DISABLE_CRASH_RECOVERY", "1") - // 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")}") } diff --git a/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanPlugin.kt b/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanPlugin.kt index 9ae119af912..e8bfd1cb5b8 100644 --- a/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanPlugin.kt +++ b/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanPlugin.kt @@ -57,28 +57,29 @@ internal val Project.konanCompilerDownloadTask get() = tasks.getByName(KonanPlu internal val Project.konanVersion 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(' ') - if (targets.contains("all")) { - return target?.isSupported() ?: true - } else { - return target == null || targets.contains(target) - } + + return (targets.contains(target) || + targets.contains("all") || + target == null) } -internal val Project.supportedCompileTasks: TaskCollection - get() { +internal fun Project.targetIsSupportedAndRequested(task: KonanTargetableTask) + = task.targetIsSupported && this.targetIsRequested(task.target) - return project.tasks.withType(KonanCompileTask::class.java).matching { isTargetSupported(it.target) } +internal val Project.supportedCompileTasks: TaskCollection + get() = project.tasks.withType(KonanCompileTask::class.java).matching { + targetIsSupportedAndRequested(it) } internal val Project.supportedInteropTasks: TaskCollection - get() { - return project.tasks.withType(KonanInteropTask::class.java).matching { isTargetSupported(it.target) } + get() = project.tasks.withType(KonanInteropTask::class.java).matching { + targetIsSupportedAndRequested(it) } internal fun Project.konanCompilerName(): String = - "kotlin-native-${KonanCompilerDownloadTask.simpleOsName()}-${this.konanVersion}" + "kotlin-native-${project.simpleOsName}-${this.konanVersion}" internal fun Project.konanCompilerDownloadDir(): String = 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) : Plugin { @@ -230,14 +220,8 @@ class KonanPlugin @Inject constructor(private val registry: ToolingModelBuilderR if (!project.extensions.extraProperties.has(KonanPlugin.KONAN_HOME_PROPERTY_NAME)) { 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)) { - project.extensions.extraProperties.set(KonanPlugin.KONAN_BUILD_TARGETS, hostTarget) + project.extensions.extraProperties.set(KonanPlugin.KONAN_BUILD_TARGETS, project.host) } getTask(project, "build").apply { dependsOn(project.supportedCompileTasks) @@ -246,8 +230,8 @@ class KonanPlugin @Inject constructor(private val registry: ToolingModelBuilderR getOrCreateTask(project, "run").apply { dependsOn(getTask(project, "build")) doLast { - for (task in project.tasks.withType(KonanCompileTask::class.java).matching { it.target?.equals(hostTarget) ?: true}) { - if (task.artifactPath.endsWith("kexe")) { + for (task in project.tasks.withType(KonanCompileTask::class.java).matching { !it.isCrossCompile}) { + if (task?.produce == "program") { project.exec { with(it) { commandLine(task.artifactPath) diff --git a/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanTargetableTask.kt b/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanTargetableTask.kt new file mode 100644 index 00000000000..1b5ee26b3b7 --- /dev/null +++ b/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanTargetableTask.kt @@ -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()