[K/N] Untie C header generation from NativeGenerationState

This commit is contained in:
Sergey Bogolepov
2023-01-25 12:05:37 +02:00
committed by Space Team
parent 8516ae2b72
commit bb1feabb79
4 changed files with 40 additions and 17 deletions
@@ -5,26 +5,34 @@
package org.jetbrains.kotlin.backend.konan.cexport
import org.jetbrains.kotlin.backend.konan.NativeGenerationState
import org.jetbrains.kotlin.builtins.UnsignedType
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.findClassAcrossModuleDependencies
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.typeUtil.isNothing
import org.jetbrains.kotlin.types.typeUtil.isUnit
import org.jetbrains.kotlin.types.typeUtil.makeNullable
import java.io.PrintWriter
import java.io.File
/**
* Third phase of C export:
* 1. Create a C++ file with runtime bindings
* 2. Create a header file with API
* 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(
private val generationState: NativeGenerationState,
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 builtIns = elements.typeTranslator.builtIns
@@ -155,7 +163,6 @@ internal class CAdapterApiExporter(
// TODO: Pass temp and output files explicitly and untie from `NativeGenerationState`.
fun makeGlobalStruct() {
val top = elements.scopes.first()
val headerFile = generationState.outputFiles.cAdapterHeader
outputStreamWriter = headerFile.printWriter()
val exportedSymbol = "${prefix}_symbols"
@@ -188,7 +195,7 @@ internal class CAdapterApiExporter(
output("typedef double ${prefix}_KDouble;")
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.
output("#ifndef _MSC_VER")
output(typedef_KVector128)
@@ -240,9 +247,7 @@ internal class CAdapterApiExporter(
outputStreamWriter.close()
println("Produced library API in ${prefix}_api.h")
outputStreamWriter = generationState.tempFiles
.cAdapterCpp
.printWriter()
outputStreamWriter = cppAdapterFile.printWriter()
// Include header into C++ source.
headerFile.forEachLine { it -> output(it) }
@@ -379,10 +384,8 @@ internal class CAdapterApiExporter(
output("RUNTIME_USED ${prefix}_ExportedSymbols* $exportedSymbol(void) { return &__konan_symbols;}")
outputStreamWriter.close()
if (generationState.config.target.family == Family.MINGW) {
outputStreamWriter = generationState.outputFiles
.cAdapterDef
.printWriter()
if (defFile != null) {
outputStreamWriter = defFile.printWriter()
output("EXPORTS")
exportedSymbols.forEach { output(it) }
outputStreamWriter.close()
@@ -5,11 +5,12 @@
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.CAdapterExportedElements
import org.jetbrains.kotlin.backend.konan.cexport.CAdapterGenerator
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>(
"BuildCExports", "Build C exports",
@@ -20,9 +21,22 @@ internal val BuildCExports = createSimpleNamedCompilerPhase<PsiToIrContext, Fron
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",
description = "Create C header for the exported API",
) { context, _ ->
CAdapterApiExporter(context, context.context.cAdapterExportedElements!!).makeGlobalStruct()
) { context, input ->
CAdapterApiExporter(
elements = input.elements,
headerFile = input.headerFile,
defFile = input.defFile,
cppAdapterFile = input.cppAdapterFile,
target = context.config.target,
).makeGlobalStruct()
}
@@ -18,6 +18,7 @@ import org.jetbrains.kotlin.ir.declarations.path
import org.jetbrains.kotlin.ir.util.hasAnnotation
import org.jetbrains.kotlin.konan.TempFiles
import org.jetbrains.kotlin.konan.target.CompilerOutputKind
import org.jetbrains.kotlin.konan.target.Family
import org.jetbrains.kotlin.library.impl.javaFile
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)
runCodegen(module)
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)
// TODO: Consider extracting llvmModule and friends from nativeGenerationState and pass them explicitly.
@@ -10,7 +10,6 @@ import llvm.*
import org.jetbrains.kotlin.backend.common.lower.coroutines.getOrCreateFunctionWithContinuationStub
import org.jetbrains.kotlin.backend.common.lower.inline.InlinerExpressionLocationHint
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.CAdapterExportedElements
import org.jetbrains.kotlin.backend.konan.cgen.CBridgeOrigin