-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:
committed by
alexander-gorshenev
parent
34491cfb01
commit
380010d1ee
@@ -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)
|
||||
|
||||
+4
-3
@@ -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;
|
||||
|
||||
}
|
||||
|
||||
|
||||
+56
-57
@@ -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
|
||||
}
|
||||
|
||||
+2
-3
@@ -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 }
|
||||
|
||||
+1
-1
@@ -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)) +
|
||||
|
||||
+2
-7
@@ -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,
|
||||
|
||||
+37
-31
@@ -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
@@ -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")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user