Skip to content

Commit

Permalink
Different extensions (and KonanTarget communalization). (JetBrains#665)
Browse files Browse the repository at this point in the history
  • Loading branch information
alexander-gorshenev authored and olonho committed Jun 19, 2017
1 parent c57ad51 commit d3c24bb
Show file tree
Hide file tree
Showing 51 changed files with 414 additions and 240 deletions.
2 changes: 1 addition & 1 deletion GRADLE_PLUGIN.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
12 changes: 6 additions & 6 deletions INTEROP.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion RELEASE_NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down
6 changes: 5 additions & 1 deletion backend.native/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down Expand Up @@ -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
Expand Down
20 changes: 5 additions & 15 deletions backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2Native.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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,
Expand Down Expand Up @@ -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) }
Expand Down Expand Up @@ -154,7 +144,7 @@ class K2Native : CLICompiler<K2NativeCompilerArguments>() {
}
}

maybeExecuteHelper(configuration)
maybeExecuteHelper(arguments.target ?: "host")
}

override fun createArguments(): K2NativeCompilerArguments {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand All @@ -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"
Expand All @@ -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")}"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<String>
get() {
Expand All @@ -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)}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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")
Expand Down Expand Up @@ -95,8 +94,3 @@ class KonanConfigKeys {
}
}

enum class CompilerOutputKind(val suffix: String) {
PROGRAM(".kexe"),
LIBRARY(".klib"),
BITCODE(".bc")
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 ->
Expand All @@ -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
Expand Down Expand Up @@ -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)) +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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(
Expand Down
Loading

0 comments on commit d3c24bb

Please sign in to comment.