Initial checkin of klib support.
The libraries exist in two incarnations:
packed foo.klib and unpacked foo/ .
The compiler when given '-library foo' expects to find either
a foo.klib file and unpack it, or an already unpacked foo/ directory.
The stdlib is always unpacked in dist/klib .
The semantics of -o has changed slightly.
It now accepts '-o foo' and the compiler
either produces foo.kexe or foo.klib .
This commit is contained in:
committed by
alexander-gorshenev
parent
77e093354f
commit
3b5ce031f8
@@ -38,6 +38,9 @@ model {
|
|||||||
include '**/*.c'
|
include '**/*.c'
|
||||||
}
|
}
|
||||||
binaries.all {
|
binaries.all {
|
||||||
|
def host = rootProject.ext.host
|
||||||
|
def hostLibffiDir = rootProject.ext.get("${host}LibffiDir")
|
||||||
|
|
||||||
cCompiler.args compilerArgsForJniIncludes
|
cCompiler.args compilerArgsForJniIncludes
|
||||||
cCompiler.args "-I$hostLibffiDir/include"
|
cCompiler.args "-I$hostLibffiDir/include"
|
||||||
|
|
||||||
|
|||||||
+10
-10
@@ -153,7 +153,7 @@ kotlinNativeInterop {
|
|||||||
compilerOpts '-fPIC'
|
compilerOpts '-fPIC'
|
||||||
linkerOpts '-fPIC'
|
linkerOpts '-fPIC'
|
||||||
linker 'clang++'
|
linker 'clang++'
|
||||||
linkOutputs ':common:hostHash'
|
linkOutputs ":common:${host}Hash"
|
||||||
|
|
||||||
headers fileTree('../common/src/hash/headers') {
|
headers fileTree('../common/src/hash/headers') {
|
||||||
include '**/*.h'
|
include '**/*.h'
|
||||||
@@ -194,8 +194,8 @@ build.dependsOn 'compilerClasses','cli_bcClasses','bc_frontendClasses'
|
|||||||
|
|
||||||
|
|
||||||
// These are just a couple of aliases
|
// These are just a couple of aliases
|
||||||
task stdlib(dependsOn: 'hostStdlib')
|
task stdlib(dependsOn: "${host}Stdlib")
|
||||||
task start(dependsOn: 'hostStart')
|
task start(dependsOn: "${host}Start")
|
||||||
|
|
||||||
// These files are built before the 'dist' is complete,
|
// These files are built before the 'dist' is complete,
|
||||||
// so we provide custom values for
|
// so we provide custom values for
|
||||||
@@ -208,8 +208,8 @@ targetList.each { target ->
|
|||||||
jvmArgs "-ea",
|
jvmArgs "-ea",
|
||||||
"-Dkonan.home=${project.parent.file('dist')}",
|
"-Dkonan.home=${project.parent.file('dist')}",
|
||||||
"-Djava.library.path=${project.buildDir}/nativelibs"
|
"-Djava.library.path=${project.buildDir}/nativelibs"
|
||||||
args('-output', project(':runtime').file("build/${target}/stdlib.kt.bc"),
|
args('-output', project(':runtime').file("build/${target}Stdlib"),
|
||||||
'-nolink', '-nostdlib', '-ea',
|
'-nolink', '-nopack', '-nostdlib','-ea',
|
||||||
'-target', target,
|
'-target', target,
|
||||||
'-runtime', project(':runtime').file("build/${target}/runtime.bc"),
|
'-runtime', project(':runtime').file("build/${target}/runtime.bc"),
|
||||||
'-properties', project(':backend.native').file('konan.properties'),
|
'-properties', project(':backend.native').file('konan.properties'),
|
||||||
@@ -221,7 +221,7 @@ targetList.each { target ->
|
|||||||
inputs.dir(project(':runtime').file('src/main/kotlin'))
|
inputs.dir(project(':runtime').file('src/main/kotlin'))
|
||||||
inputs.dir(project(':Interop:Runtime').file('src/main/kotlin'))
|
inputs.dir(project(':Interop:Runtime').file('src/main/kotlin'))
|
||||||
inputs.dir(project(':Interop:Runtime').file('src/native/kotlin'))
|
inputs.dir(project(':Interop:Runtime').file('src/native/kotlin'))
|
||||||
outputs.file(project(':runtime').file("build/${target}/stdlib.kt.bc"))
|
outputs.file(project(':runtime').file("build/${target}Stdlib"))
|
||||||
|
|
||||||
dependsOn ":runtime:${target}Runtime"
|
dependsOn ":runtime:${target}Runtime"
|
||||||
}
|
}
|
||||||
@@ -234,17 +234,17 @@ targetList.each { target ->
|
|||||||
jvmArgs "-ea",
|
jvmArgs "-ea",
|
||||||
"-Dkonan.home=${project.parent.file('dist')}",
|
"-Dkonan.home=${project.parent.file('dist')}",
|
||||||
"-Djava.library.path=${project.buildDir}/nativelibs"
|
"-Djava.library.path=${project.buildDir}/nativelibs"
|
||||||
args('-output', project(':runtime').file("build/${target}/start.kt.bc"),
|
args('-output', project(':runtime').file("build/${target}Start"),
|
||||||
'-nolink', '-nostdlib', '-ea',
|
'-nolink', '-nopack', '-nostdlib', '-ea',
|
||||||
'-target', target,
|
'-target', target,
|
||||||
'-library', project(':runtime').file("build/${target}/stdlib.kt.bc"),
|
'-library', project(':runtime').file("build/${target}Stdlib"),
|
||||||
'-runtime', project(':runtime').file("build/${target}/runtime.bc"),
|
'-runtime', project(':runtime').file("build/${target}/runtime.bc"),
|
||||||
'-properties', project(':backend.native').file('konan.properties'),
|
'-properties', project(':backend.native').file('konan.properties'),
|
||||||
project(':runtime').file('src/launcher/kotlin'),
|
project(':runtime').file('src/launcher/kotlin'),
|
||||||
*project.globalBuildArgs)
|
*project.globalBuildArgs)
|
||||||
|
|
||||||
inputs.dir(project(':runtime').file('src/launcher/kotlin'))
|
inputs.dir(project(':runtime').file('src/launcher/kotlin'))
|
||||||
outputs.file(project(':runtime').file("build/${target}/start.kt.bc"))
|
outputs.file(project(':runtime').file("build/${target}Start"))
|
||||||
|
|
||||||
dependsOn ":runtime:${target}Runtime", "${target}Stdlib"
|
dependsOn ":runtime:${target}Runtime", "${target}Stdlib"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -90,36 +90,38 @@ class K2Native : CLICompiler<K2NativeCompilerArguments>() {
|
|||||||
|
|
||||||
put(NOSTDLIB, arguments.nostdlib)
|
put(NOSTDLIB, arguments.nostdlib)
|
||||||
put(NOLINK, arguments.nolink)
|
put(NOLINK, arguments.nolink)
|
||||||
|
put(NOPACK, arguments.nopack)
|
||||||
put(NOMAIN, arguments.nomain)
|
put(NOMAIN, arguments.nomain)
|
||||||
put(LIBRARY_FILES,
|
put(LIBRARY_FILES,
|
||||||
arguments.libraries.toNonNullList())
|
arguments.libraries.toNonNullList())
|
||||||
|
|
||||||
put(LINKER_ARGS, arguments.linkerArguments.toNonNullList())
|
put(LINKER_ARGS, arguments.linkerArguments.toNonNullList())
|
||||||
|
if (arguments.target != null)
|
||||||
|
put(TARGET, arguments.target)
|
||||||
|
|
||||||
put(NATIVE_LIBRARY_FILES,
|
put(NATIVE_LIBRARY_FILES,
|
||||||
arguments.nativeLibraries.toNonNullList())
|
arguments.nativeLibraries.toNonNullList())
|
||||||
|
|
||||||
// TODO: Collect all the explicit file names into an object
|
// TODO: Collect all the explicit file names into an object
|
||||||
// and teach the compiler to work with temporaries and -save-temps.
|
// and teach the compiler to work with temporaries and -save-temps.
|
||||||
val bitcodeFile = if (arguments.nolink) {
|
val library = arguments.outputFile ?: "library"
|
||||||
arguments.outputFile ?: "program.kt.bc"
|
if (arguments.nolink)
|
||||||
} else {
|
put(LIBRARY_NAME, library)
|
||||||
"${arguments.outputFile ?: "program"}.kt.bc"
|
put(LIBRARY_FILE, "${library}.klib")
|
||||||
|
val program = arguments.outputFile ?: "program"
|
||||||
|
if (!arguments.nolink) {
|
||||||
|
put(PROGRAM_NAME,program)
|
||||||
|
put(EXECUTABLE_FILE,"${program}.kexe")
|
||||||
}
|
}
|
||||||
put(BITCODE_FILE, bitcodeFile)
|
|
||||||
|
|
||||||
// This is a decision we could change
|
// This is a decision we could change
|
||||||
put(CommonConfigurationKeys.MODULE_NAME, bitcodeFile)
|
val module = if (arguments.nolink) library else program
|
||||||
|
put(CommonConfigurationKeys.MODULE_NAME, module)
|
||||||
put(ABI_VERSION, 1)
|
put(ABI_VERSION, 1)
|
||||||
|
|
||||||
put(EXECUTABLE_FILE,
|
|
||||||
arguments.outputFile ?: "program.kexe")
|
|
||||||
if (arguments.runtimeFile != null)
|
if (arguments.runtimeFile != null)
|
||||||
put(RUNTIME_FILE, arguments.runtimeFile)
|
put(RUNTIME_FILE, arguments.runtimeFile)
|
||||||
if (arguments.propertyFile != null)
|
if (arguments.propertyFile != null)
|
||||||
put(PROPERTY_FILE, arguments.propertyFile)
|
put(PROPERTY_FILE, arguments.propertyFile)
|
||||||
if (arguments.target != null)
|
|
||||||
put(TARGET, arguments.target)
|
|
||||||
put(LIST_TARGETS, arguments.listTargets)
|
put(LIST_TARGETS, arguments.listTargets)
|
||||||
put(OPTIMIZATION, arguments.optimization)
|
put(OPTIMIZATION, arguments.optimization)
|
||||||
put(DEBUG, arguments.debug)
|
put(DEBUG, arguments.debug)
|
||||||
|
|||||||
@@ -38,6 +38,9 @@ public class K2NativeCompilerArguments extends CommonCompilerArguments {
|
|||||||
@Argument(value = "-nolink", description = "Don't link, just produce a bitcode file")
|
@Argument(value = "-nolink", description = "Don't link, just produce a bitcode file")
|
||||||
public boolean nolink;
|
public boolean nolink;
|
||||||
|
|
||||||
|
@Argument(value = "-nopack", description = "Don't pack the library into a klib file")
|
||||||
|
public boolean nopack;
|
||||||
|
|
||||||
@Argument(value = "-nomain", description = "Assume 'main' entry point to be provided by external libraries")
|
@Argument(value = "-nomain", description = "Assume 'main' entry point to be provided by external libraries")
|
||||||
public boolean nomain;
|
public boolean nomain;
|
||||||
|
|
||||||
|
|||||||
+2
-5
@@ -55,11 +55,6 @@ import java.util.*
|
|||||||
import kotlin.LazyThreadSafetyMode.PUBLICATION
|
import kotlin.LazyThreadSafetyMode.PUBLICATION
|
||||||
import kotlin.reflect.KProperty
|
import kotlin.reflect.KProperty
|
||||||
|
|
||||||
internal class LinkData(
|
|
||||||
val module: String,
|
|
||||||
val fragments: List<String>,
|
|
||||||
val fragmentNames: List<String> )
|
|
||||||
|
|
||||||
internal class SpecialDescriptorsFactory(val context: Context) {
|
internal class SpecialDescriptorsFactory(val context: Context) {
|
||||||
private val enumSpecialDescriptorsFactory by lazy { EnumSpecialDescriptorsFactory(context) }
|
private val enumSpecialDescriptorsFactory by lazy { EnumSpecialDescriptorsFactory(context) }
|
||||||
private val outerThisDescriptors = mutableMapOf<ClassDescriptor, PropertyDescriptor>()
|
private val outerThisDescriptors = mutableMapOf<ClassDescriptor, PropertyDescriptor>()
|
||||||
@@ -270,6 +265,8 @@ internal class Context(config: KonanConfig) : KonanBackendContext(config) {
|
|||||||
|
|
||||||
lateinit var llvm: Llvm
|
lateinit var llvm: Llvm
|
||||||
lateinit var llvmDeclarations: LlvmDeclarations
|
lateinit var llvmDeclarations: LlvmDeclarations
|
||||||
|
lateinit var bitcodeFileName: String
|
||||||
|
lateinit var library: KonanLibraryWriter
|
||||||
|
|
||||||
var phase: KonanPhase? = null
|
var phase: KonanPhase? = null
|
||||||
var depth: Int = 0
|
var depth: Int = 0
|
||||||
|
|||||||
+4
-8
@@ -22,9 +22,7 @@ import java.io.File
|
|||||||
class Distribution(val config: CompilerConfiguration) {
|
class Distribution(val config: CompilerConfiguration) {
|
||||||
|
|
||||||
val targetManager = TargetManager(config)
|
val targetManager = TargetManager(config)
|
||||||
val target =
|
val target = targetManager.currentName
|
||||||
if (!targetManager.crossCompile) "host"
|
|
||||||
else targetManager.current.name.toLowerCase()
|
|
||||||
val suffix = targetManager.currentSuffix()
|
val suffix = targetManager.currentSuffix()
|
||||||
val hostSuffix = TargetManager.host.suffix
|
val hostSuffix = TargetManager.host.suffix
|
||||||
init { if (!targetManager.crossCompile) assert(suffix == hostSuffix) }
|
init { if (!targetManager.crossCompile) assert(suffix == hostSuffix) }
|
||||||
@@ -40,16 +38,14 @@ class Distribution(val config: CompilerConfiguration) {
|
|||||||
?: "$konanHome/konan/konan.properties"
|
?: "$konanHome/konan/konan.properties"
|
||||||
val properties = KonanProperties(propertyFile)
|
val properties = KonanProperties(propertyFile)
|
||||||
|
|
||||||
val lib = "$konanHome/lib/$target"
|
val klib = "$konanHome/klib"
|
||||||
|
|
||||||
val dependenciesDir = "$konanHome/dependencies"
|
val dependenciesDir = "$konanHome/dependencies"
|
||||||
val dependencies = properties.propertyList("dependencies.$suffix")
|
val dependencies = properties.propertyList("dependencies.$suffix")
|
||||||
|
|
||||||
val stdlib = "$lib/stdlib.kt.bc"
|
val stdlib = "$klib/stdlib"
|
||||||
val start = "$lib/start.kt.bc"
|
|
||||||
val launcher = "$lib/launcher.bc"
|
|
||||||
val runtime = config.get(KonanConfigKeys.RUNTIME_FILE)
|
val runtime = config.get(KonanConfigKeys.RUNTIME_FILE)
|
||||||
?: "$lib/runtime.bc"
|
?: "$stdlib/$target/native/runtime.bc"
|
||||||
|
|
||||||
val llvmHome = "$dependenciesDir/${properties.propertyString("llvmHome.$hostSuffix")}"
|
val llvmHome = "$dependenciesDir/${properties.propertyString("llvmHome.$hostSuffix")}"
|
||||||
val sysRoot = "$dependenciesDir/${properties.propertyString("sysRoot.$hostSuffix")}"
|
val sysRoot = "$dependenciesDir/${properties.propertyString("sysRoot.$hostSuffix")}"
|
||||||
|
|||||||
+4
-4
@@ -28,6 +28,7 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration
|
|||||||
val moduleId: String
|
val moduleId: String
|
||||||
get() = configuration.getNotNull(CommonConfigurationKeys.MODULE_NAME)
|
get() = configuration.getNotNull(CommonConfigurationKeys.MODULE_NAME)
|
||||||
|
|
||||||
|
internal val targetManager = TargetManager(configuration)
|
||||||
internal val distribution = Distribution(configuration)
|
internal val distribution = Distribution(configuration)
|
||||||
|
|
||||||
private val libraryNames: List<String>
|
private val libraryNames: List<String>
|
||||||
@@ -39,16 +40,15 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration
|
|||||||
return fromCommandLine + distribution.stdlib
|
return fromCommandLine + distribution.stdlib
|
||||||
}
|
}
|
||||||
|
|
||||||
internal val libraries: List<KonanLibrary> by lazy {
|
internal val libraries: List<KonanLibraryReader> by lazy {
|
||||||
// Here we have chosen a particular .kt.bc KonanLibrary implementation
|
// Here we have chosen a particular KonanLibraryReader implementation
|
||||||
libraryNames.map{it -> KtBcLibrary(it, configuration)}
|
libraryNames.map{it -> SplitLibraryReader(it, configuration)}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val loadedDescriptors = loadLibMetadata()
|
private val loadedDescriptors = loadLibMetadata()
|
||||||
|
|
||||||
internal val nativeLibraries: List<String> = configuration.getList(KonanConfigKeys.NATIVE_LIBRARY_FILES)
|
internal val nativeLibraries: List<String> = configuration.getList(KonanConfigKeys.NATIVE_LIBRARY_FILES)
|
||||||
|
|
||||||
|
|
||||||
fun loadLibMetadata(): List<ModuleDescriptorImpl> {
|
fun loadLibMetadata(): List<ModuleDescriptorImpl> {
|
||||||
|
|
||||||
val allMetadata = mutableListOf<ModuleDescriptorImpl>()
|
val allMetadata = mutableListOf<ModuleDescriptorImpl>()
|
||||||
|
|||||||
+8
-2
@@ -25,8 +25,12 @@ class KonanConfigKeys {
|
|||||||
= CompilerConfigurationKey.create("library file paths")
|
= CompilerConfigurationKey.create("library file paths")
|
||||||
val NATIVE_LIBRARY_FILES: CompilerConfigurationKey<List<String>>
|
val NATIVE_LIBRARY_FILES: CompilerConfigurationKey<List<String>>
|
||||||
= CompilerConfigurationKey.create("native library file paths")
|
= CompilerConfigurationKey.create("native library file paths")
|
||||||
val BITCODE_FILE: CompilerConfigurationKey<String>
|
val LIBRARY_NAME: CompilerConfigurationKey<String>
|
||||||
= CompilerConfigurationKey.create("emitted bitcode file path")
|
= CompilerConfigurationKey.create("library name")
|
||||||
|
val LIBRARY_FILE: CompilerConfigurationKey<String>
|
||||||
|
= CompilerConfigurationKey.create("library file path")
|
||||||
|
val PROGRAM_NAME: CompilerConfigurationKey<String>
|
||||||
|
= CompilerConfigurationKey.create("program name")
|
||||||
val EXECUTABLE_FILE: CompilerConfigurationKey<String>
|
val EXECUTABLE_FILE: CompilerConfigurationKey<String>
|
||||||
= CompilerConfigurationKey.create("final executable file path")
|
= CompilerConfigurationKey.create("final executable file path")
|
||||||
val RUNTIME_FILE: CompilerConfigurationKey<String?>
|
val RUNTIME_FILE: CompilerConfigurationKey<String?>
|
||||||
@@ -43,6 +47,8 @@ class KonanConfigKeys {
|
|||||||
= CompilerConfigurationKey.create("don't link with stdlib")
|
= CompilerConfigurationKey.create("don't link with stdlib")
|
||||||
val NOLINK: CompilerConfigurationKey<Boolean>
|
val NOLINK: CompilerConfigurationKey<Boolean>
|
||||||
= CompilerConfigurationKey.create("don't link, only produce a bitcode file ")
|
= CompilerConfigurationKey.create("don't link, only produce a bitcode file ")
|
||||||
|
val NOPACK: CompilerConfigurationKey<Boolean>
|
||||||
|
= CompilerConfigurationKey.create("don't the library into a klib file")
|
||||||
val NOMAIN: CompilerConfigurationKey<Boolean>
|
val NOMAIN: CompilerConfigurationKey<Boolean>
|
||||||
= CompilerConfigurationKey.create("assume 'main' entry point to be provided by external libraries")
|
= CompilerConfigurationKey.create("assume 'main' entry point to be provided by external libraries")
|
||||||
val LINKER_ARGS: CompilerConfigurationKey<List<String>>
|
val LINKER_ARGS: CompilerConfigurationKey<List<String>>
|
||||||
|
|||||||
+1
-1
@@ -48,7 +48,7 @@ public fun runTopLevelPhases(konanConfig: KonanConfig, environment: KotlinCoreEn
|
|||||||
|
|
||||||
val config = konanConfig.configuration
|
val config = konanConfig.configuration
|
||||||
|
|
||||||
val targets = TargetManager(config)
|
val targets = konanConfig.targetManager
|
||||||
if (config.get(KonanConfigKeys.LIST_TARGETS) ?: false) {
|
if (config.get(KonanConfigKeys.LIST_TARGETS) ?: false) {
|
||||||
targets.list()
|
targets.list()
|
||||||
}
|
}
|
||||||
|
|||||||
-69
@@ -1,69 +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.descriptors.impl.ModuleDescriptorImpl
|
|
||||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
|
||||||
import org.jetbrains.kotlin.backend.konan.llvm.MetadataReader
|
|
||||||
import org.jetbrains.kotlin.backend.konan.llvm.loadSerializedModule
|
|
||||||
import org.jetbrains.kotlin.backend.konan.llvm.loadSerializedPackageFragment
|
|
||||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
|
||||||
import org.jetbrains.kotlin.name.FqName
|
|
||||||
import org.jetbrains.kotlin.backend.konan.serialization.Base64
|
|
||||||
import org.jetbrains.kotlin.backend.konan.serialization.deserializeModule
|
|
||||||
import java.io.File
|
|
||||||
|
|
||||||
interface KonanLibrary {
|
|
||||||
val libraryName: String
|
|
||||||
val moduleName: String
|
|
||||||
val moduleDescriptor: ModuleDescriptorImpl
|
|
||||||
val bitcodePaths: List<String>
|
|
||||||
}
|
|
||||||
|
|
||||||
class KtBcLibrary(val file: File, val configuration: CompilerConfiguration): KonanLibrary {
|
|
||||||
constructor(path: String, configuration: CompilerConfiguration) : this(File(path), configuration)
|
|
||||||
init {
|
|
||||||
if (!file.exists())
|
|
||||||
error("Path '" + file.path + "' does not exist")
|
|
||||||
}
|
|
||||||
|
|
||||||
override val libraryName: String
|
|
||||||
get() = file.path
|
|
||||||
|
|
||||||
override val bitcodePaths: List<String>
|
|
||||||
get() = listOf(libraryName)
|
|
||||||
|
|
||||||
private val reader = MetadataReader(file)
|
|
||||||
|
|
||||||
private val namedModuleData by lazy {
|
|
||||||
val currentAbiVersion = configuration.get(KonanConfigKeys.ABI_VERSION)!!
|
|
||||||
reader.loadSerializedModule(currentAbiVersion)
|
|
||||||
}
|
|
||||||
override val moduleName = namedModuleData.name
|
|
||||||
|
|
||||||
private val tableOfContentsAsString = namedModuleData.base64
|
|
||||||
|
|
||||||
private fun packageMetadata(fqName: String): Base64 =
|
|
||||||
reader.loadSerializedPackageFragment(fqName)
|
|
||||||
|
|
||||||
override val moduleDescriptor: ModuleDescriptorImpl by lazy {
|
|
||||||
deserializeModule(configuration,
|
|
||||||
{it -> packageMetadata(it)},
|
|
||||||
tableOfContentsAsString, moduleName)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
+1
@@ -77,6 +77,7 @@ object KonanPhases {
|
|||||||
|
|
||||||
// Don't serialize anything to a final executable.
|
// Don't serialize anything to a final executable.
|
||||||
KonanPhase.SERIALIZER.enabled = getBoolean(NOLINK)
|
KonanPhase.SERIALIZER.enabled = getBoolean(NOLINK)
|
||||||
|
KonanPhase.METADATOR.enabled = getBoolean(NOLINK)
|
||||||
|
|
||||||
val disabled = get(DISABLED_PHASES)
|
val disabled = get(DISABLED_PHASES)
|
||||||
disabled?.forEach { phases[known(it)]!!.enabled = false }
|
disabled?.forEach { phases[known(it)]!!.enabled = false }
|
||||||
|
|||||||
+2
@@ -30,6 +30,8 @@ enum class KonanTarget(val suffix: String, var enabled: Boolean = false) {
|
|||||||
class TargetManager(val config: CompilerConfiguration) {
|
class TargetManager(val config: CompilerConfiguration) {
|
||||||
val targets = KonanTarget.values().associate{ it.name.toLowerCase() to it }
|
val targets = KonanTarget.values().associate{ it.name.toLowerCase() to it }
|
||||||
val current = determineCurrent()
|
val current = determineCurrent()
|
||||||
|
val currentName
|
||||||
|
get() = current.name.toLowerCase()
|
||||||
|
|
||||||
init {
|
init {
|
||||||
when (host) {
|
when (host) {
|
||||||
|
|||||||
+4
-5
@@ -147,9 +147,9 @@ internal class LinkStage(val context: Context) {
|
|||||||
|
|
||||||
val config = context.config.configuration
|
val config = context.config.configuration
|
||||||
|
|
||||||
val targetManager = TargetManager(config)
|
val targetManager = context.config.targetManager
|
||||||
private val distribution =
|
private val distribution =
|
||||||
Distribution(context.config.configuration)
|
context.config.distribution
|
||||||
private val properties = distribution.properties
|
private val properties = distribution.properties
|
||||||
|
|
||||||
val platform = when (TargetManager.host) {
|
val platform = when (TargetManager.host) {
|
||||||
@@ -164,8 +164,8 @@ internal class LinkStage(val context: Context) {
|
|||||||
val suffix = targetManager.currentSuffix()
|
val suffix = targetManager.currentSuffix()
|
||||||
|
|
||||||
val optimize = config.get(KonanConfigKeys.OPTIMIZATION) ?: false
|
val optimize = config.get(KonanConfigKeys.OPTIMIZATION) ?: false
|
||||||
val emitted = config.get(KonanConfigKeys.BITCODE_FILE)!!
|
|
||||||
val nomain = config.get(KonanConfigKeys.NOMAIN) ?: false
|
val nomain = config.get(KonanConfigKeys.NOMAIN) ?: false
|
||||||
|
val emitted = context.bitcodeFileName
|
||||||
val libraries = context.config.libraries
|
val libraries = context.config.libraries
|
||||||
|
|
||||||
fun llvmLto(files: List<BitcodeFile>): ObjectFile {
|
fun llvmLto(files: List<BitcodeFile>): ObjectFile {
|
||||||
@@ -265,8 +265,7 @@ internal class LinkStage(val context: Context) {
|
|||||||
fun linkStage() {
|
fun linkStage() {
|
||||||
context.log{"# Compiler root: ${distribution.konanHome}"}
|
context.log{"# Compiler root: ${distribution.konanHome}"}
|
||||||
|
|
||||||
val bitcodeFiles = listOf<BitcodeFile>(emitted, distribution.start,
|
val bitcodeFiles = listOf<BitcodeFile>(emitted) +
|
||||||
distribution.runtime, distribution.launcher) +
|
|
||||||
libraries.map{it -> it.bitcodePaths}.flatten()
|
libraries.map{it -> it.bitcodePaths}.flatten()
|
||||||
|
|
||||||
var objectFiles: List<String> = listOf()
|
var objectFiles: List<String> = listOf()
|
||||||
|
|||||||
+70
@@ -0,0 +1,70 @@
|
|||||||
|
/*
|
||||||
|
* 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 java.io.File
|
||||||
|
import java.net.URI
|
||||||
|
import java.nio.file.FileSystems
|
||||||
|
import java.nio.file.Files
|
||||||
|
import java.nio.file.Path
|
||||||
|
import java.nio.file.StandardCopyOption
|
||||||
|
|
||||||
|
val File.zipUri: URI
|
||||||
|
get() = URI.create("jar:file:${this.absolutePath}")
|
||||||
|
|
||||||
|
val File.zipRootPath: Path
|
||||||
|
get() {
|
||||||
|
val zipUri = this.zipUri
|
||||||
|
val allowCreation = hashMapOf("create" to "true")
|
||||||
|
val zipfs = FileSystems.newFileSystem(zipUri, allowCreation, null)
|
||||||
|
return zipfs.getPath("/")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun File.zipDirAs(zipFile: File) {
|
||||||
|
val zipPath = zipFile.zipRootPath
|
||||||
|
this.toPath().recursiveCopyTo(zipPath)
|
||||||
|
zipPath.fileSystem.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun File.unzipAs(directory: File) {
|
||||||
|
val zipPath = this.zipRootPath
|
||||||
|
zipPath.recursiveCopyTo(directory.toPath())
|
||||||
|
zipPath.fileSystem.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Path.recursiveCopyTo(destPath: Path) {
|
||||||
|
val sourcePath = this
|
||||||
|
Files.walk(sourcePath).forEach next@ { oldPath ->
|
||||||
|
|
||||||
|
val relative = sourcePath.relativize(oldPath)
|
||||||
|
val destFs = destPath.getFileSystem()
|
||||||
|
// We are copying files between file systems,
|
||||||
|
// so pass the relative path through the Sting.
|
||||||
|
val newPath = destFs.getPath(destPath.toString(), relative.toString())
|
||||||
|
|
||||||
|
// File systems don't allow replacing an existing root.
|
||||||
|
if (newPath == newPath.getRoot()) return@next
|
||||||
|
Files.copy(oldPath, newPath,
|
||||||
|
StandardCopyOption.REPLACE_EXISTING)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun File.copyTo(destination: File) {
|
||||||
|
Files.copy(this.toPath(), destination.toPath())
|
||||||
|
}
|
||||||
|
|
||||||
+225
@@ -0,0 +1,225 @@
|
|||||||
|
/*
|
||||||
|
* 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 llvm.LLVMLinkModules2
|
||||||
|
import llvm.LLVMModuleRef
|
||||||
|
import llvm.LLVMWriteBitcodeToFile
|
||||||
|
import org.jetbrains.kotlin.backend.konan.llvm.*
|
||||||
|
import org.jetbrains.kotlin.backend.konan.serialization.Base64
|
||||||
|
import org.jetbrains.kotlin.backend.konan.serialization.deserializeModule
|
||||||
|
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||||
|
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
interface KonanLibraryReader {
|
||||||
|
val libraryName: String
|
||||||
|
val moduleName: String
|
||||||
|
val moduleDescriptor: ModuleDescriptorImpl
|
||||||
|
val bitcodePaths: List<String>
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class FileBasedLibraryReader(
|
||||||
|
val file: File,
|
||||||
|
val configuration: CompilerConfiguration,
|
||||||
|
val reader: MetadataReader): KonanLibraryReader {
|
||||||
|
|
||||||
|
override val libraryName: String
|
||||||
|
get() = file.path
|
||||||
|
|
||||||
|
protected val namedModuleData by lazy {
|
||||||
|
val currentAbiVersion = configuration.get(KonanConfigKeys.ABI_VERSION)!!
|
||||||
|
reader.loadSerializedModule(currentAbiVersion)
|
||||||
|
}
|
||||||
|
|
||||||
|
override val moduleName: String
|
||||||
|
get() = namedModuleData.name
|
||||||
|
|
||||||
|
protected val tableOfContentsAsString : String
|
||||||
|
get() = namedModuleData.base64
|
||||||
|
|
||||||
|
protected fun packageMetadata(fqName: String): Base64 =
|
||||||
|
reader.loadSerializedPackageFragment(fqName)
|
||||||
|
|
||||||
|
override val moduleDescriptor: ModuleDescriptorImpl by lazy {
|
||||||
|
deserializeModule(configuration,
|
||||||
|
{it -> packageMetadata(it)},
|
||||||
|
tableOfContentsAsString, moduleName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class KtBcLibraryReader(file: File, configuration: CompilerConfiguration)
|
||||||
|
: FileBasedLibraryReader(file, configuration, KtBcMetadataReader(file)) {
|
||||||
|
|
||||||
|
public constructor(path: String, configuration: CompilerConfiguration) : this(File(path), configuration)
|
||||||
|
|
||||||
|
override val bitcodePaths: List<String>
|
||||||
|
get() = listOf(libraryName)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Get rid of the configuration here.
|
||||||
|
class SplitLibraryReader(val libDir: File, configuration: CompilerConfiguration)
|
||||||
|
: FileBasedLibraryReader(libDir, configuration, SplitMetadataReader(libDir)) {
|
||||||
|
|
||||||
|
public constructor(path: String, configuration: CompilerConfiguration) : this(File(path), configuration)
|
||||||
|
|
||||||
|
val klibFile = File("${libDir.path}.klib")
|
||||||
|
|
||||||
|
init {
|
||||||
|
unpackIfNeeded()
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Search path processing is also goes somewhere around here.
|
||||||
|
fun unpackIfNeeded() {
|
||||||
|
// TODO: Clarify the policy here.
|
||||||
|
if (libDir.exists()) {
|
||||||
|
if (libDir.isDirectory()) return
|
||||||
|
}
|
||||||
|
if (!klibFile.exists()) {
|
||||||
|
error("Could not find neither $libDir nor $klibFile.")
|
||||||
|
}
|
||||||
|
if (klibFile.isFile()) {
|
||||||
|
klibFile.unzipAs(libDir)
|
||||||
|
|
||||||
|
if (!libDir.exists()) error("Could not unpack $klibFile as $libDir.")
|
||||||
|
} else {
|
||||||
|
error("Expected $klibFile to be a regular libDir.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val File.dirAbsolutePaths: List<String>
|
||||||
|
get() = this.listFiles()!!.toList()!!.map{it->it.absolutePath}
|
||||||
|
|
||||||
|
private val targetDir: File
|
||||||
|
get() {
|
||||||
|
val target = TargetManager(configuration).currentName
|
||||||
|
val dir = File(libDir, target)
|
||||||
|
return dir
|
||||||
|
}
|
||||||
|
|
||||||
|
override val bitcodePaths: List<String>
|
||||||
|
get() = File(targetDir, "kotlin").dirAbsolutePaths +
|
||||||
|
File(targetDir, "native").dirAbsolutePaths
|
||||||
|
|
||||||
|
}
|
||||||
|
/* ------------ writer part ----------------*/
|
||||||
|
|
||||||
|
interface KonanLibraryWriter {
|
||||||
|
|
||||||
|
fun addLinkData(linkData: LinkData)
|
||||||
|
fun addNativeBitcode(library: String)
|
||||||
|
fun addKotlinBitcode(llvmModule: LLVMModuleRef)
|
||||||
|
fun commit()
|
||||||
|
|
||||||
|
val mainBitcodeFileName: String
|
||||||
|
}
|
||||||
|
|
||||||
|
class LinkData(
|
||||||
|
val abiVersion: Int,
|
||||||
|
val module: String,
|
||||||
|
val moduleName: String,
|
||||||
|
val fragments: List<String>,
|
||||||
|
val fragmentNames: List<String> )
|
||||||
|
|
||||||
|
abstract class FileBasedLibraryWriter (
|
||||||
|
val file: File): KonanLibraryWriter {
|
||||||
|
}
|
||||||
|
|
||||||
|
class KtBcLibraryWriter(file: File, val llvmModule: LLVMModuleRef)
|
||||||
|
: FileBasedLibraryWriter(file) {
|
||||||
|
|
||||||
|
override val mainBitcodeFileName = file.path
|
||||||
|
|
||||||
|
public constructor(path: String, llvmModule: LLVMModuleRef)
|
||||||
|
: this(File(path), llvmModule)
|
||||||
|
|
||||||
|
override fun addKotlinBitcode(llvmModule: LLVMModuleRef) {
|
||||||
|
// This is a noop for .kt.bc based libraries,
|
||||||
|
// because the bitcode itself is the container.
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun addLinkData(linkData: LinkData) {
|
||||||
|
MetadataGenerator(llvmModule).addLinkData(linkData)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun addNativeBitcode(library: String) {
|
||||||
|
|
||||||
|
val libraryModule = parseBitcodeFile(library)
|
||||||
|
val failed = LLVMLinkModules2(llvmModule, libraryModule)
|
||||||
|
if (failed != 0) {
|
||||||
|
throw Error("failed to link $library") // TODO: retrieve error message from LLVM.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun commit() {
|
||||||
|
LLVMWriteBitcodeToFile(llvmModule, file.path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class SplitLibraryWriter(val libDir: File, target: String, val nopack: Boolean = false): FileBasedLibraryWriter(libDir) {
|
||||||
|
public constructor(path: String, target: String, nopack: Boolean): this(File(path), target, nopack)
|
||||||
|
|
||||||
|
val klibFile = File("${libDir.path}.klib")
|
||||||
|
val linkdataDir = File(libDir, "linkdata")
|
||||||
|
val resourcesDir = File(libDir, "resources")
|
||||||
|
val targetDir = File(libDir, target)
|
||||||
|
val kotlinDir = File(targetDir, "kotlin")
|
||||||
|
val nativeDir = File(targetDir, "native")
|
||||||
|
// TODO: Experiment with separate bitcode files.
|
||||||
|
// Per package or per class.
|
||||||
|
val mainBitcodeFile = File(kotlinDir, "program.kt.bc")
|
||||||
|
override val mainBitcodeFileName = mainBitcodeFile.path
|
||||||
|
|
||||||
|
init {
|
||||||
|
// TODO: figure out the proper policy here.
|
||||||
|
libDir.deleteRecursively()
|
||||||
|
klibFile.delete()
|
||||||
|
libDir.mkdirs()
|
||||||
|
linkdataDir.mkdirs()
|
||||||
|
targetDir.mkdirs()
|
||||||
|
kotlinDir.mkdirs()
|
||||||
|
nativeDir.mkdirs()
|
||||||
|
resourcesDir.mkdirs()
|
||||||
|
}
|
||||||
|
|
||||||
|
var llvmModule: LLVMModuleRef? = null
|
||||||
|
|
||||||
|
override fun addKotlinBitcode(llvmModule: LLVMModuleRef) {
|
||||||
|
this.llvmModule = llvmModule
|
||||||
|
LLVMWriteBitcodeToFile(llvmModule, mainBitcodeFileName)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun addLinkData(linkData: LinkData) {
|
||||||
|
SplitMetadataGenerator(linkdataDir).addLinkData(linkData)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun addNativeBitcode(library: String) {
|
||||||
|
val basename = File(library).getName()
|
||||||
|
File(library).copyTo(File(nativeDir, basename))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun commit() {
|
||||||
|
if (!nopack) {
|
||||||
|
// This is no-op for the Split library.
|
||||||
|
// Or should we zip the directory?
|
||||||
|
libDir.zipDirAs(klibFile)
|
||||||
|
libDir.deleteRecursively()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
+10
-1
@@ -22,6 +22,7 @@ import llvm.*
|
|||||||
import org.jetbrains.kotlin.backend.konan.Context
|
import org.jetbrains.kotlin.backend.konan.Context
|
||||||
import org.jetbrains.kotlin.backend.konan.KonanConfigKeys
|
import org.jetbrains.kotlin.backend.konan.KonanConfigKeys
|
||||||
import org.jetbrains.kotlin.backend.konan.KonanVersion
|
import org.jetbrains.kotlin.backend.konan.KonanVersion
|
||||||
|
import org.jetbrains.kotlin.backend.konan.TargetManager
|
||||||
import org.jetbrains.kotlin.backend.konan.util.File
|
import org.jetbrains.kotlin.backend.konan.util.File
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||||
@@ -94,7 +95,15 @@ internal fun String?.toFileAndFolder():FileAndFolder {
|
|||||||
|
|
||||||
internal fun generateDebugInfoHeader(context: Context) {
|
internal fun generateDebugInfoHeader(context: Context) {
|
||||||
if (context.shouldContainDebugInfo()) {
|
if (context.shouldContainDebugInfo()) {
|
||||||
val path = context.config.configuration.get(KonanConfigKeys.BITCODE_FILE).toFileAndFolder()
|
|
||||||
|
val path = with(context.config.configuration) {
|
||||||
|
if (!getBoolean(KonanConfigKeys.NOLINK)) {
|
||||||
|
get(KonanConfigKeys.EXECUTABLE_FILE)!!
|
||||||
|
} else {
|
||||||
|
get(KonanConfigKeys.LIBRARY_NAME)!!
|
||||||
|
}
|
||||||
|
}.toFileAndFolder()
|
||||||
|
|
||||||
context.debugInfo.module = DICreateModule(
|
context.debugInfo.module = DICreateModule(
|
||||||
builder = context.debugInfo.builder,
|
builder = context.debugInfo.builder,
|
||||||
scope = context.llvmModule as DIScopeOpaqueRef,
|
scope = context.llvmModule as DIScopeOpaqueRef,
|
||||||
|
|||||||
+64
-30
@@ -23,9 +23,14 @@ import org.jetbrains.kotlin.backend.common.descriptors.isSuspend
|
|||||||
import org.jetbrains.kotlin.backend.konan.Context
|
import org.jetbrains.kotlin.backend.konan.Context
|
||||||
import org.jetbrains.kotlin.backend.konan.KonanConfigKeys
|
import org.jetbrains.kotlin.backend.konan.KonanConfigKeys
|
||||||
import org.jetbrains.kotlin.backend.konan.KonanPhase
|
import org.jetbrains.kotlin.backend.konan.KonanPhase
|
||||||
|
import org.jetbrains.kotlin.backend.konan.LinkData
|
||||||
import org.jetbrains.kotlin.backend.konan.PhaseManager
|
import org.jetbrains.kotlin.backend.konan.PhaseManager
|
||||||
import org.jetbrains.kotlin.backend.konan.descriptors.*
|
import org.jetbrains.kotlin.backend.konan.descriptors.*
|
||||||
import org.jetbrains.kotlin.backend.konan.ir.*
|
import org.jetbrains.kotlin.backend.konan.ir.*
|
||||||
|
import org.jetbrains.kotlin.backend.konan.TargetManager
|
||||||
|
import org.jetbrains.kotlin.backend.konan.KonanLibraryWriter
|
||||||
|
import org.jetbrains.kotlin.backend.konan.KtBcLibraryWriter
|
||||||
|
import org.jetbrains.kotlin.backend.konan.SplitLibraryWriter
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||||
@@ -52,7 +57,9 @@ import org.jetbrains.kotlin.types.typeUtil.isUnit
|
|||||||
|
|
||||||
internal fun emitLLVM(context: Context) {
|
internal fun emitLLVM(context: Context) {
|
||||||
|
|
||||||
|
val config = context.config.configuration
|
||||||
val irModule = context.irModule!!
|
val irModule = context.irModule!!
|
||||||
|
|
||||||
// Note that we don't set module target explicitly.
|
// Note that we don't set module target explicitly.
|
||||||
// It is determined by the target of runtime.bc
|
// It is determined by the target of runtime.bc
|
||||||
// (see Llvm class in ContextUtils)
|
// (see Llvm class in ContextUtils)
|
||||||
@@ -61,7 +68,6 @@ internal fun emitLLVM(context: Context) {
|
|||||||
val llvmModule = LLVMModuleCreateWithName("out")!! // TODO: dispose
|
val llvmModule = LLVMModuleCreateWithName("out")!! // TODO: dispose
|
||||||
context.llvmModule = llvmModule
|
context.llvmModule = llvmModule
|
||||||
context.debugInfo.builder = DICreateBuilder(llvmModule)
|
context.debugInfo.builder = DICreateBuilder(llvmModule)
|
||||||
|
|
||||||
context.llvmDeclarations = createLlvmDeclarations(context)
|
context.llvmDeclarations = createLlvmDeclarations(context)
|
||||||
|
|
||||||
val phaser = PhaseManager(context)
|
val phaser = PhaseManager(context)
|
||||||
@@ -70,33 +76,74 @@ internal fun emitLLVM(context: Context) {
|
|||||||
irModule.acceptVoid(RTTIGeneratorVisitor(context))
|
irModule.acceptVoid(RTTIGeneratorVisitor(context))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
generateDebugInfoHeader(context)
|
generateDebugInfoHeader(context)
|
||||||
|
|
||||||
phaser.phase(KonanPhase.CODEGEN) {
|
phaser.phase(KonanPhase.CODEGEN) {
|
||||||
irModule.acceptVoid(CodeGeneratorVisitor(context))
|
irModule.acceptVoid(CodeGeneratorVisitor(context))
|
||||||
}
|
}
|
||||||
|
|
||||||
phaser.phase(KonanPhase.METADATOR) {
|
|
||||||
irModule.acceptVoid(MetadatorVisitor(context))
|
|
||||||
}
|
|
||||||
|
|
||||||
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.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (context.shouldContainDebugInfo()) {
|
if (context.shouldContainDebugInfo()) {
|
||||||
DIFinalize(context.debugInfo.builder)
|
DIFinalize(context.debugInfo.builder)
|
||||||
}
|
}
|
||||||
LLVMWriteBitcodeToFile(llvmModule, context.config.configuration.get(KonanConfigKeys.BITCODE_FILE)!!)
|
|
||||||
|
if (!config.getBoolean(KonanConfigKeys.NOLINK)) {
|
||||||
|
val program = config.get(KonanConfigKeys.PROGRAM_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)
|
||||||
|
} else {
|
||||||
|
|
||||||
|
val libraryName = config.get(KonanConfigKeys.LIBRARY_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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal fun buildLibrary(phaser: PhaseManager, 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)
|
||||||
|
|
||||||
|
phaser.phase(KonanPhase.METADATOR) {
|
||||||
|
library.addLinkData(linkData)
|
||||||
|
}
|
||||||
|
|
||||||
|
phaser.phase(KonanPhase.BITCODE_LINKER) {
|
||||||
|
natives.forEach {
|
||||||
|
library.addNativeBitcode(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
library.commit()
|
||||||
|
return library
|
||||||
|
}
|
||||||
|
|
||||||
internal fun verifyModule(llvmModule: LLVMModuleRef, current: String = "") {
|
internal fun verifyModule(llvmModule: LLVMModuleRef, current: String = "") {
|
||||||
memScoped {
|
memScoped {
|
||||||
@@ -134,19 +181,6 @@ internal class RTTIGeneratorVisitor(context: Context) : IrElementVisitorVoid {
|
|||||||
|
|
||||||
//-------------------------------------------------------------------------//
|
//-------------------------------------------------------------------------//
|
||||||
|
|
||||||
internal class MetadatorVisitor(val context: Context) : IrElementVisitorVoid {
|
|
||||||
|
|
||||||
val metadator = MetadataGenerator(context)
|
|
||||||
|
|
||||||
override fun visitElement(element: IrElement) {
|
|
||||||
element.acceptChildrenVoid(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitModuleFragment(module: IrModuleFragment) {
|
|
||||||
module.acceptChildrenVoid(this)
|
|
||||||
metadator.endModule(module)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines how to generate context-dependent operations.
|
* Defines how to generate context-dependent operations.
|
||||||
|
|||||||
+65
-15
@@ -20,13 +20,51 @@ import kotlinx.cinterop.*
|
|||||||
import llvm.*
|
import llvm.*
|
||||||
import org.jetbrains.kotlin.backend.konan.Context
|
import org.jetbrains.kotlin.backend.konan.Context
|
||||||
import org.jetbrains.kotlin.backend.konan.KonanConfigKeys
|
import org.jetbrains.kotlin.backend.konan.KonanConfigKeys
|
||||||
|
import org.jetbrains.kotlin.backend.konan.LinkData
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||||
import java.io.Closeable
|
import java.io.Closeable
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
import kotlin.io.readText
|
||||||
|
import java.util.Properties
|
||||||
|
|
||||||
class NamedModuleData(val name:String, val base64: String)
|
class NamedModuleData(val name:String, val base64: String)
|
||||||
|
|
||||||
fun MetadataReader.loadSerializedModule(currentAbiVersion: Int): NamedModuleData {
|
interface MetadataReader {
|
||||||
|
fun loadSerializedModule(currentAbiVersion: Int): NamedModuleData
|
||||||
|
fun loadSerializedPackageFragment(fqName: String): String
|
||||||
|
}
|
||||||
|
|
||||||
|
class SplitMetadataReader(file: File) : MetadataReader {
|
||||||
|
|
||||||
|
val linkDataDir = File(file, "linkdata")
|
||||||
|
|
||||||
|
override fun loadSerializedModule(currentAbiVersion: Int): NamedModuleData {
|
||||||
|
val header = Properties()
|
||||||
|
val file = File(linkDataDir, "module")
|
||||||
|
file.bufferedReader().use { reader ->
|
||||||
|
header.load(reader)
|
||||||
|
}
|
||||||
|
val headerAbiVersion = header.getProperty("abi_version")!!
|
||||||
|
val moduleName = header.getProperty("module_name")!!
|
||||||
|
val moduleData = header.getProperty("module_data")!!
|
||||||
|
|
||||||
|
if ("$currentAbiVersion" != headerAbiVersion)
|
||||||
|
error("ABI version mismatch. Compiler expects: $currentAbiVersion, the library is $headerAbiVersion")
|
||||||
|
|
||||||
|
return NamedModuleData(moduleName, moduleData)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun loadSerializedPackageFragment(fqName: String): String {
|
||||||
|
val realName = if (fqName == "") "<root>" else fqName
|
||||||
|
|
||||||
|
return File(linkDataDir, realName).readText()
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class KtBcMetadataReader(file: File) : Closeable, MetadataReader {
|
||||||
|
|
||||||
|
override fun loadSerializedModule(currentAbiVersion: Int): NamedModuleData {
|
||||||
val (nodeCount, kmetadataNodeArg) = namedMetadataNode("kmetadata")
|
val (nodeCount, kmetadataNodeArg) = namedMetadataNode("kmetadata")
|
||||||
|
|
||||||
if (nodeCount != 1) {
|
if (nodeCount != 1) {
|
||||||
@@ -48,7 +86,7 @@ fun MetadataReader.loadSerializedModule(currentAbiVersion: Int): NamedModuleData
|
|||||||
return NamedModuleData(moduleName, tableOfContentsAsString)
|
return NamedModuleData(moduleName, tableOfContentsAsString)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun MetadataReader.loadSerializedPackageFragment(fqName: String): String {
|
override fun loadSerializedPackageFragment(fqName: String): String {
|
||||||
val (nodeCount, kpackageNodeArg) = namedMetadataNode("kpackage:$fqName")
|
val (nodeCount, kpackageNodeArg) = namedMetadataNode("kpackage:$fqName")
|
||||||
|
|
||||||
if (nodeCount != 1) {
|
if (nodeCount != 1) {
|
||||||
@@ -61,8 +99,6 @@ fun MetadataReader.loadSerializedPackageFragment(fqName: String): String {
|
|||||||
return base64
|
return base64
|
||||||
}
|
}
|
||||||
|
|
||||||
class MetadataReader(file: File) : Closeable {
|
|
||||||
|
|
||||||
lateinit var llvmModule: LLVMModuleRef
|
lateinit var llvmModule: LLVMModuleRef
|
||||||
lateinit var llvmContext: LLVMContextRef
|
lateinit var llvmContext: LLVMContextRef
|
||||||
|
|
||||||
@@ -141,7 +177,7 @@ class MetadataReader(file: File) : Closeable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class MetadataGenerator(override val context: Context): ContextUtils {
|
internal class MetadataGenerator(val llvmModule: LLVMModuleRef) {
|
||||||
|
|
||||||
private fun metadataNode(args: List<LLVMValueRef?>): LLVMValueRef {
|
private fun metadataNode(args: List<LLVMValueRef?>): LLVMValueRef {
|
||||||
return LLVMMDNode(args.toCValues(), args.size)!!
|
return LLVMMDNode(args.toCValues(), args.size)!!
|
||||||
@@ -154,38 +190,52 @@ internal class MetadataGenerator(override val context: Context): ContextUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun emitModuleMetadata(name: String, md: LLVMValueRef?) {
|
private fun emitModuleMetadata(name: String, md: LLVMValueRef?) {
|
||||||
LLVMAddNamedMetadataOperand(context.llvmModule, name, md)
|
LLVMAddNamedMetadataOperand(llvmModule, name, md)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun metadataString(str: String): LLVMValueRef {
|
private fun metadataString(str: String): LLVMValueRef {
|
||||||
return LLVMMDString(str, str.length)!!
|
return LLVMMDString(str, str.length)!!
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun addLinkData(module: IrModuleFragment) {
|
fun addLinkData(linkData: LinkData) {
|
||||||
val linkData = context.serializedLinkData
|
|
||||||
if (linkData == null) return
|
if (linkData == null) return
|
||||||
|
|
||||||
val abiVersion = context.config.configuration.get(KonanConfigKeys.ABI_VERSION)
|
val abiNode = metadataString("${linkData.abiVersion}")
|
||||||
val abiNode = metadataString("$abiVersion")
|
val moduleNameNode = metadataString(linkData.moduleName)
|
||||||
val moduleName = metadataString(module.descriptor.name.asString())
|
|
||||||
val module = linkData.module
|
val module = linkData.module
|
||||||
val fragments = linkData.fragments
|
val fragments = linkData.fragments
|
||||||
val fragmentNames = linkData.fragmentNames
|
val fragmentNames = linkData.fragmentNames
|
||||||
val dataNode = metadataString(module)
|
val dataNode = metadataString(module)
|
||||||
|
|
||||||
val kmetadataArg = metadataNode(listOf(abiNode, moduleName, dataNode))
|
val kmetadataArg = metadataNode(listOf(abiNode, moduleNameNode, dataNode))
|
||||||
emitModuleMetadata("kmetadata", kmetadataArg)
|
emitModuleMetadata("kmetadata", kmetadataArg)
|
||||||
|
|
||||||
fragments.forEachIndexed { index, it ->
|
fragments.forEachIndexed { index, it ->
|
||||||
val name = fragmentNames.get(index)
|
val name = fragmentNames[index]
|
||||||
val dataNode = metadataString(it)
|
val dataNode = metadataString(it)
|
||||||
val kpackageArg = metadataNode(listOf(dataNode))
|
val kpackageArg = metadataNode(listOf(dataNode))
|
||||||
emitModuleMetadata("kpackage:$name", kpackageArg)
|
emitModuleMetadata("kpackage:$name", kpackageArg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
internal fun endModule(module: IrModuleFragment) {
|
internal class SplitMetadataGenerator(val file: File) {
|
||||||
addLinkData(module)
|
|
||||||
|
fun addLinkData(linkData: LinkData) {
|
||||||
|
|
||||||
|
val header = Properties()
|
||||||
|
header.putAll(hashMapOf(
|
||||||
|
"abi_version" to "${linkData.abiVersion}",
|
||||||
|
"module_name" to "${linkData.moduleName}",
|
||||||
|
"module_data" to "${linkData.module}"
|
||||||
|
))
|
||||||
|
header.store(File(file, "module").outputStream(), null)
|
||||||
|
|
||||||
|
linkData.fragments.forEachIndexed { index, it ->
|
||||||
|
val name = linkData.fragmentNames[index]
|
||||||
|
val realName = if (name == "") "<root>" else name
|
||||||
|
File(file, realName).writeText(it)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
-1
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.backend.konan.serialization
|
|||||||
import org.jetbrains.kotlin.backend.konan.Context
|
import org.jetbrains.kotlin.backend.konan.Context
|
||||||
import org.jetbrains.kotlin.backend.konan.LinkData
|
import org.jetbrains.kotlin.backend.konan.LinkData
|
||||||
import org.jetbrains.kotlin.backend.konan.KonanBuiltIns
|
import org.jetbrains.kotlin.backend.konan.KonanBuiltIns
|
||||||
|
import org.jetbrains.kotlin.backend.konan.KonanConfigKeys
|
||||||
import org.jetbrains.kotlin.backend.konan.llvm.base64Decode
|
import org.jetbrains.kotlin.backend.konan.llvm.base64Decode
|
||||||
import org.jetbrains.kotlin.backend.konan.llvm.base64Encode
|
import org.jetbrains.kotlin.backend.konan.llvm.base64Encode
|
||||||
import org.jetbrains.kotlin.backend.konan.llvm.isExported
|
import org.jetbrains.kotlin.backend.konan.llvm.isExported
|
||||||
@@ -274,7 +275,9 @@ internal class KonanSerializationUtil(val context: Context) {
|
|||||||
}
|
}
|
||||||
val libraryAsByteArray = libraryProto.build().toByteArray()
|
val libraryAsByteArray = libraryProto.build().toByteArray()
|
||||||
val library = byteArrayToBase64(libraryAsByteArray)
|
val library = byteArrayToBase64(libraryAsByteArray)
|
||||||
return LinkData(library, fragments, fragmentNames)
|
val abiVersion = context.config.configuration.get(KonanConfigKeys.ABI_VERSION)!!
|
||||||
|
val moduleName = moduleDescriptor.name.asString()
|
||||||
|
return LinkData(abiVersion, library, moduleName, fragments, fragmentNames)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+52
-26
@@ -67,8 +67,9 @@ void setupCompilationFlags() {
|
|||||||
final String binDir
|
final String binDir
|
||||||
|
|
||||||
if (isLinux()) {
|
if (isLinux()) {
|
||||||
|
ext.host = "linux"
|
||||||
ext.targetArgs <<
|
ext.targetArgs <<
|
||||||
["host":
|
[(ext.host):
|
||||||
["--sysroot=${gccToolchainDir}/${gnuTriplet}/sysroot"],
|
["--sysroot=${gccToolchainDir}/${gnuTriplet}/sysroot"],
|
||||||
"raspberrypi":
|
"raspberrypi":
|
||||||
["-target", "armv7-unknown-linux-gnueabihf",
|
["-target", "armv7-unknown-linux-gnueabihf",
|
||||||
@@ -79,9 +80,10 @@ void setupCompilationFlags() {
|
|||||||
"-I$raspberryPiSysrootDir/usr/include/c++/4.8.3/arm-linux-gnueabihf"]
|
"-I$raspberryPiSysrootDir/usr/include/c++/4.8.3/arm-linux-gnueabihf"]
|
||||||
]
|
]
|
||||||
} else {
|
} else {
|
||||||
|
ext.host = "macbook"
|
||||||
ext.targetArgs <<
|
ext.targetArgs <<
|
||||||
["host":
|
[(ext.host):
|
||||||
["--sysroot=$hostSysrootDir", "-mmacosx-version-min=$minMacOsVersion"],
|
["--sysroot=$macbookSysrootDir", "-mmacosx-version-min=$minMacOsVersion"],
|
||||||
"iphone":
|
"iphone":
|
||||||
["-stdlib=libc++", "-arch", "arm64", "-isysroot", "$iphoneSysrootDir",
|
["-stdlib=libc++", "-arch", "arm64", "-isysroot", "$iphoneSysrootDir",
|
||||||
"-miphoneos-version-min=8.0.0"]
|
"-miphoneos-version-min=8.0.0"]
|
||||||
@@ -99,11 +101,11 @@ void setupCompilationFlags() {
|
|||||||
"-L$llvmDir/lib"
|
"-L$llvmDir/lib"
|
||||||
])
|
])
|
||||||
} else {
|
} else {
|
||||||
binDir = "$hostSysrootDir/usr/bin"
|
binDir = "$macbookSysrootDir/usr/bin"
|
||||||
}
|
}
|
||||||
ext.clangArgs << "-B$binDir"
|
ext.clangArgs << "-B$binDir"
|
||||||
ext.hostClangArgs = ext.clangArgs.clone()
|
ext.hostClangArgs = ext.clangArgs.clone()
|
||||||
ext.hostClangArgs.addAll(ext.targetArgs['host'])
|
ext.hostClangArgs.addAll(ext.targetArgs[host])
|
||||||
|
|
||||||
ext.clangPath << binDir
|
ext.clangPath << binDir
|
||||||
ext.jvmArgs = ["-ea"]
|
ext.jvmArgs = ["-ea"]
|
||||||
@@ -164,7 +166,12 @@ class PlatformInfo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
task dist_compiler(type: Copy) {
|
task dist_compiler(dependsOn: "distCompiler")
|
||||||
|
task dist_runtime(dependsOn: "distRuntime")
|
||||||
|
task cross_dist(dependsOn: "crossDist")
|
||||||
|
task list_dist(dependsOn: "listDist")
|
||||||
|
|
||||||
|
task distCompiler(type: Copy) {
|
||||||
dependsOn ':backend.native:jars'
|
dependsOn ':backend.native:jars'
|
||||||
dependsOn ':tools:helpers:jar'
|
dependsOn ':tools:helpers:jar'
|
||||||
|
|
||||||
@@ -221,46 +228,65 @@ task dist_compiler(type: Copy) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
task list_dist(type: Exec) {
|
task listDist(type: Exec) {
|
||||||
commandLine 'find', 'dist'
|
commandLine 'find', 'dist'
|
||||||
}
|
}
|
||||||
|
|
||||||
task dist_runtime(type: Copy) {
|
task distRuntime(type: Copy) {
|
||||||
dependsOn ':runtime:hostRuntime'
|
dependsOn "${host}CrossDistRuntime"
|
||||||
dependsOn ':backend.native:hostStdlib'
|
dependsOn('commonDistRuntime')
|
||||||
dependsOn ':backend.native:hostStart'
|
}
|
||||||
|
|
||||||
|
task commonDistRuntime(type: Copy) {
|
||||||
destinationDir file('dist')
|
destinationDir file('dist')
|
||||||
|
|
||||||
from(project(':runtime').file('build')) {
|
// Target independant common part.
|
||||||
include('*/*.bc')
|
from(project(':runtime').file("build/${host}Stdlib")) {
|
||||||
into('lib')
|
include('**')
|
||||||
|
into('klib/stdlib')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
task cross_dist_runtime(type: Copy) {
|
task crossDistRuntime(type: Copy) {
|
||||||
dependsOn.addAll(targetList.collect { ":runtime:${it}Runtime" })
|
dependsOn.addAll(targetList.collect { "${it}CrossDistRuntime" })
|
||||||
dependsOn.addAll(targetList.collect { ":backend.native:${it}Stdlib" })
|
dependsOn('commonDistRuntime')
|
||||||
dependsOn.addAll(targetList.collect { ":backend.native:${it}Start" })
|
}
|
||||||
|
|
||||||
destinationDir file('dist')
|
targetList.each { target ->
|
||||||
|
task("${target}CrossDistRuntime", type: Copy) {
|
||||||
|
dependsOn ":runtime:${target}Runtime"
|
||||||
|
dependsOn ":backend.native:${target}Stdlib"
|
||||||
|
dependsOn ":backend.native:${target}Start"
|
||||||
|
|
||||||
from(project(':runtime').file('build')) {
|
destinationDir file('dist')
|
||||||
include('*/*.bc')
|
|
||||||
into('lib')
|
from(project(':runtime').file("build/$target")) {
|
||||||
|
include("*.bc")
|
||||||
|
eachFile {println("eachfile= $it")}
|
||||||
|
into("klib/stdlib/$target/native")
|
||||||
|
}
|
||||||
|
from(project(':runtime').file("build/${target}Stdlib")) {
|
||||||
|
include('**')
|
||||||
|
into('klib/stdlib')
|
||||||
|
}
|
||||||
|
from(project(':runtime').file("build/${target}Start/$target/kotlin")) {
|
||||||
|
include("program.kt.bc")
|
||||||
|
rename('program.kt.bc', 'start.kt.bc')
|
||||||
|
into("klib/stdlib/$target/native")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
task dist {
|
task dist {
|
||||||
dependsOn 'dist_compiler', 'dist_runtime', ':tools:gradle-plugin:dist'
|
dependsOn 'distCompiler', 'distRuntime', ':tools:gradle-plugin:dist'
|
||||||
}
|
}
|
||||||
|
|
||||||
task cross_dist {
|
task crossDist {
|
||||||
dependsOn 'cross_dist_runtime', 'dist'
|
dependsOn 'crossDistRuntime', 'distCompiler'
|
||||||
}
|
}
|
||||||
|
|
||||||
task bundle(type: Tar) {
|
task bundle(type: Tar) {
|
||||||
dependsOn('cross_dist')
|
dependsOn('crossDist')
|
||||||
baseName = "kotlin-native-${simpleOsName()}-${project.konanVersion}"
|
baseName = "kotlin-native-${simpleOsName()}-${project.konanVersion}"
|
||||||
from("$project.rootDir/dist") {
|
from("$project.rootDir/dist") {
|
||||||
include '**'
|
include '**'
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ abstract class KonanTest extends JavaExec {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String buildExePath() {
|
String buildExePath() {
|
||||||
def exeName = project.file(source).name.replace(".kt", ".kt.exe")
|
def exeName = project.file(source).name.replace(".kt", "")
|
||||||
return "$outputDirectory/$exeName"
|
return "$outputDirectory/$exeName"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -206,9 +206,10 @@ fun handleExceptionContinuation(x: (Throwable) -> Unit): Continuation<Any?> = ob
|
|||||||
@TaskAction
|
@TaskAction
|
||||||
void executeTest() {
|
void executeTest() {
|
||||||
createOutputDirectory()
|
createOutputDirectory()
|
||||||
def exe = buildExePath()
|
def program = buildExePath()
|
||||||
|
def exe = "${program}.kexe"
|
||||||
|
|
||||||
compileTest(buildCompileList(), exe)
|
compileTest(buildCompileList(), program)
|
||||||
|
|
||||||
if (!run) {
|
if (!run) {
|
||||||
println "to be executed manually: $exe"
|
println "to be executed manually: $exe"
|
||||||
|
|||||||
+1
-1
@@ -27,7 +27,7 @@ targetList.each { targetName ->
|
|||||||
}
|
}
|
||||||
|
|
||||||
task build {
|
task build {
|
||||||
dependsOn hostHash
|
dependsOn "${host}Hash"
|
||||||
}
|
}
|
||||||
|
|
||||||
task clean << {
|
task clean << {
|
||||||
|
|||||||
Vendored
+12
-11
@@ -178,16 +178,14 @@ class HelperNativeDep extends TgzNativeDep {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
task hostLibffi(type: HelperNativeDep) {
|
|
||||||
baseName = "libffi-3.2.1-2-$host"
|
|
||||||
}
|
|
||||||
|
|
||||||
task llvm(type: HelperNativeDep) {
|
task llvm(type: HelperNativeDep) {
|
||||||
baseName = "clang-llvm-$llvmVersion-$host"
|
baseName = "clang-llvm-$llvmVersion-$host"
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isLinux()) {
|
if (isLinux()) {
|
||||||
|
task linuxLibffi(type: HelperNativeDep) {
|
||||||
|
baseName = "libffi-3.2.1-2-$host"
|
||||||
|
}
|
||||||
task gccToolchain(type: HelperNativeDep) {
|
task gccToolchain(type: HelperNativeDep) {
|
||||||
baseName = "target-gcc-toolchain-3-$host"
|
baseName = "target-gcc-toolchain-3-$host"
|
||||||
}
|
}
|
||||||
@@ -198,7 +196,10 @@ if (isLinux()) {
|
|||||||
baseName = "libffi-3.2.1-2-raspberrypi"
|
baseName = "libffi-3.2.1-2-raspberrypi"
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
task hostSysroot(type: HelperNativeDep) {
|
task macbookLibffi(type: HelperNativeDep) {
|
||||||
|
baseName = "libffi-3.2.1-2-$host"
|
||||||
|
}
|
||||||
|
task macbookSysroot(type: HelperNativeDep) {
|
||||||
baseName = "target-sysroot-1-$host"
|
baseName = "target-sysroot-1-$host"
|
||||||
}
|
}
|
||||||
task iphoneSysroot(type: HelperNativeDep) {
|
task iphoneSysroot(type: HelperNativeDep) {
|
||||||
@@ -207,11 +208,11 @@ if (isLinux()) {
|
|||||||
task iphoneLibffi(type: HelperNativeDep) {
|
task iphoneLibffi(type: HelperNativeDep) {
|
||||||
baseName = "libffi-3.2.1-2-darwin-ios"
|
baseName = "libffi-3.2.1-2-darwin-ios"
|
||||||
}
|
}
|
||||||
// TODO: re-enable when we known how to bring the simulator
|
// TODO: re-enable when we known how to bring the simulator
|
||||||
// sysroot to dependencies.
|
// sysroot to dependencies.
|
||||||
// task iphoneSimSysroot(type: TgzNativeDep) {
|
// task iphoneSimSysroot(type: TgzNativeDep) {
|
||||||
// baseName = "target-sysroot-1-darwin-ios-sim"
|
// baseName = "target-sysroot-1-darwin-ios-sim"
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -43,6 +43,8 @@ targetList.each { targetName ->
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
task hostRuntime(dependsOn: "${rootProject.ext.host}Runtime")
|
||||||
|
|
||||||
task clean << {
|
task clean << {
|
||||||
delete buildDir
|
delete buildDir
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user