[K/N] Untie C header generation from NativeGenerationState
This commit is contained in:
committed by
Space Team
parent
8516ae2b72
commit
bb1feabb79
+14
-11
@@ -5,26 +5,34 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.backend.konan.cexport
|
package org.jetbrains.kotlin.backend.konan.cexport
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.konan.NativeGenerationState
|
|
||||||
import org.jetbrains.kotlin.builtins.UnsignedType
|
import org.jetbrains.kotlin.builtins.UnsignedType
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.findClassAcrossModuleDependencies
|
import org.jetbrains.kotlin.descriptors.findClassAcrossModuleDependencies
|
||||||
import org.jetbrains.kotlin.konan.target.Family
|
import org.jetbrains.kotlin.konan.target.Family
|
||||||
|
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.kotlin.types.typeUtil.isNothing
|
import org.jetbrains.kotlin.types.typeUtil.isNothing
|
||||||
import org.jetbrains.kotlin.types.typeUtil.isUnit
|
import org.jetbrains.kotlin.types.typeUtil.isUnit
|
||||||
import org.jetbrains.kotlin.types.typeUtil.makeNullable
|
import org.jetbrains.kotlin.types.typeUtil.makeNullable
|
||||||
import java.io.PrintWriter
|
import java.io.PrintWriter
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Third phase of C export:
|
* Third phase of C export:
|
||||||
* 1. Create a C++ file with runtime bindings
|
* 1. Create a C++ file with runtime bindings
|
||||||
* 2. Create a header file with API
|
* 2. Create a header file with API
|
||||||
* 3. (MinGW only) create EXPORTS def file.
|
* 3. (MinGW only) create EXPORTS def file.
|
||||||
|
*
|
||||||
|
* @param headerFile C header file that will be populated with the exported C API.
|
||||||
|
* @param defFile DLL module definition file
|
||||||
|
* @param cppAdapterFile C++ source that will be populated with glue code between K/N runtime and exported API.
|
||||||
*/
|
*/
|
||||||
internal class CAdapterApiExporter(
|
internal class CAdapterApiExporter(
|
||||||
private val generationState: NativeGenerationState,
|
|
||||||
private val elements: CAdapterExportedElements,
|
private val elements: CAdapterExportedElements,
|
||||||
|
private val headerFile: File,
|
||||||
|
private val defFile: File?,
|
||||||
|
private val cppAdapterFile: File,
|
||||||
|
private val target: KonanTarget,
|
||||||
) {
|
) {
|
||||||
private val typeTranslator = elements.typeTranslator
|
private val typeTranslator = elements.typeTranslator
|
||||||
private val builtIns = elements.typeTranslator.builtIns
|
private val builtIns = elements.typeTranslator.builtIns
|
||||||
@@ -155,7 +163,6 @@ internal class CAdapterApiExporter(
|
|||||||
// TODO: Pass temp and output files explicitly and untie from `NativeGenerationState`.
|
// TODO: Pass temp and output files explicitly and untie from `NativeGenerationState`.
|
||||||
fun makeGlobalStruct() {
|
fun makeGlobalStruct() {
|
||||||
val top = elements.scopes.first()
|
val top = elements.scopes.first()
|
||||||
val headerFile = generationState.outputFiles.cAdapterHeader
|
|
||||||
outputStreamWriter = headerFile.printWriter()
|
outputStreamWriter = headerFile.printWriter()
|
||||||
|
|
||||||
val exportedSymbol = "${prefix}_symbols"
|
val exportedSymbol = "${prefix}_symbols"
|
||||||
@@ -188,7 +195,7 @@ internal class CAdapterApiExporter(
|
|||||||
output("typedef double ${prefix}_KDouble;")
|
output("typedef double ${prefix}_KDouble;")
|
||||||
|
|
||||||
val typedef_KVector128 = "typedef float __attribute__ ((__vector_size__ (16))) ${prefix}_KVector128;"
|
val typedef_KVector128 = "typedef float __attribute__ ((__vector_size__ (16))) ${prefix}_KVector128;"
|
||||||
if (generationState.config.target.family == Family.MINGW) {
|
if (target.family == Family.MINGW) {
|
||||||
// Separate `output` for each line to ensure Windows EOL (LFCR), otherwise generated file will have inconsistent line ending.
|
// Separate `output` for each line to ensure Windows EOL (LFCR), otherwise generated file will have inconsistent line ending.
|
||||||
output("#ifndef _MSC_VER")
|
output("#ifndef _MSC_VER")
|
||||||
output(typedef_KVector128)
|
output(typedef_KVector128)
|
||||||
@@ -240,9 +247,7 @@ internal class CAdapterApiExporter(
|
|||||||
outputStreamWriter.close()
|
outputStreamWriter.close()
|
||||||
println("Produced library API in ${prefix}_api.h")
|
println("Produced library API in ${prefix}_api.h")
|
||||||
|
|
||||||
outputStreamWriter = generationState.tempFiles
|
outputStreamWriter = cppAdapterFile.printWriter()
|
||||||
.cAdapterCpp
|
|
||||||
.printWriter()
|
|
||||||
|
|
||||||
// Include header into C++ source.
|
// Include header into C++ source.
|
||||||
headerFile.forEachLine { it -> output(it) }
|
headerFile.forEachLine { it -> output(it) }
|
||||||
@@ -379,10 +384,8 @@ internal class CAdapterApiExporter(
|
|||||||
output("RUNTIME_USED ${prefix}_ExportedSymbols* $exportedSymbol(void) { return &__konan_symbols;}")
|
output("RUNTIME_USED ${prefix}_ExportedSymbols* $exportedSymbol(void) { return &__konan_symbols;}")
|
||||||
outputStreamWriter.close()
|
outputStreamWriter.close()
|
||||||
|
|
||||||
if (generationState.config.target.family == Family.MINGW) {
|
if (defFile != null) {
|
||||||
outputStreamWriter = generationState.outputFiles
|
outputStreamWriter = defFile.printWriter()
|
||||||
.cAdapterDef
|
|
||||||
.printWriter()
|
|
||||||
output("EXPORTS")
|
output("EXPORTS")
|
||||||
exportedSymbols.forEach { output(it) }
|
exportedSymbols.forEach { output(it) }
|
||||||
outputStreamWriter.close()
|
outputStreamWriter.close()
|
||||||
|
|||||||
+18
-4
@@ -5,11 +5,12 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.backend.konan.driver.phases
|
package org.jetbrains.kotlin.backend.konan.driver.phases
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.konan.NativeGenerationState
|
|
||||||
import org.jetbrains.kotlin.backend.konan.cexport.CAdapterApiExporter
|
import org.jetbrains.kotlin.backend.konan.cexport.CAdapterApiExporter
|
||||||
import org.jetbrains.kotlin.backend.konan.cexport.CAdapterExportedElements
|
import org.jetbrains.kotlin.backend.konan.cexport.CAdapterExportedElements
|
||||||
import org.jetbrains.kotlin.backend.konan.cexport.CAdapterGenerator
|
import org.jetbrains.kotlin.backend.konan.cexport.CAdapterGenerator
|
||||||
import org.jetbrains.kotlin.backend.konan.cexport.CAdapterTypeTranslator
|
import org.jetbrains.kotlin.backend.konan.cexport.CAdapterTypeTranslator
|
||||||
|
import org.jetbrains.kotlin.backend.konan.driver.PhaseContext
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
internal val BuildCExports = createSimpleNamedCompilerPhase<PsiToIrContext, FrontendPhaseOutput.Full, CAdapterExportedElements>(
|
internal val BuildCExports = createSimpleNamedCompilerPhase<PsiToIrContext, FrontendPhaseOutput.Full, CAdapterExportedElements>(
|
||||||
"BuildCExports", "Build C exports",
|
"BuildCExports", "Build C exports",
|
||||||
@@ -20,9 +21,22 @@ internal val BuildCExports = createSimpleNamedCompilerPhase<PsiToIrContext, Fron
|
|||||||
CAdapterGenerator(context, typeTranslator).buildExports(input.moduleDescriptor)
|
CAdapterGenerator(context, typeTranslator).buildExports(input.moduleDescriptor)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal val CExportGenerateApiPhase = createSimpleNamedCompilerPhase<NativeGenerationState, Unit>(
|
internal data class CExportGenerateApiInput(
|
||||||
|
val elements: CAdapterExportedElements,
|
||||||
|
val headerFile: File,
|
||||||
|
val defFile: File?,
|
||||||
|
val cppAdapterFile: File,
|
||||||
|
)
|
||||||
|
|
||||||
|
internal val CExportGenerateApiPhase = createSimpleNamedCompilerPhase<PhaseContext, CExportGenerateApiInput>(
|
||||||
name = "CExportGenerateApi",
|
name = "CExportGenerateApi",
|
||||||
description = "Create C header for the exported API",
|
description = "Create C header for the exported API",
|
||||||
) { context, _ ->
|
) { context, input ->
|
||||||
CAdapterApiExporter(context, context.context.cAdapterExportedElements!!).makeGlobalStruct()
|
CAdapterApiExporter(
|
||||||
|
elements = input.elements,
|
||||||
|
headerFile = input.headerFile,
|
||||||
|
defFile = input.defFile,
|
||||||
|
cppAdapterFile = input.cppAdapterFile,
|
||||||
|
target = context.config.target,
|
||||||
|
).makeGlobalStruct()
|
||||||
}
|
}
|
||||||
+8
-1
@@ -18,6 +18,7 @@ import org.jetbrains.kotlin.ir.declarations.path
|
|||||||
import org.jetbrains.kotlin.ir.util.hasAnnotation
|
import org.jetbrains.kotlin.ir.util.hasAnnotation
|
||||||
import org.jetbrains.kotlin.konan.TempFiles
|
import org.jetbrains.kotlin.konan.TempFiles
|
||||||
import org.jetbrains.kotlin.konan.target.CompilerOutputKind
|
import org.jetbrains.kotlin.konan.target.CompilerOutputKind
|
||||||
|
import org.jetbrains.kotlin.konan.target.Family
|
||||||
import org.jetbrains.kotlin.library.impl.javaFile
|
import org.jetbrains.kotlin.library.impl.javaFile
|
||||||
|
|
||||||
internal fun PhaseEngine<PhaseContext>.runFrontend(config: KonanConfig, environment: KotlinCoreEnvironment): FrontendPhaseOutput.Full? {
|
internal fun PhaseEngine<PhaseContext>.runFrontend(config: KonanConfig, environment: KotlinCoreEnvironment): FrontendPhaseOutput.Full? {
|
||||||
@@ -174,7 +175,13 @@ internal fun PhaseEngine<NativeGenerationState>.runBackendCodegen(module: IrModu
|
|||||||
mergeDependencies(module, dependenciesToCompile)
|
mergeDependencies(module, dependenciesToCompile)
|
||||||
runCodegen(module)
|
runCodegen(module)
|
||||||
if (context.config.produce.isNativeLibrary) {
|
if (context.config.produce.isNativeLibrary) {
|
||||||
runPhase(CExportGenerateApiPhase)
|
val input = CExportGenerateApiInput(
|
||||||
|
context.context.cAdapterExportedElements!!,
|
||||||
|
headerFile = context.outputFiles.cAdapterHeader.javaFile(),
|
||||||
|
defFile = if (context.config.target.family == Family.MINGW) context.outputFiles.cAdapterDef.javaFile() else null,
|
||||||
|
cppAdapterFile = context.tempFiles.cAdapterCpp.javaFile()
|
||||||
|
)
|
||||||
|
runPhase(CExportGenerateApiPhase, input)
|
||||||
}
|
}
|
||||||
runPhase(CStubsPhase)
|
runPhase(CStubsPhase)
|
||||||
// TODO: Consider extracting llvmModule and friends from nativeGenerationState and pass them explicitly.
|
// TODO: Consider extracting llvmModule and friends from nativeGenerationState and pass them explicitly.
|
||||||
|
|||||||
-1
@@ -10,7 +10,6 @@ import llvm.*
|
|||||||
import org.jetbrains.kotlin.backend.common.lower.coroutines.getOrCreateFunctionWithContinuationStub
|
import org.jetbrains.kotlin.backend.common.lower.coroutines.getOrCreateFunctionWithContinuationStub
|
||||||
import org.jetbrains.kotlin.backend.common.lower.inline.InlinerExpressionLocationHint
|
import org.jetbrains.kotlin.backend.common.lower.inline.InlinerExpressionLocationHint
|
||||||
import org.jetbrains.kotlin.backend.konan.*
|
import org.jetbrains.kotlin.backend.konan.*
|
||||||
import org.jetbrains.kotlin.backend.konan.cexport.CAdapterApiExporter
|
|
||||||
import org.jetbrains.kotlin.backend.konan.cexport.CAdapterCodegen
|
import org.jetbrains.kotlin.backend.konan.cexport.CAdapterCodegen
|
||||||
import org.jetbrains.kotlin.backend.konan.cexport.CAdapterExportedElements
|
import org.jetbrains.kotlin.backend.konan.cexport.CAdapterExportedElements
|
||||||
import org.jetbrains.kotlin.backend.konan.cgen.CBridgeOrigin
|
import org.jetbrains.kotlin.backend.konan.cgen.CBridgeOrigin
|
||||||
|
|||||||
Reference in New Issue
Block a user