[K/N][gradle] Supported friend modules for two stage compilation
Fixes https://youtrack.jetbrains.com/issue/KT-49248
This commit is contained in:
+15
-12
@@ -5,6 +5,7 @@ import org.jetbrains.kotlin.backend.common.serialization.metadata.KlibMetadataMo
|
|||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||||
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
||||||
|
import org.jetbrains.kotlin.konan.file.File
|
||||||
import org.jetbrains.kotlin.library.KotlinLibrary
|
import org.jetbrains.kotlin.library.KotlinLibrary
|
||||||
import org.jetbrains.kotlin.storage.StorageManager
|
import org.jetbrains.kotlin.storage.StorageManager
|
||||||
|
|
||||||
@@ -29,23 +30,25 @@ interface KlibResolvedModuleDescriptorsFactory {
|
|||||||
storageManager: StorageManager,
|
storageManager: StorageManager,
|
||||||
builtIns: KotlinBuiltIns?,
|
builtIns: KotlinBuiltIns?,
|
||||||
languageVersionSettings: LanguageVersionSettings,
|
languageVersionSettings: LanguageVersionSettings,
|
||||||
customAction: ((KotlinLibrary, ModuleDescriptorImpl) -> Unit)? = null,
|
friendModuleFiles: Set<File>,
|
||||||
|
includedLibraryFiles: Set<File>,
|
||||||
additionalDependencyModules: Iterable<ModuleDescriptorImpl>
|
additionalDependencyModules: Iterable<ModuleDescriptorImpl>
|
||||||
): KotlinResolvedModuleDescriptors
|
): KotlinResolvedModuleDescriptors
|
||||||
}
|
}
|
||||||
|
|
||||||
class KotlinResolvedModuleDescriptors(
|
class KotlinResolvedModuleDescriptors(
|
||||||
|
/**
|
||||||
|
* The list of modules each representing an individual Kotlin/Native library. All modules
|
||||||
|
* in this list have properly installed dependencies, i.e. module has all necessary dependencies
|
||||||
|
* on other modules plus a dependency on the [forwardDeclarationsModule].
|
||||||
|
*/
|
||||||
|
val resolvedDescriptors: List<ModuleDescriptorImpl>,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The list of modules each representing an individual Kotlin/Native library. All modules
|
* This is a module which "contains" forward declarations.
|
||||||
* in this list have properly installed dependencies, i.e. module has all necessary dependencies
|
* Note: this module should be unique per compilation and should always be the last dependency of any module.
|
||||||
* on other modules plus a dependency on the [forwardDeclarationsModule].
|
*/
|
||||||
*/
|
val forwardDeclarationsModule: ModuleDescriptorImpl,
|
||||||
val resolvedDescriptors: List<ModuleDescriptorImpl>,
|
|
||||||
|
|
||||||
/**
|
val friendModules: Set<ModuleDescriptorImpl>
|
||||||
* This is a module which "contains" forward declarations.
|
|
||||||
* Note: this module should be unique per compilation and should always be the last dependency of any module.
|
|
||||||
*/
|
|
||||||
val forwardDeclarationsModule: ModuleDescriptorImpl
|
|
||||||
)
|
)
|
||||||
|
|||||||
+17
-5
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.descriptors.konan.KlibModuleOrigin
|
|||||||
import org.jetbrains.kotlin.descriptors.konan.SyntheticModulesOrigin
|
import org.jetbrains.kotlin.descriptors.konan.SyntheticModulesOrigin
|
||||||
import org.jetbrains.kotlin.incremental.components.LookupLocation
|
import org.jetbrains.kotlin.incremental.components.LookupLocation
|
||||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||||
|
import org.jetbrains.kotlin.konan.file.File
|
||||||
import org.jetbrains.kotlin.util.profile
|
import org.jetbrains.kotlin.util.profile
|
||||||
import org.jetbrains.kotlin.library.KotlinLibrary
|
import org.jetbrains.kotlin.library.KotlinLibrary
|
||||||
import org.jetbrains.kotlin.library.metadata.PackageAccessHandler
|
import org.jetbrains.kotlin.library.metadata.PackageAccessHandler
|
||||||
@@ -37,14 +38,19 @@ class KlibResolvedModuleDescriptorsFactoryImpl(
|
|||||||
storageManager: StorageManager,
|
storageManager: StorageManager,
|
||||||
builtIns: KotlinBuiltIns?,
|
builtIns: KotlinBuiltIns?,
|
||||||
languageVersionSettings: LanguageVersionSettings,
|
languageVersionSettings: LanguageVersionSettings,
|
||||||
customAction: ((KotlinLibrary, ModuleDescriptorImpl) -> Unit)?,
|
friendModuleFiles: Set<File>,
|
||||||
|
includedLibraryFiles: Set<File>,
|
||||||
additionalDependencyModules: Iterable<ModuleDescriptorImpl>
|
additionalDependencyModules: Iterable<ModuleDescriptorImpl>
|
||||||
): KotlinResolvedModuleDescriptors {
|
): KotlinResolvedModuleDescriptors {
|
||||||
|
|
||||||
val moduleDescriptors = mutableListOf<ModuleDescriptorImpl>()
|
val moduleDescriptors = mutableListOf<ModuleDescriptorImpl>()
|
||||||
|
|
||||||
@Suppress("NAME_SHADOWING")
|
@Suppress("NAME_SHADOWING")
|
||||||
var builtIns = builtIns
|
var builtIns = builtIns
|
||||||
|
|
||||||
|
val friendModuleDescriptors = mutableSetOf<ModuleDescriptorImpl>()
|
||||||
|
val includedLibraryDescriptors = mutableSetOf<ModuleDescriptorImpl>()
|
||||||
|
|
||||||
// Build module descriptors.
|
// Build module descriptors.
|
||||||
resolvedLibraries.forEach { library, packageAccessHandler ->
|
resolvedLibraries.forEach { library, packageAccessHandler ->
|
||||||
profile("Loading ${library.libraryName}") {
|
profile("Loading ${library.libraryName}") {
|
||||||
@@ -56,7 +62,10 @@ class KlibResolvedModuleDescriptorsFactoryImpl(
|
|||||||
builtIns = moduleDescriptor.builtIns
|
builtIns = moduleDescriptor.builtIns
|
||||||
moduleDescriptors.add(moduleDescriptor)
|
moduleDescriptors.add(moduleDescriptor)
|
||||||
|
|
||||||
customAction?.invoke(library, moduleDescriptor)
|
if (friendModuleFiles.contains(library.libraryFile))
|
||||||
|
friendModuleDescriptors.add(moduleDescriptor)
|
||||||
|
if (includedLibraryFiles.contains(library.libraryFile))
|
||||||
|
includedLibraryDescriptors.add(moduleDescriptor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,14 +73,17 @@ class KlibResolvedModuleDescriptorsFactoryImpl(
|
|||||||
|
|
||||||
// Set inter-dependencies between module descriptors, add forwarding declarations module.
|
// Set inter-dependencies between module descriptors, add forwarding declarations module.
|
||||||
for (module in moduleDescriptors) {
|
for (module in moduleDescriptors) {
|
||||||
// Yes, just to all of them.
|
val friends = additionalDependencyModules.toMutableSet()
|
||||||
|
if (module in includedLibraryDescriptors)
|
||||||
|
friends.addAll(friendModuleDescriptors)
|
||||||
module.setDependencies(
|
module.setDependencies(
|
||||||
|
// Yes, just to all of them.
|
||||||
moduleDescriptors + additionalDependencyModules + forwardDeclarationsModule,
|
moduleDescriptors + additionalDependencyModules + forwardDeclarationsModule,
|
||||||
additionalDependencyModules.toSet()
|
friends
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return KotlinResolvedModuleDescriptors(moduleDescriptors, forwardDeclarationsModule)
|
return KotlinResolvedModuleDescriptors(moduleDescriptors, forwardDeclarationsModule, friendModuleDescriptors)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun createForwardDeclarationsModule(
|
fun createForwardDeclarationsModule(
|
||||||
|
|||||||
+10
-2
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.ir.linkage.IrDeserializer
|
|||||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||||
import org.jetbrains.kotlin.ir.util.*
|
import org.jetbrains.kotlin.ir.util.*
|
||||||
import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
||||||
|
import org.jetbrains.kotlin.library.uniqueName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi2ir.Psi2IrConfiguration
|
import org.jetbrains.kotlin.psi2ir.Psi2IrConfiguration
|
||||||
import org.jetbrains.kotlin.psi2ir.Psi2IrTranslator
|
import org.jetbrains.kotlin.psi2ir.Psi2IrTranslator
|
||||||
@@ -94,7 +95,14 @@ internal fun Context.psiToIr(
|
|||||||
get() = generatorContext.irBuiltIns
|
get() = generatorContext.irBuiltIns
|
||||||
}
|
}
|
||||||
|
|
||||||
val friendModules = emptyMap<String, Collection<String>>() // TODO: provide friend modules
|
val friendModules = config.resolvedLibraries.getFullList()
|
||||||
|
.filter { it.libraryFile in config.friendModuleFiles }
|
||||||
|
.map { it.uniqueName }
|
||||||
|
|
||||||
|
val friendModulesMap = (
|
||||||
|
listOf(moduleDescriptor.name.asStringStripSpecialMarkers()) +
|
||||||
|
config.resolve.includedLibraries.map { it.uniqueName }
|
||||||
|
).associateWith { friendModules }
|
||||||
|
|
||||||
KonanIrLinker(
|
KonanIrLinker(
|
||||||
moduleDescriptor,
|
moduleDescriptor,
|
||||||
@@ -102,7 +110,7 @@ internal fun Context.psiToIr(
|
|||||||
messageLogger,
|
messageLogger,
|
||||||
generatorContext.irBuiltIns,
|
generatorContext.irBuiltIns,
|
||||||
symbolTable,
|
symbolTable,
|
||||||
friendModules,
|
friendModulesMap,
|
||||||
forwardDeclarationsModuleDescriptor,
|
forwardDeclarationsModuleDescriptor,
|
||||||
stubGenerator,
|
stubGenerator,
|
||||||
irProviderForCEnumsAndCStructs,
|
irProviderForCEnumsAndCStructs,
|
||||||
|
|||||||
+9
-51
@@ -6,60 +6,49 @@
|
|||||||
package org.jetbrains.kotlin.backend.konan
|
package org.jetbrains.kotlin.backend.konan
|
||||||
|
|
||||||
import org.jetbrains.kotlin.analyzer.AnalysisResult
|
import org.jetbrains.kotlin.analyzer.AnalysisResult
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
|
||||||
import org.jetbrains.kotlin.builtins.functions.functionInterfacePackageFragmentProvider
|
import org.jetbrains.kotlin.builtins.functions.functionInterfacePackageFragmentProvider
|
||||||
import org.jetbrains.kotlin.builtins.konan.KonanBuiltIns
|
import org.jetbrains.kotlin.builtins.konan.KonanBuiltIns
|
||||||
import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
||||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
|
||||||
import org.jetbrains.kotlin.container.get
|
import org.jetbrains.kotlin.container.get
|
||||||
import org.jetbrains.kotlin.context.ModuleContext
|
import org.jetbrains.kotlin.context.ModuleContext
|
||||||
import org.jetbrains.kotlin.context.MutableModuleContextImpl
|
import org.jetbrains.kotlin.context.MutableModuleContextImpl
|
||||||
import org.jetbrains.kotlin.context.ProjectContext
|
import org.jetbrains.kotlin.context.ProjectContext
|
||||||
import org.jetbrains.kotlin.descriptors.PackageFragmentProvider
|
import org.jetbrains.kotlin.descriptors.PackageFragmentProvider
|
||||||
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
|
||||||
import org.jetbrains.kotlin.descriptors.konan.CurrentKlibModuleOrigin
|
import org.jetbrains.kotlin.descriptors.konan.CurrentKlibModuleOrigin
|
||||||
import org.jetbrains.kotlin.descriptors.konan.isNativeStdlib
|
import org.jetbrains.kotlin.descriptors.konan.isNativeStdlib
|
||||||
import org.jetbrains.kotlin.konan.file.File
|
|
||||||
import org.jetbrains.kotlin.konan.util.KlibMetadataFactories
|
import org.jetbrains.kotlin.konan.util.KlibMetadataFactories
|
||||||
import org.jetbrains.kotlin.library.KotlinLibrary
|
|
||||||
import org.jetbrains.kotlin.library.metadata.NativeTypeTransformer
|
import org.jetbrains.kotlin.library.metadata.NativeTypeTransformer
|
||||||
import org.jetbrains.kotlin.library.metadata.NullFlexibleTypeDeserializer
|
import org.jetbrains.kotlin.library.metadata.NullFlexibleTypeDeserializer
|
||||||
import org.jetbrains.kotlin.library.resolver.KotlinLibraryResolveResult
|
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import org.jetbrains.kotlin.resolve.*
|
import org.jetbrains.kotlin.resolve.*
|
||||||
import org.jetbrains.kotlin.resolve.extensions.AnalysisHandlerExtension
|
import org.jetbrains.kotlin.resolve.extensions.AnalysisHandlerExtension
|
||||||
import org.jetbrains.kotlin.resolve.lazy.declarations.FileBasedDeclarationProviderFactory
|
import org.jetbrains.kotlin.resolve.lazy.declarations.FileBasedDeclarationProviderFactory
|
||||||
import org.jetbrains.kotlin.serialization.konan.KotlinResolvedModuleDescriptors
|
|
||||||
import org.jetbrains.kotlin.storage.StorageManager
|
|
||||||
|
|
||||||
internal object TopDownAnalyzerFacadeForKonan {
|
internal object TopDownAnalyzerFacadeForKonan {
|
||||||
|
|
||||||
|
private val nativeFactories = KlibMetadataFactories(::KonanBuiltIns, NullFlexibleTypeDeserializer, NativeTypeTransformer())
|
||||||
|
|
||||||
fun analyzeFiles(files: Collection<KtFile>, context: Context): AnalysisResult {
|
fun analyzeFiles(files: Collection<KtFile>, context: Context): AnalysisResult {
|
||||||
val config = context.config
|
val config = context.config
|
||||||
val moduleName = Name.special("<${config.moduleId}>")
|
val moduleName = Name.special("<${config.moduleId}>")
|
||||||
|
|
||||||
val projectContext = ProjectContext(config.project, "TopDownAnalyzer for Konan")
|
val projectContext = ProjectContext(config.project, "TopDownAnalyzer for Konan")
|
||||||
|
|
||||||
val module = NativeFactories.DefaultDescriptorFactory.createDescriptorAndNewBuiltIns(
|
val module = nativeFactories.DefaultDescriptorFactory.createDescriptorAndNewBuiltIns(
|
||||||
moduleName, projectContext.storageManager, origin = CurrentKlibModuleOrigin)
|
moduleName, projectContext.storageManager, origin = CurrentKlibModuleOrigin)
|
||||||
val moduleContext = MutableModuleContextImpl(module, projectContext)
|
val moduleContext = MutableModuleContextImpl(module, projectContext)
|
||||||
|
|
||||||
val resolvedDependencies = ResolvedDependencies(
|
val resolvedModuleDescriptors = nativeFactories.DefaultResolvedDescriptorsFactory.createResolved(
|
||||||
config.resolvedLibraries,
|
config.resolvedLibraries, projectContext.storageManager, module.builtIns, config.languageVersionSettings,
|
||||||
projectContext.storageManager,
|
config.friendModuleFiles, config.resolve.includedLibraries.map { it.libraryFile }.toSet(), listOf(module))
|
||||||
module.builtIns,
|
|
||||||
config.languageVersionSettings,
|
|
||||||
config.friendModuleFiles,
|
|
||||||
module
|
|
||||||
)
|
|
||||||
|
|
||||||
val additionalPackages = mutableListOf<PackageFragmentProvider>()
|
val additionalPackages = mutableListOf<PackageFragmentProvider>()
|
||||||
if (!module.isNativeStdlib()) {
|
if (!module.isNativeStdlib()) {
|
||||||
val dependencies = listOf(module) + resolvedDependencies.moduleDescriptors.resolvedDescriptors + resolvedDependencies.moduleDescriptors.forwardDeclarationsModule
|
val dependencies = listOf(module) + resolvedModuleDescriptors.resolvedDescriptors + resolvedModuleDescriptors.forwardDeclarationsModule
|
||||||
module.setDependencies(dependencies, resolvedDependencies.friends)
|
module.setDependencies(dependencies, resolvedModuleDescriptors.friendModules)
|
||||||
} else {
|
} else {
|
||||||
assert (resolvedDependencies.moduleDescriptors.resolvedDescriptors.isEmpty())
|
assert(resolvedModuleDescriptors.resolvedDescriptors.isEmpty())
|
||||||
moduleContext.setDependencies(module)
|
moduleContext.setDependencies(module)
|
||||||
// [K][Suspend]FunctionN belong to stdlib.
|
// [K][Suspend]FunctionN belong to stdlib.
|
||||||
additionalPackages += functionInterfacePackageFragmentProvider(projectContext.storageManager, module)
|
additionalPackages += functionInterfacePackageFragmentProvider(projectContext.storageManager, module)
|
||||||
@@ -122,34 +111,3 @@ internal object TopDownAnalyzerFacadeForKonan {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class ResolvedDependencies(
|
|
||||||
resolvedLibraries: KotlinLibraryResolveResult,
|
|
||||||
storageManager: StorageManager,
|
|
||||||
builtIns: KotlinBuiltIns,
|
|
||||||
specifics: LanguageVersionSettings,
|
|
||||||
friendModuleFiles: Set<File>,
|
|
||||||
currentModuleDescriptor: ModuleDescriptorImpl
|
|
||||||
) {
|
|
||||||
|
|
||||||
val moduleDescriptors: KotlinResolvedModuleDescriptors
|
|
||||||
val friends: Set<ModuleDescriptorImpl>
|
|
||||||
|
|
||||||
init {
|
|
||||||
|
|
||||||
val collectedFriends = mutableListOf<ModuleDescriptorImpl>()
|
|
||||||
|
|
||||||
val customAction: (KotlinLibrary, ModuleDescriptorImpl) -> Unit = { library, moduleDescriptor ->
|
|
||||||
if (friendModuleFiles.contains(library.libraryFile)) {
|
|
||||||
collectedFriends.add(moduleDescriptor)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.moduleDescriptors = NativeFactories.DefaultResolvedDescriptorsFactory.createResolved(
|
|
||||||
resolvedLibraries, storageManager, builtIns, specifics, customAction, listOf(currentModuleDescriptor))
|
|
||||||
|
|
||||||
this.friends = collectedFriends.toSet()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val NativeFactories = KlibMetadataFactories(::KonanBuiltIns, NullFlexibleTypeDeserializer, NativeTypeTransformer())
|
|
||||||
|
|||||||
+6
@@ -77,6 +77,7 @@ internal fun buildKotlinNativeBinaryLinkerArgs(
|
|||||||
target: KonanTarget,
|
target: KonanTarget,
|
||||||
outputKind: CompilerOutputKind,
|
outputKind: CompilerOutputKind,
|
||||||
libraries: List<File>,
|
libraries: List<File>,
|
||||||
|
friendModule: FileCollection,
|
||||||
|
|
||||||
languageSettings: LanguageSettings,
|
languageSettings: LanguageSettings,
|
||||||
enableEndorsedLibs: Boolean,
|
enableEndorsedLibs: Boolean,
|
||||||
@@ -111,6 +112,11 @@ internal fun buildKotlinNativeBinaryLinkerArgs(
|
|||||||
|
|
||||||
exportLibraries.forEach { add("-Xexport-library=${it.absolutePath}") }
|
exportLibraries.forEach { add("-Xexport-library=${it.absolutePath}") }
|
||||||
includeLibraries.forEach { add("-Xinclude=${it.absolutePath}") }
|
includeLibraries.forEach { add("-Xinclude=${it.absolutePath}") }
|
||||||
|
|
||||||
|
val friends = friendModule.files
|
||||||
|
if (friends.isNotEmpty()) {
|
||||||
|
addArg("-friend-modules", friends.joinToString(File.pathSeparator) { it.absolutePath })
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun buildKotlinNativeMainArgs(
|
private fun buildKotlinNativeMainArgs(
|
||||||
|
|||||||
+6
-4
@@ -168,6 +168,11 @@ abstract class AbstractKotlinNativeCompile<T : KotlinCommonToolOptions, K : Kotl
|
|||||||
else objects.fileCollection()
|
else objects.fileCollection()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@get:Classpath
|
||||||
|
protected val friendModule: FileCollection by project.provider {
|
||||||
|
project.files(compilation.friendPaths)
|
||||||
|
}
|
||||||
|
|
||||||
@Deprecated("For native tasks use 'libraries' instead", ReplaceWith("libraries"))
|
@Deprecated("For native tasks use 'libraries' instead", ReplaceWith("libraries"))
|
||||||
override fun getClasspath(): FileCollection = libraries
|
override fun getClasspath(): FileCollection = libraries
|
||||||
override fun setClasspath(configuration: FileCollection?) {
|
override fun setClasspath(configuration: FileCollection?) {
|
||||||
@@ -354,10 +359,6 @@ constructor(
|
|||||||
private val commonSourcesTree: FileTree
|
private val commonSourcesTree: FileTree
|
||||||
get() = commonSources.asFileTree
|
get() = commonSources.asFileTree
|
||||||
|
|
||||||
|
|
||||||
private val friendModule: FileCollection by project.provider {
|
|
||||||
project.files(compilation.friendPaths)
|
|
||||||
}
|
|
||||||
// endregion.
|
// endregion.
|
||||||
|
|
||||||
// region Language settings imported from a SourceSet.
|
// region Language settings imported from a SourceSet.
|
||||||
@@ -634,6 +635,7 @@ constructor(
|
|||||||
konanTarget,
|
konanTarget,
|
||||||
outputKind,
|
outputKind,
|
||||||
libraries.files.filterKlibsPassedToCompiler(),
|
libraries.files.filterKlibsPassedToCompiler(),
|
||||||
|
friendModule,
|
||||||
languageSettings,
|
languageSettings,
|
||||||
enableEndorsedLibs,
|
enableEndorsedLibs,
|
||||||
localKotlinOptions,
|
localKotlinOptions,
|
||||||
|
|||||||
Reference in New Issue
Block a user