diff --git a/kotlin-native/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/jvm/CommandLine.kt b/kotlin-native/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/jvm/CommandLine.kt index e4a9a1bb23b..86b0d5b2f0e 100644 --- a/kotlin-native/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/jvm/CommandLine.kt +++ b/kotlin-native/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/jvm/CommandLine.kt @@ -19,6 +19,7 @@ package org.jetbrains.kotlin.native.interop.tool import kotlinx.cli.ArgParser import kotlinx.cli.ArgType import kotlinx.cli.* +import org.jetbrains.kotlin.native.interop.gen.jvm.GenerationMode const val HEADER_FILTER_ADDITIONAL_SEARCH_PREFIX = "headerFilterAdditionalSearchPrefix" const val NODEFAULTLIBS_DEPRECATED = "nodefaultlibs" @@ -46,7 +47,7 @@ open class CommonInteropArguments(val argParser: ArgParser) { .multiple() val repo by argParser.option(ArgType.String, shortName = "r", description = "repository to resolve dependencies") .multiple() - val mode by argParser.option(ArgType.Choice(listOf(MODE_METADATA, MODE_SOURCECODE)), description = "the way interop library is generated") + val mode by argParser.option(ArgType.Choice(), description = "the way interop library is generated") .default(DEFAULT_MODE) val nodefaultlibs by argParser.option(ArgType.Boolean, NODEFAULTLIBS, description = "don't link the libraries from dist/klib automatically").default(false) @@ -65,10 +66,7 @@ open class CommonInteropArguments(val argParser: ArgParser) { description = "additional kotlinc compiler option").multiple() companion object { - const val MODE_SOURCECODE = "sourcecode" - const val MODE_METADATA = "metadata" - - const val DEFAULT_MODE = MODE_METADATA + val DEFAULT_MODE = GenerationMode.METADATA } } @@ -127,8 +125,13 @@ open class CInteropArguments(argParser: ArgParser = class JSInteropArguments(argParser: ArgParser = ArgParser("jsinterop", prefixStyle = ArgParser.OptionPrefixStyle.JVM)): CommonInteropArguments(argParser) { - val target by argParser.option(ArgType.Choice(listOf("wasm32")), - description = "wasm target to compile to").default("wasm32") + enum class TargetType { + WASM32; + + override fun toString() = name.toLowerCase() + } + val target by argParser.option(ArgType.Choice(), + description = "wasm target to compile to").default(TargetType.WASM32) } internal fun warn(msg: String) { diff --git a/kotlin-native/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/jvm/GenerationMode.kt b/kotlin-native/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/jvm/GenerationMode.kt index 6174374932d..6fbd67d235d 100644 --- a/kotlin-native/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/jvm/GenerationMode.kt +++ b/kotlin-native/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/jvm/GenerationMode.kt @@ -1,13 +1,8 @@ package org.jetbrains.kotlin.native.interop.gen.jvm -import org.jetbrains.kotlin.native.interop.tool.CommonInteropArguments +enum class GenerationMode(val modeName: String) { + SOURCE_CODE("sourcecode"), + METADATA("metadata"); -enum class GenerationMode { - SOURCE_CODE, METADATA -} - -fun parseGenerationMode(mode: String): GenerationMode? = when(mode) { - CommonInteropArguments.MODE_METADATA -> GenerationMode.METADATA - CommonInteropArguments.MODE_SOURCECODE -> GenerationMode.SOURCE_CODE - else -> null + override fun toString(): String = modeName } \ No newline at end of file diff --git a/kotlin-native/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/jvm/main.kt b/kotlin-native/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/jvm/main.kt index 7fdcf966774..e7d58b300f1 100644 --- a/kotlin-native/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/jvm/main.kt +++ b/kotlin-native/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/jvm/main.kt @@ -50,8 +50,8 @@ data class InternalInteropOptions(val generated: String, val natives: String, va fun main(args: Array) { // Adding flavor option for interop plugin. class FullCInteropArguments: CInteropArguments() { - val flavor by argParser.option(ArgType.Choice(listOf("jvm", "native", "wasm")), description = "Interop target") - .default("jvm") + val flavor by argParser.option(ArgType.Choice(), description = "Interop target") + .default(KotlinPlatform.JVM) val generated by argParser.option(ArgType.String, description = "place generated bindings to the directory") .required() val natives by argParser.option(ArgType.String, description = "where to put the built native files") @@ -70,7 +70,8 @@ fun interop( "jvm", "native" -> { val cinteropArguments = CInteropArguments() cinteropArguments.argParser.parse(args) - processCLib(flavor, cinteropArguments, additionalArgs) + val platform = KotlinPlatform.values().single { it.name.equals(flavor, ignoreCase = true) } + processCLib(platform, cinteropArguments, additionalArgs) } "wasm" -> processIdlLib(args, additionalArgs) else -> error("Unexpected flavor") @@ -192,11 +193,10 @@ private fun findFilesByGlobs(roots: List, globs: List): Map? { val ktGenRoot = additionalArgs.generated val nativeLibsDir = additionalArgs.natives - val flavor = KotlinPlatform.values().single { it.name.equals(flavorName, ignoreCase = true) } val defFile = cinteropArguments.def?.let { File(it) } val manifestAddend = additionalArgs.manifest?.let { File(it) } @@ -210,7 +210,7 @@ private fun processCLib(flavorName: String, cinteropArguments: CInteropArguments val isLinkerOptsSetByUser = (cinteropArguments.linkerOpts.valueOrigin == ArgParser.ValueOrigin.SET_BY_USER) || (cinteropArguments.linkerOptions.valueOrigin == ArgParser.ValueOrigin.SET_BY_USER) || (cinteropArguments.linkerOption.valueOrigin == ArgParser.ValueOrigin.SET_BY_USER) - if (flavorName == "native" && isLinkerOptsSetByUser) { + if (flavor == KotlinPlatform.NATIVE && isLinkerOptsSetByUser) { warn("-linker-option(s)/-linkerOpts option is not supported by cinterop. Please add linker options to .def file or binary compilation instead.") } @@ -238,8 +238,7 @@ private fun processCLib(flavorName: String, cinteropArguments: CInteropArguments val outKtPkg = fqParts.joinToString(".") val mode = run { - val providedMode = parseGenerationMode(cinteropArguments.mode) - ?: error ("Unexpected interop generation mode: ${cinteropArguments.mode}") + val providedMode = cinteropArguments.mode if (providedMode == GenerationMode.METADATA && flavor == KotlinPlatform.JVM) { warn("Metadata mode isn't supported for Kotlin/JVM! Falling back to sourcecode.") diff --git a/kotlin-native/utilities/cli-runner/src/main/kotlin/org/jetbrains/kotlin/cli/utilities/GeneratePlatformLibraries.kt b/kotlin-native/utilities/cli-runner/src/main/kotlin/org/jetbrains/kotlin/cli/utilities/GeneratePlatformLibraries.kt index e86c72d9c7b..c4fc36d6c58 100644 --- a/kotlin-native/utilities/cli-runner/src/main/kotlin/org/jetbrains/kotlin/cli/utilities/GeneratePlatformLibraries.kt +++ b/kotlin-native/utilities/cli-runner/src/main/kotlin/org/jetbrains/kotlin/cli/utilities/GeneratePlatformLibraries.kt @@ -19,9 +19,8 @@ import org.jetbrains.kotlin.konan.target.customerDistribution import org.jetbrains.kotlin.konan.util.KonanHomeProvider import org.jetbrains.kotlin.konan.util.PlatformLibsInfo import org.jetbrains.kotlin.konan.util.visibleName +import org.jetbrains.kotlin.native.interop.gen.jvm.GenerationMode import org.jetbrains.kotlin.native.interop.tool.CommonInteropArguments.Companion.DEFAULT_MODE -import org.jetbrains.kotlin.native.interop.tool.CommonInteropArguments.Companion.MODE_METADATA -import org.jetbrains.kotlin.native.interop.tool.CommonInteropArguments.Companion.MODE_SOURCECODE import org.jetbrains.kotlin.native.interop.tool.SHORT_MODULE_NAME import java.io.PrintWriter import java.io.StringWriter @@ -64,6 +63,11 @@ private fun Logger.logStackTrace(error: Throwable) { verbose(stringWriter.toString()) } +private enum class CacheKind(val outputKind: CompilerOutputKind) { + DYNAMIC_CACHE(CompilerOutputKind.DYNAMIC_CACHE), + STATIC_CACHE(CompilerOutputKind.STATIC_CACHE) +} + // TODO: Use Distribution's paths after compiler update. fun generatePlatformLibraries(args: Array) { // IMPORTANT! These command line keys are used by the Gradle plugin to configure platform libraries generation, @@ -90,17 +94,15 @@ fun generatePlatformLibraries(args: Array) { "Place where stdlib is located. Default value is /klib/common/stdlib" ) - val dynamicCacheKind = CompilerOutputKind.DYNAMIC_CACHE.visibleName - val staticCacheKind = CompilerOutputKind.STATIC_CACHE.visibleName val cacheKind by argParser.option( - ArgType.Choice(listOf(dynamicCacheKind, staticCacheKind)), "cache-kind", "k", "Type of cache." - ).default(dynamicCacheKind) + ArgType.Choice(toString = { it.outputKind.visibleName }), "cache-kind", "k", "Type of cache." + ).default(CacheKind.DYNAMIC_CACHE) val cacheDirectoryPath by argParser.option( ArgType.String, "cache-directory", "c", "Cache output directory") val mode by argParser.option( - ArgType.Choice(listOf(MODE_METADATA, MODE_SOURCECODE)), + ArgType.Choice(), fullName = "mode", shortName = "m", description = "The way interop library is generated." @@ -146,7 +148,7 @@ fun generatePlatformLibraries(args: Array) { val logger = Logger(if (verbose) Logger.Level.VERBOSE else Logger.Level.NORMAL) - val cacheInfo = cacheDirectory?.let { CacheInfo(it, cacheKind, cacheArgs) } + val cacheInfo = cacheDirectory?.let { CacheInfo(it, cacheKind.outputKind.visibleName, cacheArgs) } generatePlatformLibraries( target, mode, @@ -217,7 +219,7 @@ private fun topoSort(defFiles: List): List { private fun generateLibrary( target: KonanTarget, - mode: String, + mode: GenerationMode, def: DefFile, directories: DirectoriesInfo, tmpDirectory: File, @@ -242,7 +244,7 @@ private fun generateLibrary( "-compiler-option", "-fmodules-cache-path=${tmpDirectory.child("clangModulesCache").absolutePath}", "-repo", outputDirectory.absolutePath, "-no-default-libs", "-no-endorsed-libs", "-Xpurge-user-libs", "-nopack", - "-mode", mode, + "-mode", mode.modeName, "-$SHORT_MODULE_NAME", def.shortLibraryName, *def.depends.flatMap { listOf("-l", "$outputDirectory/${it.libraryName}") }.toTypedArray() ) @@ -327,7 +329,7 @@ private fun buildStdlibCache( K2Native.mainNoExit(compilerArgs) } -private fun generatePlatformLibraries(target: KonanTarget, mode: String, +private fun generatePlatformLibraries(target: KonanTarget, mode: GenerationMode, directories: DirectoriesInfo, cacheInfo: CacheInfo?, rebuild: Boolean, saveTemps: Boolean, logger: Logger) = with(directories) { if (cacheInfo != null) { diff --git a/kotlin-native/utilities/cli-runner/src/main/kotlin/org/jetbrains/kotlin/cli/utilities/InteropCompiler.kt b/kotlin-native/utilities/cli-runner/src/main/kotlin/org/jetbrains/kotlin/cli/utilities/InteropCompiler.kt index c2e7a97fdcc..829fc2fe7e8 100644 --- a/kotlin-native/utilities/cli-runner/src/main/kotlin/org/jetbrains/kotlin/cli/utilities/InteropCompiler.kt +++ b/kotlin-native/utilities/cli-runner/src/main/kotlin/org/jetbrains/kotlin/cli/utilities/InteropCompiler.kt @@ -39,7 +39,7 @@ fun invokeInterop(flavor: String, args: Array): Array? { val libraries = arguments.library val repos = arguments.repo val targetRequest = if (arguments is CInteropArguments) arguments.target - else (arguments as JSInteropArguments).target + else (arguments as JSInteropArguments).target.toString() val target = PlatformManager(KonanHomeProvider.determineKonanHome()).targetManager(targetRequest).target val cinteropArgsToCompiler = interop(flavor, args,