Different extensions (and KonanTarget communalization). (#665)
This commit is contained in:
committed by
Nikolay Igotti
parent
c57ad51fc7
commit
d3c24bb387
@@ -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")
|
||||
|
||||
+10
-11
@@ -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")}"
|
||||
|
||||
+26
-5
@@ -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)}
|
||||
}
|
||||
|
||||
+2
-8
@@ -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")
|
||||
}
|
||||
|
||||
+2
@@ -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()
|
||||
|
||||
+1
@@ -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,
|
||||
|
||||
-124
@@ -1,124 +0,0 @@
|
||||
/*
|
||||
* 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.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")
|
||||
}
|
||||
|
||||
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()
|
||||
|
||||
init {
|
||||
when (host) {
|
||||
KonanTarget.LINUX -> {
|
||||
KonanTarget.LINUX.enabled = true
|
||||
KonanTarget.RASPBERRYPI.enabled = true
|
||||
KonanTarget.ANDROID_ARM32.enabled = true
|
||||
KonanTarget.ANDROID_ARM64.enabled = true
|
||||
}
|
||||
KonanTarget.MINGW -> {
|
||||
KonanTarget.MINGW.enabled = true
|
||||
}
|
||||
KonanTarget.MACBOOK -> {
|
||||
KonanTarget.MACBOOK.enabled = true
|
||||
KonanTarget.IPHONE.enabled = true
|
||||
KonanTarget.IPHONE_SIM.enabled = true
|
||||
KonanTarget.ANDROID_ARM32.enabled = true
|
||||
KonanTarget.ANDROID_ARM64.enabled = true
|
||||
}
|
||||
else ->
|
||||
error("Unknown host platform: $host")
|
||||
}
|
||||
|
||||
if (!current.enabled) {
|
||||
error("Target $current is not available on the current host")
|
||||
}
|
||||
}
|
||||
|
||||
fun known(name: String): String {
|
||||
if (targets[name] == null) {
|
||||
error("Unknown target: $name. Use -list_targets to see the list of available targets")
|
||||
}
|
||||
return name
|
||||
}
|
||||
|
||||
fun list() {
|
||||
targets.forEach { key, target ->
|
||||
if (target.enabled) {
|
||||
val isDefault = if (target == current) "(default)" else ""
|
||||
println(String.format("%1$-30s%2$-10s", "$key:", "$isDefault"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun determineCurrent(): KonanTarget {
|
||||
return if (userRequest == null || userRequest == "host") {
|
||||
host
|
||||
} else {
|
||||
targets[known(userRequest)]!!
|
||||
}
|
||||
}
|
||||
|
||||
fun hostSuffix() = host.suffix
|
||||
fun hostTargetSuffix() =
|
||||
if (current == host) host.suffix else "${host.suffix}-${current.suffix}"
|
||||
fun targetSuffix() = current.suffix
|
||||
|
||||
companion object {
|
||||
fun host_os(): String {
|
||||
val javaOsName = System.getProperty("os.name")
|
||||
return when {
|
||||
javaOsName == "Mac OS X" -> "osx"
|
||||
javaOsName == "Linux" -> "linux"
|
||||
javaOsName.startsWith("Windows") -> "windows"
|
||||
else -> error("Unknown operating system: ${javaOsName}")
|
||||
}
|
||||
}
|
||||
|
||||
fun host_arch(): String {
|
||||
val javaArch = System.getProperty("os.arch")
|
||||
return when (javaArch) {
|
||||
"x86_64" -> "x86_64"
|
||||
"amd64" -> "x86_64"
|
||||
"arm64" -> "arm64"
|
||||
else -> error("Unknown hardware platform: ${javaArch}")
|
||||
}
|
||||
}
|
||||
|
||||
val host: KonanTarget = when (host_os()) {
|
||||
"osx" -> KonanTarget.MACBOOK
|
||||
"linux" -> KonanTarget.LINUX
|
||||
"windows" -> KonanTarget.MINGW
|
||||
else -> error("Unknown host target: ${host_os()} ${host_arch()}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+4
-3
@@ -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)) +
|
||||
|
||||
-1
@@ -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
|
||||
|
||||
+2
-2
@@ -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() {
|
||||
|
||||
+2
-2
@@ -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"
|
||||
}
|
||||
|
||||
+1
-2
@@ -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(
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
+51
-51
@@ -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()
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user