[Interop] Move dependency resolution into processCLib
Because metadata mode doesn't call compiler we need to resolve dependencies (including stdlib) by hand. This logic was partially implemented in `InteropCompiler.kt`. So we move it into `processCLib`.
This commit is contained in:
committed by
Sergey Bogolepov
parent
2e22d5a389
commit
e714f1e067
+4
-1
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.konan.library.impl.KonanLibraryWriterImpl
|
|||||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||||
import org.jetbrains.kotlin.library.KotlinLibraryVersioning
|
import org.jetbrains.kotlin.library.KotlinLibraryVersioning
|
||||||
import org.jetbrains.kotlin.library.KotlinAbiVersion
|
import org.jetbrains.kotlin.library.KotlinAbiVersion
|
||||||
|
import org.jetbrains.kotlin.library.KotlinLibrary
|
||||||
import org.jetbrains.kotlin.library.SerializedMetadata
|
import org.jetbrains.kotlin.library.SerializedMetadata
|
||||||
import org.jetbrains.kotlin.util.removeSuffixIfPresent
|
import org.jetbrains.kotlin.util.removeSuffixIfPresent
|
||||||
import java.util.*
|
import java.util.*
|
||||||
@@ -24,7 +25,8 @@ data class LibraryCreationArguments(
|
|||||||
val moduleName: String,
|
val moduleName: String,
|
||||||
val nativeBitcodePath: String,
|
val nativeBitcodePath: String,
|
||||||
val target: KonanTarget,
|
val target: KonanTarget,
|
||||||
val manifest: Properties
|
val manifest: Properties,
|
||||||
|
val dependencies: List<KotlinLibrary>
|
||||||
)
|
)
|
||||||
|
|
||||||
fun createInteropLibrary(arguments: LibraryCreationArguments) {
|
fun createInteropLibrary(arguments: LibraryCreationArguments) {
|
||||||
@@ -47,6 +49,7 @@ fun createInteropLibrary(arguments: LibraryCreationArguments) {
|
|||||||
addMetadata(SerializedMetadata(metadata.header, metadata.fragments, metadata.fragmentNames))
|
addMetadata(SerializedMetadata(metadata.header, metadata.fragments, metadata.fragmentNames))
|
||||||
addNativeBitcode(arguments.nativeBitcodePath)
|
addNativeBitcode(arguments.nativeBitcodePath)
|
||||||
addManifestAddend(arguments.manifest)
|
addManifestAddend(arguments.manifest)
|
||||||
|
addLinkDependencies(arguments.dependencies)
|
||||||
commit()
|
commit()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+46
-17
@@ -24,8 +24,12 @@ import org.jetbrains.kotlin.native.interop.gen.wasm.processIdlLib
|
|||||||
import org.jetbrains.kotlin.native.interop.indexer.*
|
import org.jetbrains.kotlin.native.interop.indexer.*
|
||||||
import org.jetbrains.kotlin.native.interop.tool.*
|
import org.jetbrains.kotlin.native.interop.tool.*
|
||||||
import kotlinx.cli.ArgParser
|
import kotlinx.cli.ArgParser
|
||||||
import org.jetbrains.kotlin.konan.library.KLIB_INTEROP_IR_PROVIDER_IDENTIFIER
|
import org.jetbrains.kotlin.konan.library.*
|
||||||
|
import org.jetbrains.kotlin.konan.target.Distribution
|
||||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||||
|
import org.jetbrains.kotlin.library.KotlinLibrary
|
||||||
|
import org.jetbrains.kotlin.library.resolver.impl.libraryResolver
|
||||||
|
import org.jetbrains.kotlin.library.toUnresolvedLibraries
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.lang.IllegalArgumentException
|
import java.lang.IllegalArgumentException
|
||||||
import java.nio.file.*
|
import java.nio.file.*
|
||||||
@@ -98,15 +102,14 @@ private fun selectNativeLanguage(config: DefFile.DefFileConfig): Language {
|
|||||||
error("Unexpected language '$language'. Possible values are: ${languages.keys.joinToString { "'$it'" }}")
|
error("Unexpected language '$language'. Possible values are: ${languages.keys.joinToString { "'$it'" }}")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun parseImports(imports: Array<String>): ImportsImpl {
|
private fun parseImports(dependencies: List<KotlinLibrary>): ImportsImpl =
|
||||||
val headerIdToPackage = imports.map { arg ->
|
dependencies.filterIsInstance<KonanLibrary>().mapNotNull { library ->
|
||||||
val (pkg, joinedIds) = arg.split(':')
|
// TODO: handle missing properties?
|
||||||
val ids = joinedIds.split(';')
|
library.packageFqName?.let { packageFqName ->
|
||||||
ids.map { HeaderId(it) to pkg }
|
val headerIds = library.includedHeaders
|
||||||
}.reversed().flatten().toMap()
|
headerIds.map { HeaderId(it) to packageFqName }
|
||||||
|
}
|
||||||
return ImportsImpl(headerIdToPackage)
|
}.reversed().flatten().toMap().let(::ImportsImpl)
|
||||||
}
|
|
||||||
|
|
||||||
fun getCompilerFlagsForVfsOverlay(headerFilterPrefix: Array<String>, def: DefFile): List<String> {
|
fun getCompilerFlagsForVfsOverlay(headerFilterPrefix: Array<String>, def: DefFile): List<String> {
|
||||||
val relativeToRoot = mutableMapOf<Path, Path>() // TODO: handle clashes
|
val relativeToRoot = mutableMapOf<Path, Path>() // TODO: handle clashes
|
||||||
@@ -161,7 +164,6 @@ private fun findFilesByGlobs(roots: List<Path>, globs: List<String>): Map<Path,
|
|||||||
return relativeToRoot
|
return relativeToRoot
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun processCLib(args: Array<String>, additionalArgs: Map<String, Any> = mapOf()): Array<String>? {
|
private fun processCLib(args: Array<String>, additionalArgs: Map<String, Any> = mapOf()): Array<String>? {
|
||||||
val cinteropArguments = CInteropArguments()
|
val cinteropArguments = CInteropArguments()
|
||||||
cinteropArguments.argParser.parse(args)
|
cinteropArguments.argParser.parse(args)
|
||||||
@@ -209,11 +211,19 @@ private fun processCLib(args: Array<String>, additionalArgs: Map<String, Any> =
|
|||||||
|
|
||||||
val outKtPkg = fqParts.joinToString(".")
|
val outKtPkg = fqParts.joinToString(".")
|
||||||
|
|
||||||
val libName = (additionalArgs["cstubsname"] as? String)?: fqParts.joinToString("") + "stubs"
|
val mode = parseGenerationMode(cinteropArguments.mode)
|
||||||
|
?: error ("Unexpected interop generation mode: ${cinteropArguments.mode}")
|
||||||
|
|
||||||
|
val allLibraryDependencies = when (flavor) {
|
||||||
|
KotlinPlatform.NATIVE -> resolveDependencies(cinteropArguments, tool.target)
|
||||||
|
else -> listOf()
|
||||||
|
}
|
||||||
|
|
||||||
|
val libName = additionalArgs["cstubsName"] as? String ?: fqParts.joinToString("") + "stubs"
|
||||||
|
|
||||||
val tempFiles = TempFiles(libName, cinteropArguments.tempDir)
|
val tempFiles = TempFiles(libName, cinteropArguments.tempDir)
|
||||||
|
|
||||||
val imports = parseImports((additionalArgs["import"] as? List<String>)?.toTypedArray() ?: arrayOf())
|
val imports = parseImports(allLibraryDependencies)
|
||||||
|
|
||||||
val library = buildNativeLibrary(tool, def, cinteropArguments, imports)
|
val library = buildNativeLibrary(tool, def, cinteropArguments, imports)
|
||||||
|
|
||||||
@@ -251,9 +261,6 @@ private fun processCLib(args: Array<String>, additionalArgs: Map<String, Any> =
|
|||||||
{}
|
{}
|
||||||
}
|
}
|
||||||
|
|
||||||
val mode = parseGenerationMode(cinteropArguments.mode)
|
|
||||||
?: error ("Unexpected interop generation mode: ${cinteropArguments.mode}")
|
|
||||||
|
|
||||||
val stubIrContext = StubIrContext(logger, configuration, nativeIndex, imports, flavor, libName)
|
val stubIrContext = StubIrContext(logger, configuration, nativeIndex, imports, flavor, libName)
|
||||||
val stubIrOutput = run {
|
val stubIrOutput = run {
|
||||||
val outKtFileCreator = {
|
val outKtFileCreator = {
|
||||||
@@ -320,7 +327,8 @@ private fun processCLib(args: Array<String>, additionalArgs: Map<String, Any> =
|
|||||||
target = tool.target,
|
target = tool.target,
|
||||||
moduleName = moduleName,
|
moduleName = moduleName,
|
||||||
outputPath = cinteropArguments.output,
|
outputPath = cinteropArguments.output,
|
||||||
manifest = def.manifestAddendProperties
|
manifest = def.manifestAddendProperties,
|
||||||
|
dependencies = allLibraryDependencies
|
||||||
)
|
)
|
||||||
createInteropLibrary(args)
|
createInteropLibrary(args)
|
||||||
return null
|
return null
|
||||||
@@ -328,6 +336,27 @@ private fun processCLib(args: Array<String>, additionalArgs: Map<String, Any> =
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun resolveDependencies(
|
||||||
|
cinteropArguments: CInteropArguments, target: KonanTarget
|
||||||
|
): List<KotlinLibrary> {
|
||||||
|
val libraries = cinteropArguments.library
|
||||||
|
val repos = cinteropArguments.repo
|
||||||
|
val noDefaultLibs = cinteropArguments.nodefaultlibs || cinteropArguments.nodefaultlibsDeprecated
|
||||||
|
val noEndorsedLibs = cinteropArguments.noendorsedlibs
|
||||||
|
val resolver = defaultResolver(
|
||||||
|
repos,
|
||||||
|
libraries.filter { it.contains(org.jetbrains.kotlin.konan.file.File.separator) },
|
||||||
|
target,
|
||||||
|
Distribution()
|
||||||
|
).libraryResolver()
|
||||||
|
return resolver.resolveWithDependencies(
|
||||||
|
libraries.toUnresolvedLibraries,
|
||||||
|
noStdLib = false,
|
||||||
|
noDefaultLibs = noDefaultLibs,
|
||||||
|
noEndorsedLibs = noEndorsedLibs
|
||||||
|
).getFullList()
|
||||||
|
}
|
||||||
|
|
||||||
internal fun prepareTool(target: String?, flavor: KotlinPlatform): ToolConfig {
|
internal fun prepareTool(target: String?, flavor: KotlinPlatform): ToolConfig {
|
||||||
val tool = ToolConfig(target, flavor)
|
val tool = ToolConfig(target, flavor)
|
||||||
tool.downloadDependencies()
|
tool.downloadDependencies()
|
||||||
|
|||||||
@@ -5,14 +5,7 @@
|
|||||||
package org.jetbrains.kotlin.cli.utilities
|
package org.jetbrains.kotlin.cli.utilities
|
||||||
|
|
||||||
import org.jetbrains.kotlin.konan.file.File
|
import org.jetbrains.kotlin.konan.file.File
|
||||||
import org.jetbrains.kotlin.konan.library.KonanLibrary
|
|
||||||
import org.jetbrains.kotlin.konan.library.defaultResolver
|
|
||||||
import org.jetbrains.kotlin.konan.library.includedHeaders
|
|
||||||
import org.jetbrains.kotlin.konan.library.packageFqName
|
|
||||||
import org.jetbrains.kotlin.konan.target.Distribution
|
|
||||||
import org.jetbrains.kotlin.konan.target.PlatformManager
|
import org.jetbrains.kotlin.konan.target.PlatformManager
|
||||||
import org.jetbrains.kotlin.library.resolver.impl.libraryResolver
|
|
||||||
import org.jetbrains.kotlin.library.toUnresolvedLibraries
|
|
||||||
import org.jetbrains.kotlin.native.interop.gen.jvm.interop
|
import org.jetbrains.kotlin.native.interop.gen.jvm.interop
|
||||||
import org.jetbrains.kotlin.native.interop.tool.*
|
import org.jetbrains.kotlin.native.interop.tool.*
|
||||||
|
|
||||||
@@ -41,8 +34,6 @@ fun invokeInterop(flavor: String, args: Array<String>): Array<String>? {
|
|||||||
"-natives", nativesDir.path,
|
"-natives", nativesDir.path,
|
||||||
"-flavor", flavor
|
"-flavor", flavor
|
||||||
)
|
)
|
||||||
val additionalProperties = mutableMapOf<String, Any>(
|
|
||||||
"manifest" to manifest.path)
|
|
||||||
val cstubsName ="cstubs"
|
val cstubsName ="cstubs"
|
||||||
val libraries = arguments.library
|
val libraries = arguments.library
|
||||||
val repos = arguments.repo
|
val repos = arguments.repo
|
||||||
@@ -50,31 +41,12 @@ fun invokeInterop(flavor: String, args: Array<String>): Array<String>? {
|
|||||||
else (arguments as JSInteropArguments).target
|
else (arguments as JSInteropArguments).target
|
||||||
val target = PlatformManager().targetManager(targetRequest).target
|
val target = PlatformManager().targetManager(targetRequest).target
|
||||||
|
|
||||||
if (flavor == "native") {
|
val cinteropArgsToCompiler = interop(flavor, args + additionalArgs,
|
||||||
val resolver = defaultResolver(
|
listOfNotNull(
|
||||||
repos,
|
"manifest" to manifest.path,
|
||||||
libraries.filter { it.contains(File.separator) },
|
("cstubsName" to cstubsName).takeIf { flavor == "native" }
|
||||||
target,
|
).toMap()
|
||||||
Distribution()
|
) ?: return null // There is no need in compiler invocation if we're generating only metadata.
|
||||||
).libraryResolver()
|
|
||||||
val allLibraries = resolver.resolveWithDependencies(
|
|
||||||
libraries.toUnresolvedLibraries, noStdLib = true, noDefaultLibs = noDefaultLibs,
|
|
||||||
noEndorsedLibs = noEndorsedLibs
|
|
||||||
).getFullList() as List<KonanLibrary>
|
|
||||||
|
|
||||||
val imports = allLibraries.map { library ->
|
|
||||||
// TODO: handle missing properties?
|
|
||||||
library.packageFqName?.let { packageFqName ->
|
|
||||||
val headerIds = library.includedHeaders
|
|
||||||
"$packageFqName:${headerIds.joinToString(";")}"
|
|
||||||
}
|
|
||||||
}.filterNotNull()
|
|
||||||
additionalProperties.putAll(mapOf("cstubsname" to cstubsName, "import" to imports))
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
val cinteropArgsToCompiler = interop(flavor, args + additionalArgs, additionalProperties)
|
|
||||||
?: return null // There is no need in compiler invocation if we're generating only metadata.
|
|
||||||
|
|
||||||
val nativeStubs =
|
val nativeStubs =
|
||||||
if (flavor == "wasm")
|
if (flavor == "wasm")
|
||||||
@@ -82,7 +54,7 @@ fun invokeInterop(flavor: String, args: Array<String>): Array<String>? {
|
|||||||
else
|
else
|
||||||
arrayOf("-native-library", File(nativesDir, "$cstubsName.bc").path)
|
arrayOf("-native-library", File(nativesDir, "$cstubsName.bc").path)
|
||||||
|
|
||||||
val konancArgs = arrayOf(
|
return arrayOf(
|
||||||
generatedDir.path,
|
generatedDir.path,
|
||||||
"-produce", "library",
|
"-produce", "library",
|
||||||
"-o", outputFileName,
|
"-o", outputFileName,
|
||||||
@@ -96,8 +68,6 @@ fun invokeInterop(flavor: String, args: Array<String>): Array<String>? {
|
|||||||
(if (noDefaultLibs) arrayOf("-$NODEFAULTLIBS") else emptyArray()) +
|
(if (noDefaultLibs) arrayOf("-$NODEFAULTLIBS") else emptyArray()) +
|
||||||
(if (noEndorsedLibs) arrayOf("-$NOENDORSEDLIBS") else emptyArray()) +
|
(if (noEndorsedLibs) arrayOf("-$NOENDORSEDLIBS") else emptyArray()) +
|
||||||
(if (purgeUserLibs) arrayOf("-$PURGE_USER_LIBS") else emptyArray())
|
(if (purgeUserLibs) arrayOf("-$PURGE_USER_LIBS") else emptyArray())
|
||||||
|
|
||||||
return konancArgs
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user