diff --git a/Interop/Runtime/build.gradle b/Interop/Runtime/build.gradle index a0d14823462..36afd9bcdae 100644 --- a/Interop/Runtime/build.gradle +++ b/Interop/Runtime/build.gradle @@ -38,6 +38,9 @@ model { include '**/*.c' } binaries.all { + def host = rootProject.ext.host + def hostLibffiDir = rootProject.ext.get("${host}LibffiDir") + cCompiler.args compilerArgsForJniIncludes cCompiler.args "-I$hostLibffiDir/include" diff --git a/backend.native/build.gradle b/backend.native/build.gradle index 863931d926c..149dd7ad473 100644 --- a/backend.native/build.gradle +++ b/backend.native/build.gradle @@ -153,7 +153,7 @@ kotlinNativeInterop { compilerOpts '-fPIC' linkerOpts '-fPIC' linker 'clang++' - linkOutputs ':common:hostHash' + linkOutputs ":common:${host}Hash" headers fileTree('../common/src/hash/headers') { include '**/*.h' @@ -194,8 +194,8 @@ build.dependsOn 'compilerClasses','cli_bcClasses','bc_frontendClasses' // These are just a couple of aliases -task stdlib(dependsOn: 'hostStdlib') -task start(dependsOn: 'hostStart') +task stdlib(dependsOn: "${host}Stdlib") +task start(dependsOn: "${host}Start") // These files are built before the 'dist' is complete, // so we provide custom values for @@ -208,8 +208,8 @@ targetList.each { target -> jvmArgs "-ea", "-Dkonan.home=${project.parent.file('dist')}", "-Djava.library.path=${project.buildDir}/nativelibs" - args('-output', project(':runtime').file("build/${target}/stdlib.kt.bc"), - '-nolink', '-nostdlib', '-ea', + args('-output', project(':runtime').file("build/${target}Stdlib"), + '-nolink', '-nopack', '-nostdlib','-ea', '-target', target, '-runtime', project(':runtime').file("build/${target}/runtime.bc"), '-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(':Interop:Runtime').file('src/main/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" } @@ -234,17 +234,17 @@ targetList.each { target -> jvmArgs "-ea", "-Dkonan.home=${project.parent.file('dist')}", "-Djava.library.path=${project.buildDir}/nativelibs" - args('-output', project(':runtime').file("build/${target}/start.kt.bc"), - '-nolink', '-nostdlib', '-ea', + args('-output', project(':runtime').file("build/${target}Start"), + '-nolink', '-nopack', '-nostdlib', '-ea', '-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"), '-properties', project(':backend.native').file('konan.properties'), project(':runtime').file('src/launcher/kotlin'), *project.globalBuildArgs) 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" } diff --git a/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2Native.kt b/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2Native.kt index 82c668ceebf..898c2d4824a 100644 --- a/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2Native.kt +++ b/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2Native.kt @@ -90,36 +90,38 @@ class K2Native : CLICompiler() { put(NOSTDLIB, arguments.nostdlib) put(NOLINK, arguments.nolink) + put(NOPACK, arguments.nopack) put(NOMAIN, arguments.nomain) put(LIBRARY_FILES, arguments.libraries.toNonNullList()) put(LINKER_ARGS, arguments.linkerArguments.toNonNullList()) + if (arguments.target != null) + put(TARGET, arguments.target) put(NATIVE_LIBRARY_FILES, arguments.nativeLibraries.toNonNullList()) // TODO: Collect all the explicit file names into an object // and teach the compiler to work with temporaries and -save-temps. - val bitcodeFile = if (arguments.nolink) { - arguments.outputFile ?: "program.kt.bc" - } else { - "${arguments.outputFile ?: "program"}.kt.bc" + val library = arguments.outputFile ?: "library" + if (arguments.nolink) + put(LIBRARY_NAME, library) + 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 - put(CommonConfigurationKeys.MODULE_NAME, bitcodeFile) + val module = if (arguments.nolink) library else program + put(CommonConfigurationKeys.MODULE_NAME, module) put(ABI_VERSION, 1) - put(EXECUTABLE_FILE, - arguments.outputFile ?: "program.kexe") if (arguments.runtimeFile != null) put(RUNTIME_FILE, arguments.runtimeFile) if (arguments.propertyFile != null) put(PROPERTY_FILE, arguments.propertyFile) - if (arguments.target != null) - put(TARGET, arguments.target) put(LIST_TARGETS, arguments.listTargets) put(OPTIMIZATION, arguments.optimization) put(DEBUG, arguments.debug) diff --git a/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2NativeCompilerArguments.java b/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2NativeCompilerArguments.java index e37f1dcbf05..f7782e91a51 100644 --- a/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2NativeCompilerArguments.java +++ b/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2NativeCompilerArguments.java @@ -38,6 +38,9 @@ public class K2NativeCompilerArguments extends CommonCompilerArguments { @Argument(value = "-nolink", description = "Don't link, just produce a bitcode file") 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") public boolean nomain; diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Context.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Context.kt index fad4262b430..dbddb3a2952 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Context.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Context.kt @@ -55,11 +55,6 @@ import java.util.* import kotlin.LazyThreadSafetyMode.PUBLICATION import kotlin.reflect.KProperty -internal class LinkData( - val module: String, - val fragments: List, - val fragmentNames: List ) - internal class SpecialDescriptorsFactory(val context: Context) { private val enumSpecialDescriptorsFactory by lazy { EnumSpecialDescriptorsFactory(context) } private val outerThisDescriptors = mutableMapOf() @@ -270,6 +265,8 @@ internal class Context(config: KonanConfig) : KonanBackendContext(config) { lateinit var llvm: Llvm lateinit var llvmDeclarations: LlvmDeclarations + lateinit var bitcodeFileName: String + lateinit var library: KonanLibraryWriter var phase: KonanPhase? = null var depth: Int = 0 diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Distribution.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Distribution.kt index 3bf9b4476c7..0705ed4016d 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Distribution.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Distribution.kt @@ -22,9 +22,7 @@ import java.io.File class Distribution(val config: CompilerConfiguration) { val targetManager = TargetManager(config) - val target = - if (!targetManager.crossCompile) "host" - else targetManager.current.name.toLowerCase() + val target = targetManager.currentName val suffix = targetManager.currentSuffix() val hostSuffix = TargetManager.host.suffix init { if (!targetManager.crossCompile) assert(suffix == hostSuffix) } @@ -40,16 +38,14 @@ class Distribution(val config: CompilerConfiguration) { ?: "$konanHome/konan/konan.properties" val properties = KonanProperties(propertyFile) - val lib = "$konanHome/lib/$target" + val klib = "$konanHome/klib" val dependenciesDir = "$konanHome/dependencies" val dependencies = properties.propertyList("dependencies.$suffix") - val stdlib = "$lib/stdlib.kt.bc" - val start = "$lib/start.kt.bc" - val launcher = "$lib/launcher.bc" + val stdlib = "$klib/stdlib" val runtime = config.get(KonanConfigKeys.RUNTIME_FILE) - ?: "$lib/runtime.bc" + ?: "$stdlib/$target/native/runtime.bc" val llvmHome = "$dependenciesDir/${properties.propertyString("llvmHome.$hostSuffix")}" val sysRoot = "$dependenciesDir/${properties.propertyString("sysRoot.$hostSuffix")}" diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfig.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfig.kt index f9a3a4d07b8..d6ba46d83d5 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfig.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfig.kt @@ -28,6 +28,7 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration val moduleId: String get() = configuration.getNotNull(CommonConfigurationKeys.MODULE_NAME) + internal val targetManager = TargetManager(configuration) internal val distribution = Distribution(configuration) private val libraryNames: List @@ -39,16 +40,15 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration return fromCommandLine + distribution.stdlib } - internal val libraries: List by lazy { - // Here we have chosen a particular .kt.bc KonanLibrary implementation - libraryNames.map{it -> KtBcLibrary(it, configuration)} + internal val libraries: List by lazy { + // Here we have chosen a particular KonanLibraryReader implementation + libraryNames.map{it -> SplitLibraryReader(it, configuration)} } private val loadedDescriptors = loadLibMetadata() internal val nativeLibraries: List = configuration.getList(KonanConfigKeys.NATIVE_LIBRARY_FILES) - fun loadLibMetadata(): List { val allMetadata = mutableListOf() diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfigurationKeys.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfigurationKeys.kt index f40c099a91d..c5bca4dd385 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfigurationKeys.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfigurationKeys.kt @@ -25,8 +25,12 @@ class KonanConfigKeys { = CompilerConfigurationKey.create("library file paths") val NATIVE_LIBRARY_FILES: CompilerConfigurationKey> = CompilerConfigurationKey.create("native library file paths") - val BITCODE_FILE: CompilerConfigurationKey - = CompilerConfigurationKey.create("emitted bitcode file path") + val LIBRARY_NAME: CompilerConfigurationKey + = CompilerConfigurationKey.create("library name") + val LIBRARY_FILE: CompilerConfigurationKey + = CompilerConfigurationKey.create("library file path") + val PROGRAM_NAME: CompilerConfigurationKey + = CompilerConfigurationKey.create("program name") val EXECUTABLE_FILE: CompilerConfigurationKey = CompilerConfigurationKey.create("final executable file path") val RUNTIME_FILE: CompilerConfigurationKey @@ -43,6 +47,8 @@ class KonanConfigKeys { = CompilerConfigurationKey.create("don't link with stdlib") val NOLINK: CompilerConfigurationKey = CompilerConfigurationKey.create("don't link, only produce a bitcode file ") + val NOPACK: CompilerConfigurationKey + = CompilerConfigurationKey.create("don't the library into a klib file") val NOMAIN: CompilerConfigurationKey = CompilerConfigurationKey.create("assume 'main' entry point to be provided by external libraries") val LINKER_ARGS: CompilerConfigurationKey> diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanDriver.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanDriver.kt index 4687e2f001a..e2b06d5632d 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanDriver.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanDriver.kt @@ -48,7 +48,7 @@ public fun runTopLevelPhases(konanConfig: KonanConfig, environment: KotlinCoreEn val config = konanConfig.configuration - val targets = TargetManager(config) + val targets = konanConfig.targetManager if (config.get(KonanConfigKeys.LIST_TARGETS) ?: false) { targets.list() } diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanLibrary.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanLibrary.kt deleted file mode 100644 index e13d46c9330..00000000000 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanLibrary.kt +++ /dev/null @@ -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 -} - -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 - 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) - } -} - diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanPhases.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanPhases.kt index c383516748e..3d9c13c4e6a 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanPhases.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanPhases.kt @@ -77,6 +77,7 @@ object KonanPhases { // Don't serialize anything to a final executable. KonanPhase.SERIALIZER.enabled = getBoolean(NOLINK) + KonanPhase.METADATOR.enabled = getBoolean(NOLINK) val disabled = get(DISABLED_PHASES) disabled?.forEach { phases[known(it)]!!.enabled = false } diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanTarget.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanTarget.kt index c3abfe0b9de..268cf504e2f 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanTarget.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanTarget.kt @@ -30,6 +30,8 @@ enum class KonanTarget(val suffix: String, var enabled: Boolean = false) { class TargetManager(val config: CompilerConfiguration) { val targets = KonanTarget.values().associate{ it.name.toLowerCase() to it } val current = determineCurrent() + val currentName + get() = current.name.toLowerCase() init { when (host) { diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/LinkStage.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/LinkStage.kt index e7f2d30b369..6ac1358ca94 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/LinkStage.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/LinkStage.kt @@ -147,9 +147,9 @@ internal class LinkStage(val context: Context) { val config = context.config.configuration - val targetManager = TargetManager(config) + val targetManager = context.config.targetManager private val distribution = - Distribution(context.config.configuration) + context.config.distribution private val properties = distribution.properties val platform = when (TargetManager.host) { @@ -164,8 +164,8 @@ internal class LinkStage(val context: Context) { val suffix = targetManager.currentSuffix() val optimize = config.get(KonanConfigKeys.OPTIMIZATION) ?: false - val emitted = config.get(KonanConfigKeys.BITCODE_FILE)!! val nomain = config.get(KonanConfigKeys.NOMAIN) ?: false + val emitted = context.bitcodeFileName val libraries = context.config.libraries fun llvmLto(files: List): ObjectFile { @@ -265,8 +265,7 @@ internal class LinkStage(val context: Context) { fun linkStage() { context.log{"# Compiler root: ${distribution.konanHome}"} - val bitcodeFiles = listOf(emitted, distribution.start, - distribution.runtime, distribution.launcher) + + val bitcodeFiles = listOf(emitted) + libraries.map{it -> it.bitcodePaths}.flatten() var objectFiles: List = listOf() diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/library/FileUtil.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/library/FileUtil.kt new file mode 100644 index 00000000000..c9fac613301 --- /dev/null +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/library/FileUtil.kt @@ -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()) +} + diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/library/KonanLibrary.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/library/KonanLibrary.kt new file mode 100644 index 00000000000..31b08f70f11 --- /dev/null +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/library/KonanLibrary.kt @@ -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 +} + +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 + 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 + 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 + 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, + val fragmentNames: List ) + +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() + } + } +} + diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/DebugUtils.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/DebugUtils.kt index fc2c8f4024a..5a996bb95ad 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/DebugUtils.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/DebugUtils.kt @@ -22,6 +22,7 @@ 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 @@ -94,7 +95,15 @@ internal fun String?.toFileAndFolder():FileAndFolder { internal fun generateDebugInfoHeader(context: Context) { 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( builder = context.debugInfo.builder, scope = context.llvmModule as DIScopeOpaqueRef, diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt index 76b05cb1e32..30cc2bcaf2f 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt @@ -23,9 +23,14 @@ import org.jetbrains.kotlin.backend.common.descriptors.isSuspend import org.jetbrains.kotlin.backend.konan.Context import org.jetbrains.kotlin.backend.konan.KonanConfigKeys 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.descriptors.* 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.descriptors.* import org.jetbrains.kotlin.incremental.components.NoLookupLocation @@ -52,7 +57,9 @@ import org.jetbrains.kotlin.types.typeUtil.isUnit internal fun emitLLVM(context: Context) { + val config = context.config.configuration val irModule = context.irModule!! + // Note that we don't set module target explicitly. // It is determined by the target of runtime.bc // (see Llvm class in ContextUtils) @@ -61,7 +68,6 @@ internal fun emitLLVM(context: Context) { val llvmModule = LLVMModuleCreateWithName("out")!! // TODO: dispose context.llvmModule = llvmModule context.debugInfo.builder = DICreateBuilder(llvmModule) - context.llvmDeclarations = createLlvmDeclarations(context) val phaser = PhaseManager(context) @@ -70,33 +76,74 @@ internal fun emitLLVM(context: Context) { irModule.acceptVoid(RTTIGeneratorVisitor(context)) } - generateDebugInfoHeader(context) phaser.phase(KonanPhase.CODEGEN) { 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()) { 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, 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 = "") { 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. diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/MetadataGenerator.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/MetadataGenerator.kt index b5d9169533f..95cb633ab5b 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/MetadataGenerator.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/MetadataGenerator.kt @@ -20,13 +20,51 @@ import kotlinx.cinterop.* import llvm.* import org.jetbrains.kotlin.backend.konan.Context import org.jetbrains.kotlin.backend.konan.KonanConfigKeys +import org.jetbrains.kotlin.backend.konan.LinkData import org.jetbrains.kotlin.ir.declarations.IrModuleFragment import java.io.Closeable import java.io.File +import kotlin.io.readText +import java.util.Properties 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 == "") "" else fqName + + return File(linkDataDir, realName).readText() + + } +} + +class KtBcMetadataReader(file: File) : Closeable, MetadataReader { + +override fun loadSerializedModule(currentAbiVersion: Int): NamedModuleData { val (nodeCount, kmetadataNodeArg) = namedMetadataNode("kmetadata") if (nodeCount != 1) { @@ -48,7 +86,7 @@ fun MetadataReader.loadSerializedModule(currentAbiVersion: Int): NamedModuleData return NamedModuleData(moduleName, tableOfContentsAsString) } -fun MetadataReader.loadSerializedPackageFragment(fqName: String): String { +override fun loadSerializedPackageFragment(fqName: String): String { val (nodeCount, kpackageNodeArg) = namedMetadataNode("kpackage:$fqName") if (nodeCount != 1) { @@ -61,8 +99,6 @@ fun MetadataReader.loadSerializedPackageFragment(fqName: String): String { return base64 } -class MetadataReader(file: File) : Closeable { - lateinit var llvmModule: LLVMModuleRef 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 { 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?) { - LLVMAddNamedMetadataOperand(context.llvmModule, name, md) + LLVMAddNamedMetadataOperand(llvmModule, name, md) } private fun metadataString(str: String): LLVMValueRef { return LLVMMDString(str, str.length)!! } - private fun addLinkData(module: IrModuleFragment) { - val linkData = context.serializedLinkData + fun addLinkData(linkData: LinkData) { if (linkData == null) return - val abiVersion = context.config.configuration.get(KonanConfigKeys.ABI_VERSION) - val abiNode = metadataString("$abiVersion") - val moduleName = metadataString(module.descriptor.name.asString()) + val abiNode = metadataString("${linkData.abiVersion}") + val moduleNameNode = metadataString(linkData.moduleName) val module = linkData.module val fragments = linkData.fragments val fragmentNames = linkData.fragmentNames val dataNode = metadataString(module) - val kmetadataArg = metadataNode(listOf(abiNode, moduleName, dataNode)) + val kmetadataArg = metadataNode(listOf(abiNode, moduleNameNode, dataNode)) emitModuleMetadata("kmetadata", kmetadataArg) fragments.forEachIndexed { index, it -> - val name = fragmentNames.get(index) + val name = fragmentNames[index] val dataNode = metadataString(it) val kpackageArg = metadataNode(listOf(dataNode)) emitModuleMetadata("kpackage:$name", kpackageArg) } } +} - internal fun endModule(module: IrModuleFragment) { - addLinkData(module) +internal class SplitMetadataGenerator(val file: File) { + + 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 == "") "" else name + File(file, realName).writeText(it) + } } } diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanSerializationUtil.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanSerializationUtil.kt index bb1f9c89dfc..99da91cfbaf 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanSerializationUtil.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanSerializationUtil.kt @@ -19,6 +19,7 @@ package org.jetbrains.kotlin.backend.konan.serialization import org.jetbrains.kotlin.backend.konan.Context import org.jetbrains.kotlin.backend.konan.LinkData 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.base64Encode import org.jetbrains.kotlin.backend.konan.llvm.isExported @@ -274,7 +275,9 @@ internal class KonanSerializationUtil(val context: Context) { } val libraryAsByteArray = libraryProto.build().toByteArray() 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) } } diff --git a/build.gradle b/build.gradle index d3a1c61a742..a8101ed82a3 100644 --- a/build.gradle +++ b/build.gradle @@ -67,8 +67,9 @@ void setupCompilationFlags() { final String binDir if (isLinux()) { + ext.host = "linux" ext.targetArgs << - ["host": + [(ext.host): ["--sysroot=${gccToolchainDir}/${gnuTriplet}/sysroot"], "raspberrypi": ["-target", "armv7-unknown-linux-gnueabihf", @@ -79,9 +80,10 @@ void setupCompilationFlags() { "-I$raspberryPiSysrootDir/usr/include/c++/4.8.3/arm-linux-gnueabihf"] ] } else { + ext.host = "macbook" ext.targetArgs << - ["host": - ["--sysroot=$hostSysrootDir", "-mmacosx-version-min=$minMacOsVersion"], + [(ext.host): + ["--sysroot=$macbookSysrootDir", "-mmacosx-version-min=$minMacOsVersion"], "iphone": ["-stdlib=libc++", "-arch", "arm64", "-isysroot", "$iphoneSysrootDir", "-miphoneos-version-min=8.0.0"] @@ -99,11 +101,11 @@ void setupCompilationFlags() { "-L$llvmDir/lib" ]) } else { - binDir = "$hostSysrootDir/usr/bin" + binDir = "$macbookSysrootDir/usr/bin" } ext.clangArgs << "-B$binDir" ext.hostClangArgs = ext.clangArgs.clone() - ext.hostClangArgs.addAll(ext.targetArgs['host']) + ext.hostClangArgs.addAll(ext.targetArgs[host]) ext.clangPath << binDir 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 ':tools:helpers:jar' @@ -221,46 +228,65 @@ task dist_compiler(type: Copy) { } } -task list_dist(type: Exec) { +task listDist(type: Exec) { commandLine 'find', 'dist' } -task dist_runtime(type: Copy) { - dependsOn ':runtime:hostRuntime' - dependsOn ':backend.native:hostStdlib' - dependsOn ':backend.native:hostStart' +task distRuntime(type: Copy) { + dependsOn "${host}CrossDistRuntime" + dependsOn('commonDistRuntime') +} +task commonDistRuntime(type: Copy) { destinationDir file('dist') - from(project(':runtime').file('build')) { - include('*/*.bc') - into('lib') + // Target independant common part. + from(project(':runtime').file("build/${host}Stdlib")) { + include('**') + into('klib/stdlib') } } -task cross_dist_runtime(type: Copy) { - dependsOn.addAll(targetList.collect { ":runtime:${it}Runtime" }) - dependsOn.addAll(targetList.collect { ":backend.native:${it}Stdlib" }) - dependsOn.addAll(targetList.collect { ":backend.native:${it}Start" }) +task crossDistRuntime(type: Copy) { + dependsOn.addAll(targetList.collect { "${it}CrossDistRuntime" }) + dependsOn('commonDistRuntime') +} - 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')) { - include('*/*.bc') - into('lib') + destinationDir file('dist') + + 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 { - dependsOn 'dist_compiler', 'dist_runtime', ':tools:gradle-plugin:dist' + dependsOn 'distCompiler', 'distRuntime', ':tools:gradle-plugin:dist' } -task cross_dist { - dependsOn 'cross_dist_runtime', 'dist' +task crossDist { + dependsOn 'crossDistRuntime', 'distCompiler' } task bundle(type: Tar) { - dependsOn('cross_dist') + dependsOn('crossDist') baseName = "kotlin-native-${simpleOsName()}-${project.konanVersion}" from("$project.rootDir/dist") { include '**' diff --git a/buildSrc/src/main/groovy/org/jetbrains/kotlin/KonanTest.groovy b/buildSrc/src/main/groovy/org/jetbrains/kotlin/KonanTest.groovy index ea7ab2808b3..9f36f80acfa 100644 --- a/buildSrc/src/main/groovy/org/jetbrains/kotlin/KonanTest.groovy +++ b/buildSrc/src/main/groovy/org/jetbrains/kotlin/KonanTest.groovy @@ -117,7 +117,7 @@ abstract class KonanTest extends JavaExec { } String buildExePath() { - def exeName = project.file(source).name.replace(".kt", ".kt.exe") + def exeName = project.file(source).name.replace(".kt", "") return "$outputDirectory/$exeName" } @@ -206,9 +206,10 @@ fun handleExceptionContinuation(x: (Throwable) -> Unit): Continuation = ob @TaskAction void executeTest() { createOutputDirectory() - def exe = buildExePath() + def program = buildExePath() + def exe = "${program}.kexe" - compileTest(buildCompileList(), exe) + compileTest(buildCompileList(), program) if (!run) { println "to be executed manually: $exe" diff --git a/common/build.gradle b/common/build.gradle index ba3a23dc457..61f1debcc77 100644 --- a/common/build.gradle +++ b/common/build.gradle @@ -27,7 +27,7 @@ targetList.each { targetName -> } task build { - dependsOn hostHash + dependsOn "${host}Hash" } task clean << { diff --git a/dependencies/build.gradle b/dependencies/build.gradle index bf3ab0c3542..9c83843ae71 100644 --- a/dependencies/build.gradle +++ b/dependencies/build.gradle @@ -178,16 +178,14 @@ class HelperNativeDep extends TgzNativeDep { } } - -task hostLibffi(type: HelperNativeDep) { - baseName = "libffi-3.2.1-2-$host" -} - task llvm(type: HelperNativeDep) { baseName = "clang-llvm-$llvmVersion-$host" } if (isLinux()) { + task linuxLibffi(type: HelperNativeDep) { + baseName = "libffi-3.2.1-2-$host" + } task gccToolchain(type: HelperNativeDep) { baseName = "target-gcc-toolchain-3-$host" } @@ -198,7 +196,10 @@ if (isLinux()) { baseName = "libffi-3.2.1-2-raspberrypi" } } 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" } task iphoneSysroot(type: HelperNativeDep) { @@ -207,11 +208,11 @@ if (isLinux()) { task iphoneLibffi(type: HelperNativeDep) { baseName = "libffi-3.2.1-2-darwin-ios" } -// TODO: re-enable when we known how to bring the simulator -// sysroot to dependencies. -// task iphoneSimSysroot(type: TgzNativeDep) { -// baseName = "target-sysroot-1-darwin-ios-sim" -// } + // TODO: re-enable when we known how to bring the simulator + // sysroot to dependencies. + // task iphoneSimSysroot(type: TgzNativeDep) { + // baseName = "target-sysroot-1-darwin-ios-sim" + // } } diff --git a/runtime/build.gradle b/runtime/build.gradle index d386d4ed0cf..16a15aa6e3e 100644 --- a/runtime/build.gradle +++ b/runtime/build.gradle @@ -43,6 +43,8 @@ targetList.each { targetName -> } } +task hostRuntime(dependsOn: "${rootProject.ext.host}Runtime") + task clean << { delete buildDir }