[KT-39120] Add "-fmodules" argument support to Cinterop

Merge-request: KT-MR-6921
Merged-by: Vladimir Sukharev <Vladimir.Sukharev@jetbrains.com>
This commit is contained in:
Vladimir Sukharev
2022-11-30 08:46:40 +00:00
committed by Space Team
parent 10fc86ef92
commit b883dc5434
173 changed files with 2707 additions and 214 deletions
@@ -335,7 +335,8 @@ class StubIrBuilder(private val context: StubIrContext) {
nativeIndex.enums.forEach { generateStubsForEnum(it) }
nativeIndex.functions.filter { it.name !in excludedFunctions }.forEach { generateStubsForFunction(it) }
nativeIndex.typedefs.forEach { generateStubsForTypedef(it) }
nativeIndex.globals.filter { it.name !in excludedFunctions }.forEach { generateStubsForGlobal(it) }
// globals are sorted, so its numbering is stable and thus testable with golden data
nativeIndex.globals.filter { it.name !in excludedFunctions }.sortedBy { it.name }.forEach { generateStubsForGlobal(it) }
nativeIndex.macroConstants.filter { it.name !in excludedMacros }.forEach { generateStubsForMacroConstant(it) }
nativeIndex.wrappedMacros.filter { it.name !in excludedMacros }.forEach { generateStubsForWrappedMacro(it) }
@@ -68,21 +68,36 @@ fun main(args: Array<String>) {
processCLibSafe(flavorName, arguments, InternalInteropOptions(arguments.generated, arguments.natives), runFromDaemon = false)
}
fun interop(
flavor: String, args: Array<String>,
additionalArgs: InternalInteropOptions,
runFromDaemon: Boolean
): Array<String>? = when (flavor) {
"jvm", "native" -> {
val cinteropArguments = CInteropArguments()
cinteropArguments.argParser.parse(args)
val platform = KotlinPlatform.values().single { it.name.equals(flavor, ignoreCase = true) }
processCLibSafe(platform, cinteropArguments, additionalArgs, runFromDaemon)
class Interop {
/**
* invoked via reflection from new test system: CompilationToolCallKt.invokeCInterop(),
* `interop()` has issues to be invoked directly due to NoSuchMethodError, caused by presence of InternalInteropOptions argtype:
* java.lang.IllegalArgumentException: argument type mismatch
*/
fun interopViaReflection(
flavor: String, args: Array<String>,
runFromDaemon: Boolean,
generated: String, natives: String, manifest: String? = null, cstubsName: String? = null
): Array<String>? {
val internalInteropOptions = InternalInteropOptions(generated, natives, manifest, cstubsName)
return interop(flavor, args, internalInteropOptions, runFromDaemon)
}
"wasm" -> processIdlLib(args, additionalArgs)
else -> error("Unexpected flavor")
}
fun interop(
flavor: String, args: Array<String>,
additionalArgs: InternalInteropOptions,
runFromDaemon: Boolean
): Array<String>? = when (flavor) {
"jvm", "native" -> {
val cinteropArguments = CInteropArguments()
cinteropArguments.argParser.parse(args)
val platform = KotlinPlatform.values().single { it.name.equals(flavor, ignoreCase = true) }
processCLibSafe(platform, cinteropArguments, additionalArgs, runFromDaemon)
}
"wasm" -> processIdlLib(args, additionalArgs)
else -> error("Unexpected flavor")
}
}
// Options, whose values are space-separated and can be escaped.
val escapedOptions = setOf("-compilerOpts", "-linkerOpts", "-compiler-options", "-linker-options")
@@ -390,7 +405,7 @@ private fun processCLib(flavor: KotlinPlatform, cinteropArguments: CInteropArgum
// Note that the output bitcode contains the source file path, which can lead to non-deterministc builds (see KT-54284).
// The source file is passed in via stdin to ensure the output library is deterministic.
val compilerCmd = arrayOf(compiler, *compilerArgs,
"-emit-llvm", "-x", library.language.clangLanguageName, "-c", "-", "-o", outLib.absolutePath)
"-emit-llvm", "-x", library.language.clangLanguageName, "-c", "-", "-o", outLib.absolutePath, "-Xclang", "-detailed-preprocessing-record")
runCmd(compilerCmd, verbose, redirectInputFile = File(outCFile.absolutePath))
outLib.absolutePath
}
@@ -496,11 +511,19 @@ internal fun buildNativeLibrary(
addAll(tool.getDefaultCompilerOptsForLanguage(language))
addAll(additionalCompilerOpts)
addAll(getCompilerFlagsForVfsOverlay(arguments.headerFilterPrefix.toTypedArray(), def))
add("-Wno-builtin-macro-redefined") // to suppress warning from predefinedMacrosRedefinitions(see below)
}
// Expanding macros such as __FILE__ or __TIME__ exposes arbitrary generated filenames and timestamps from the compiler pipeline
// which are not useful for interop though makes the klib generation non-deterministic. See KT-54284
// This macro redefinition just maps to their name in the properties available from Kotlin.
val predefinedMacrosRedefinitions = predefinedMacros.map {
"#define $it \"$it\""
}
val compilation = CompilationImpl(
includes = headerFiles,
additionalPreambleLines = def.defHeaderLines,
additionalPreambleLines = def.defHeaderLines + predefinedMacrosRedefinitions,
compilerArgs = defaultCompilerArgs(language) + compilerOpts + tool.platformCompilerOpts,
language = language
)
@@ -511,6 +534,7 @@ internal fun buildNativeLibrary(
val modules = def.config.modules
if (modules.isEmpty()) {
require(headerFiles.isEmpty() || !compilation.compilerArgs.contains("-fmodules")) { "cinterop doesn't support having headers in -fmodules mode" }
val excludeDependentModules = def.config.excludeDependentModules
val headerFilterGlobs = def.config.headerFilter
@@ -526,7 +550,7 @@ internal fun buildNativeLibrary(
val modulesInfo = getModulesInfo(compilation, modules)
headerFilter = NativeLibraryHeaderFilter.Predefined(modulesInfo.ownHeaders)
headerFilter = NativeLibraryHeaderFilter.Predefined(modulesInfo.ownHeaders, modulesInfo.modules)
includes = modulesInfo.topLevelHeaders
}
@@ -13,7 +13,6 @@ import org.jetbrains.kotlin.native.interop.gen.jvm.KotlinPlatform
import org.jetbrains.kotlin.native.interop.gen.jvm.buildNativeLibrary
import org.jetbrains.kotlin.native.interop.gen.jvm.prepareTool
import org.jetbrains.kotlin.native.interop.indexer.NativeLibrary
import org.jetbrains.kotlin.native.interop.indexer.getHeaderPaths
import org.jetbrains.kotlin.native.interop.tool.CInteropArguments
import kotlin.test.*
import java.io.File