-produce program|library|bitcode

'program' makes a kexe.

    'library' makes a klib.

    'bitcode' makes just a bare bitcode file.

    The default is 'program'.
This commit is contained in:
Alexander Gorshenev
2017-05-23 18:49:45 +03:00
committed by alexander-gorshenev
parent 34491cfb01
commit 380010d1ee
9 changed files with 132 additions and 120 deletions
+4 -4
View File
@@ -209,8 +209,8 @@ targetList.each { target ->
"-Dkonan.home=${project.parent.file('dist')}",
"-Djava.library.path=${project.buildDir}/nativelibs"
args('-output', project(':runtime').file("build/${target}Stdlib"),
'-nolink', '-nopack', '-nostdlib','-ea',
'-target', target,
'-nopack', '-nostdlib','-ea',
'-produce', 'library', '-target', target,
'-runtime', project(':runtime').file("build/${target}/runtime.bc"),
'-properties', project(':backend.native').file('konan.properties'),
project(':runtime').file('src/main/kotlin'),
@@ -235,8 +235,8 @@ targetList.each { target ->
"-Dkonan.home=${project.parent.file('dist')}",
"-Djava.library.path=${project.buildDir}/nativelibs"
args('-output', project(':runtime').file("build/${target}Start"),
'-nolink', '-nopack', '-nostdlib', '-ea',
'-target', target,
'-nopack', '-nostdlib', '-ea',
'-produce', 'bitcode', '-target', target,
'-library', project(':runtime').file("build/${target}Stdlib"),
'-runtime', project(':runtime').file("build/${target}/runtime.bc"),
'-properties', rootProject.konanPropertiesFile.canonicalPath,
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.cli.bc
import com.intellij.openapi.Disposable
import org.jetbrains.kotlin.backend.konan.*
import org.jetbrains.kotlin.backend.konan.CompilerOutputKind.*
import org.jetbrains.kotlin.backend.konan.util.profile
import org.jetbrains.kotlin.cli.common.CLICompiler
import org.jetbrains.kotlin.cli.common.ExitCode
@@ -91,7 +92,6 @@ class K2Native : CLICompiler<K2NativeCompilerArguments>() {
with(configuration) {
put(NOSTDLIB, arguments.nostdlib)
put(NOLINK, arguments.nolink)
put(NOPACK, arguments.nopack)
put(NOMAIN, arguments.nomain)
put(LIBRARY_FILES,
@@ -108,18 +108,31 @@ class K2Native : CLICompiler<K2NativeCompilerArguments>() {
// TODO: Collect all the explicit file names into an object
// and teach the compiler to work with temporaries and -save-temps.
val library = arguments.outputFile ?: "library"
if (arguments.nolink)
put(LIBRARY_NAME, library)
put(LIBRARY_FILE, suffixIfNot(library, ".klib"))
val program = arguments.outputFile ?: "program"
if (!arguments.nolink) {
put(PROGRAM_NAME, program)
put(EXECUTABLE_FILE, suffixIfNot(program, ".kexe"))
val outputKind = CompilerOutputKind.valueOf(
(arguments.produce ?: "program").toUpperCase())
put(PRODUCE, outputKind)
val (defaultName, suffix) = when (outputKind) {
CompilerOutputKind.LIBRARY -> {
put(NOLINK, true)
Pair("library", ".klib")
}
CompilerOutputKind.PROGRAM -> {
put(NOLINK, false)
Pair("program", ".kexe")
}
CompilerOutputKind.BITCODE -> {
put(NOLINK, true)
Pair("output", ".bc")
}
}
val output = arguments.outputFile ?: defaultName
put(OUTPUT_NAME, output)
put(OUTPUT_FILE, suffixIfNot(output, suffix))
// This is a decision we could change
val module = if (arguments.nolink) library else program
put(CommonConfigurationKeys.MODULE_NAME, module)
put(CommonConfigurationKeys.MODULE_NAME, output)
put(ABI_VERSION, 1)
if (arguments.runtimeFile != null)
@@ -42,9 +42,6 @@ public class K2NativeCompilerArguments extends CommonCompilerArguments {
@Argument(value = "-nativelibrary", shortName = "-nl", valueDescription = "<path>", description = "Include the native library")
public String[] nativeLibraries;
@Argument(value = "-nolink", description = "Don't link, just produce a bitcode file")
public boolean nolink;
@Argument(value = "-nomain", description = "Assume 'main' entry point to be provided by external libraries")
public boolean nomain;
@@ -60,6 +57,9 @@ public class K2NativeCompilerArguments extends CommonCompilerArguments {
@Argument(value = "-output", shortName = "-o", valueDescription = "<path>", description = "Output file path")
public String outputFile;
@Argument(value = "-produce", valueDescription = "{program|library|bitcode}", description = "Produce either .kexe, .klib or a .bc file.")
public String produce;
@Argument(value = "-properties", valueDescription = "<path>", description = "Override standard 'konan.properties' location")
public String propertyFile;
@@ -116,3 +116,4 @@ public class K2NativeCompilerArguments extends CommonCompilerArguments {
public boolean verifyIr;
}
@@ -21,83 +21,82 @@ import org.jetbrains.kotlin.serialization.js.ModuleKind
class KonanConfigKeys {
companion object {
val LIBRARY_FILES: CompilerConfigurationKey<List<String>>
= CompilerConfigurationKey.create("library file paths")
val NATIVE_LIBRARY_FILES: CompilerConfigurationKey<List<String>>
= CompilerConfigurationKey.create("native library file paths")
val LIBRARY_NAME: CompilerConfigurationKey<String>
= 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>
= CompilerConfigurationKey.create("final executable file path")
val RUNTIME_FILE: CompilerConfigurationKey<String?>
= CompilerConfigurationKey.create("override default runtime file path")
val PROPERTY_FILE: CompilerConfigurationKey<String?>
= CompilerConfigurationKey.create("override default property file path")
// Keep the list lexically sorted.
val ABI_VERSION: CompilerConfigurationKey<Int>
= CompilerConfigurationKey.create("current abi version")
val OPTIMIZATION: CompilerConfigurationKey<Boolean>
= CompilerConfigurationKey.create("optimized compilation")
val DEBUG: CompilerConfigurationKey<Boolean>
= CompilerConfigurationKey.create("add debug information")
val NOSTDLIB: CompilerConfigurationKey<Boolean>
= CompilerConfigurationKey.create("don't link with stdlib")
val NOLINK: CompilerConfigurationKey<Boolean>
= 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>
= CompilerConfigurationKey.create("assume 'main' entry point to be provided by external libraries")
val DISABLED_PHASES: CompilerConfigurationKey<List<String>>
= CompilerConfigurationKey.create("disable backend phases")
val ENABLE_ASSERTIONS: CompilerConfigurationKey<Boolean>
= CompilerConfigurationKey.create("enable runtime assertions in generated code")
val ENABLED_PHASES: CompilerConfigurationKey<List<String>>
= CompilerConfigurationKey.create("enable backend phases")
val LIBRARY_FILES: CompilerConfigurationKey<List<String>>
= CompilerConfigurationKey.create("library file paths")
val LINKER_ARGS: CompilerConfigurationKey<List<String>>
= CompilerConfigurationKey.create("additional linker arguments")
val REPOSITORIES: CompilerConfigurationKey<List<String>>
= CompilerConfigurationKey.create("library search path repositories")
val TARGET: CompilerConfigurationKey<String?>
= CompilerConfigurationKey.create("target we compile for")
val LIST_PHASES: CompilerConfigurationKey<Boolean>
= CompilerConfigurationKey.create("list backend phases")
val LIST_TARGETS: CompilerConfigurationKey<Boolean>
= CompilerConfigurationKey.create("list available targets")
val SOURCE_MAP: CompilerConfigurationKey<List<String>>
= CompilerConfigurationKey.create("generate source map")
val META_INFO: CompilerConfigurationKey<List<String>>
= CompilerConfigurationKey.create("generate metadata")
val MODULE_KIND: CompilerConfigurationKey<ModuleKind>
= CompilerConfigurationKey.create("module kind")
val VERIFY_IR: CompilerConfigurationKey<Boolean>
= CompilerConfigurationKey.create("verify ir")
val VERIFY_DESCRIPTORS: CompilerConfigurationKey<Boolean>
= CompilerConfigurationKey.create("verify descriptors")
val VERIFY_BITCODE: CompilerConfigurationKey<Boolean>
= CompilerConfigurationKey.create("verify bitcode")
val NATIVE_LIBRARY_FILES: CompilerConfigurationKey<List<String>>
= CompilerConfigurationKey.create("native library file paths")
val NOLINK: CompilerConfigurationKey<Boolean>
= CompilerConfigurationKey.create("don't link, only produce a bitcode file ")
val NOMAIN: CompilerConfigurationKey<Boolean>
= CompilerConfigurationKey.create("assume 'main' entry point to be provided by external libraries")
val NOSTDLIB: CompilerConfigurationKey<Boolean>
= CompilerConfigurationKey.create("don't link with stdlib")
val NOPACK: CompilerConfigurationKey<Boolean>
= CompilerConfigurationKey.create("don't the library into a klib file")
val OPTIMIZATION: CompilerConfigurationKey<Boolean>
= CompilerConfigurationKey.create("optimized compilation")
val OUTPUT_FILE: CompilerConfigurationKey<String>
= CompilerConfigurationKey.create("final executable file path")
val OUTPUT_NAME: CompilerConfigurationKey<String>
= CompilerConfigurationKey.create("program or library name")
val PRINT_BITCODE: CompilerConfigurationKey<Boolean>
= CompilerConfigurationKey.create("print bitcode")
val PRINT_DESCRIPTORS: CompilerConfigurationKey<Boolean>
= CompilerConfigurationKey.create("print descriptors")
val PRINT_IR: CompilerConfigurationKey<Boolean>
= CompilerConfigurationKey.create("print ir")
val PRINT_IR_WITH_DESCRIPTORS: CompilerConfigurationKey<Boolean>
= CompilerConfigurationKey.create("print ir with descriptors")
val PRINT_DESCRIPTORS: CompilerConfigurationKey<Boolean>
= CompilerConfigurationKey.create("print descriptors")
val PRINT_BITCODE: CompilerConfigurationKey<Boolean>
= CompilerConfigurationKey.create("print bitcode")
val PRINT_LOCATIONS: CompilerConfigurationKey<Boolean>
= CompilerConfigurationKey.create("print locations")
val ENABLED_PHASES: CompilerConfigurationKey<List<String>>
= CompilerConfigurationKey.create("enable backend phases")
val DISABLED_PHASES: CompilerConfigurationKey<List<String>>
= CompilerConfigurationKey.create("disable backend phases")
val VERBOSE_PHASES: CompilerConfigurationKey<List<String>>
= CompilerConfigurationKey.create("verbose backend phases")
val LIST_PHASES: CompilerConfigurationKey<Boolean>
= CompilerConfigurationKey.create("list backend phases")
val PRODUCE: CompilerConfigurationKey<CompilerOutputKind>
= CompilerConfigurationKey.create("compiler output kind")
val PROPERTY_FILE: CompilerConfigurationKey<String?>
= CompilerConfigurationKey.create("override default property file path")
val REPOSITORIES: CompilerConfigurationKey<List<String>>
= CompilerConfigurationKey.create("library search path repositories")
val RUNTIME_FILE: CompilerConfigurationKey<String?>
= CompilerConfigurationKey.create("override default runtime file path")
val SOURCE_MAP: CompilerConfigurationKey<List<String>>
= CompilerConfigurationKey.create("generate source map")
val TARGET: CompilerConfigurationKey<String?>
= CompilerConfigurationKey.create("target we compile for")
val TIME_PHASES: CompilerConfigurationKey<Boolean>
= CompilerConfigurationKey.create("time backend phases")
val ENABLE_ASSERTIONS: CompilerConfigurationKey<Boolean>
= CompilerConfigurationKey.create("enable runtime assertions in generated code")
val VERIFY_BITCODE: CompilerConfigurationKey<Boolean>
= CompilerConfigurationKey.create("verify bitcode")
val VERIFY_DESCRIPTORS: CompilerConfigurationKey<Boolean>
= CompilerConfigurationKey.create("verify descriptors")
val VERIFY_IR: CompilerConfigurationKey<Boolean>
= CompilerConfigurationKey.create("verify ir")
val VERBOSE_PHASES: CompilerConfigurationKey<List<String>>
= CompilerConfigurationKey.create("verbose backend phases")
}
}
enum class CompilerOutputKind {
PROGRAM,
LIBRARY,
BITCODE
}
@@ -53,7 +53,6 @@ enum class KonanPhase(val description: String,
/* ... */ BITCODE("LLVM BitCode Generation"),
/* ... ... */ RTTI("RTTI Generation"),
/* ... ... */ CODEGEN("Code Generation"),
/* ... ... */ METADATOR("Metadata Generation"),
/* ... ... */ BITCODE_LINKER("Bitcode linking"),
/* */ LINK_STAGE("Link stage"),
/* ... */ OBJECT_FILES("Bitcode to object file"),
@@ -76,8 +75,8 @@ object KonanPhases {
with (config.configuration) { with (KonanConfigKeys) {
// Don't serialize anything to a final executable.
KonanPhase.SERIALIZER.enabled = getBoolean(NOLINK)
KonanPhase.METADATOR.enabled = getBoolean(NOLINK)
KonanPhase.SERIALIZER.enabled =
(get(PRODUCE) == CompilerOutputKind.LIBRARY)
val disabled = get(DISABLED_PHASES)
disabled?.forEach { phases[known(it)]!!.enabled = false }
@@ -205,7 +205,7 @@ internal class LinkStage(val context: Context) {
get() = if (nomain) emptyList() else platform.entrySelector
fun link(objectFiles: List<ObjectFile>): ExecutableFile {
val executable = config.get(KonanConfigKeys.EXECUTABLE_FILE)!!
val executable = config.get(KonanConfigKeys.OUTPUT_FILE)!!
val linkCommand = platform.linkCommand(objectFiles, executable, optimize) +
distribution.libffi +
asLinkerArgs(config.getNotNull(KonanConfigKeys.LINKER_ARGS)) +
@@ -103,13 +103,8 @@ internal fun String?.toFileAndFolder():FileAndFolder {
internal fun generateDebugInfoHeader(context: Context) {
if (context.shouldContainDebugInfo()) {
val path = with(context.config.configuration) {
if (!getBoolean(KonanConfigKeys.NOLINK)) {
get(KonanConfigKeys.EXECUTABLE_FILE)!!
} else {
get(KonanConfigKeys.LIBRARY_NAME)!!
}
}.toFileAndFolder()
val path = context.config.configuration.get(KonanConfigKeys.OUTPUT_FILE)!!
.toFileAndFolder()
context.debugInfo.module = DICreateModule(
builder = context.debugInfo.builder,
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.backend.common.descriptors.allParameters
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.CompilerOutputKind
import org.jetbrains.kotlin.backend.konan.KonanPhase
import org.jetbrains.kotlin.backend.konan.library.LinkData
import org.jetbrains.kotlin.backend.konan.PhaseManager
@@ -85,41 +86,48 @@ internal fun emitLLVM(context: Context) {
DIFinalize(context.debugInfo.builder)
}
if (!config.getBoolean(KonanConfigKeys.NOLINK)) {
val program = config.get(KonanConfigKeys.PROGRAM_NAME)!!
val output = "${program}.kt.bc"
context.bitcodeFileName = output
when (config.get(KonanConfigKeys.PRODUCE)) {
CompilerOutputKind.PROGRAM -> {
val program = config.get(KonanConfigKeys.OUTPUT_NAME)!!
val output = "${program}.kt.bc"
context.bitcodeFileName = output
phaser.phase(KonanPhase.BITCODE_LINKER) {
for (library in context.config.nativeLibraries) {
val libraryModule = parseBitcodeFile(library)
val failed = LLVMLinkModules2(llvmModule, libraryModule)
if (failed != 0) {
throw Error("failed to link $library") // TODO: retrieve error message from LLVM.
phaser.phase(KonanPhase.BITCODE_LINKER) {
for (library in context.config.nativeLibraries) {
val libraryModule = parseBitcodeFile(library)
val failed = LLVMLinkModules2(llvmModule, libraryModule)
if (failed != 0) {
throw Error("failed to link $library") // TODO: retrieve error message from LLVM.
}
}
}
}
LLVMWriteBitcodeToFile(llvmModule, output)
}
CompilerOutputKind.LIBRARY -> {
LLVMWriteBitcodeToFile(llvmModule, output)
} else {
val libraryName = config.get(KonanConfigKeys.OUTPUT_NAME)!!
val nopack = config.getBoolean(KonanConfigKeys.NOPACK)
val targetName = context.config.targetManager.currentName
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)
val library = buildLibrary(
phaser,
context.config.nativeLibraries,
context.serializedLinkData!!,
targetName,
libraryName,
llvmModule,
nopack)
context.library = library
context.library = library
context.bitcodeFileName =
library.mainBitcodeFileName
context.bitcodeFileName = library.mainBitcodeFileName
}
CompilerOutputKind.BITCODE -> {
val output = config.get(KonanConfigKeys.OUTPUT_FILE)!!
context.bitcodeFileName = output
LLVMWriteBitcodeToFile(llvmModule, output)
}
}
}
@@ -130,9 +138,7 @@ internal fun buildLibrary(phaser: PhaseManager, natives: List<String>, linkData:
library.addKotlinBitcode(llvmModule)
phaser.phase(KonanPhase.METADATOR) {
library.addLinkData(linkData)
}
library.addLinkData(linkData)
phaser.phase(KonanPhase.BITCODE_LINKER) {
natives.forEach {
+2 -3
View File
@@ -286,9 +286,8 @@ targetList.each { target ->
include('**')
into('klib/stdlib')
}
from(project(':runtime').file("build/${target}Start/$target/kotlin")) {
include("program.kt.bc")
rename('program.kt.bc', 'start.kt.bc')
from(project(':runtime').file("build/${target}Start.bc")) {
rename("${target}Start.bc", 'start.bc')
into("klib/stdlib/$target/native")
}
}