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>).
outputDir 'path/to/output/dir'
// *.kt.bc library for linking.
// *.klib library for linking.
library project.file('path/to/library')
// 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:
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
+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
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.
+5 -1
View File
@@ -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
@@ -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<Runnable>
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<K2NativeCompilerArguments>() {
// 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<K2NativeCompilerArguments>() {
}
}
maybeExecuteHelper(configuration)
maybeExecuteHelper(arguments.target ?: "host")
}
override fun createArguments(): K2NativeCompilerArguments {
@@ -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 = "<path>", description = "Output file path")
@JvmField var outputFile: String? = null
@field:Argument(value = "-output", shortName = "-o", valueDescription = "<name>", description = "Output name")
@JvmField var outputName: String? = null
@field:Argument(value = "-entry", shortName = "-e", valueDescription = "<name>", 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 = "<path>", description = "Override standard 'konan.properties' location")
@@ -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")}"
@@ -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))
internal val targetManager = TargetManager(configuration)
internal val distribution = Distribution(configuration)
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))
val moduleId: String
// This is a decision we could change
get() = outputName
private val libraryNames: List<String>
get() {
@@ -51,7 +72,7 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration
internal val libraries: List<KonanLibraryReader> 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)}
}
@@ -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<Boolean>
= CompilerConfigurationKey.create("optimized compilation")
val OUTPUT_FILE: CompilerConfigurationKey<String>
= CompilerConfigurationKey.create("final executable file path")
val OUTPUT_NAME: CompilerConfigurationKey<String>
val OUTPUT: CompilerConfigurationKey<String>
= CompilerConfigurationKey.create("program or library name")
val PRINT_BITCODE: CompilerConfigurationKey<Boolean>
= 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.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()
@@ -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,
@@ -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<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)) +
distribution.libffi +
asLinkerArgs(config.getNotNull(KonanConfigKeys.LINKER_ARGS)) +
@@ -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
@@ -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() {
@@ -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"
}
@@ -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(
@@ -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
@@ -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.
}
}
}
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?
//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()
+1 -1
View File
@@ -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"
+4 -10
View File
@@ -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()
}
}
+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.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<Any?> = 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)
+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.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 <command> <library> <options>")
@@ -113,7 +113,7 @@ fun main(args: Array<String>) {
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()
+3 -3
View File
@@ -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"
+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/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"
+3 -3
View File
@@ -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"
+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 \
-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"
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/
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"
+3 -3
View File
@@ -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"
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/
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"
+4 -4
View File
@@ -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"
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/
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."
-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 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
+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/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/
-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 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 ':common'
include ':backend.native:tests'
include ':shared'
include ':tools:helpers'
include ':tools:kotlin-native-gradle-plugin'
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.
*/
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) {
ANDROID_ARM32("android_arm32"),
ANDROID_ARM64("android_arm64"),
IPHONE("ios"),
IPHONE_SIM("ios_sim"),
LINUX("linux"),
MINGW("mingw"),
MACBOOK("osx"),
RASPBERRYPI("raspberrypi")
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) {
@@ -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) {
@@ -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<String>().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")
@@ -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)
}
}
}
}
@@ -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")}")
}
@@ -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<KonanCompileTask>
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<KonanCompileTask>
get() = project.tasks.withType(KonanCompileTask::class.java).matching {
targetIsSupportedAndRequested(it)
}
internal val Project.supportedInteropTasks: TaskCollection<KonanInteropTask>
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<ProjectInternal> {
@@ -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)
@@ -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()