[K/N][build] Added -Xmake-per-file-cache compiler option

This commit is contained in:
Igor Chevdar
2022-04-11 15:15:34 +05:00
committed by Space
parent 7e79b2b500
commit 030e3b306f
5 changed files with 112 additions and 25 deletions
@@ -28,7 +28,6 @@ import org.jetbrains.kotlin.konan.CURRENT
import org.jetbrains.kotlin.konan.CompilerVersion
import org.jetbrains.kotlin.konan.file.File
import org.jetbrains.kotlin.konan.target.CompilerOutputKind
import org.jetbrains.kotlin.library.uniqueName
import org.jetbrains.kotlin.metadata.deserialization.BinaryVersion
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.util.profile
@@ -90,13 +89,7 @@ class K2Native : CLICompiler<K2NativeCompilerArguments>() {
configuration.put(CLIConfigurationKeys.RENDER_DIAGNOSTIC_INTERNAL_NAME, arguments.renderInternalDiagnosticNames)
try {
val konanConfig = KonanConfig(project, configuration)
try {
ensureModuleName(konanConfig, environment)
runTopLevelPhases(konanConfig, environment)
} finally {
konanConfig.dispose()
}
KonanDriver(project, environment, configuration).run()
} catch (e: Throwable) {
if (e is KonanCompilationException || e is CompilationErrorException)
return ExitCode.COMPILATION_ERROR
@@ -123,18 +116,6 @@ class K2Native : CLICompiler<K2NativeCompilerArguments>() {
return this?.asList<String>() ?: listOf<String>()
}
private fun ensureModuleName(config: KonanConfig, environment: KotlinCoreEnvironment) {
if (environment.getSourceFiles().isEmpty()) {
val libraries = config.resolvedLibraries.getFullList()
val moduleName = config.moduleId
if (libraries.any { it.uniqueName == moduleName }) {
val kexeModuleName = "${moduleName}_kexe"
config.configuration.put(KonanConfigKeys.MODULE_NAME, kexeModuleName)
assert(libraries.none { it.uniqueName == kexeModuleName })
}
}
}
// It is executed before doExecute().
override fun setupPlatformSpecificArgumentsAndServices(
configuration: CompilerConfiguration,
@@ -308,6 +289,7 @@ class K2Native : CLICompiler<K2NativeCompilerArguments>() {
if (outputKind == CompilerOutputKind.PRELIMINARY_CACHE && fileToCache == null)
configuration.report(ERROR, "preliminary_cache only supported for per-file caches")
fileToCache?.let { put(FILE_TO_CACHE, it) }
put(MAKE_PER_FILE_CACHE, arguments.makePerFileCache)
parseShortModuleName(arguments, configuration, outputKind)?.let {
put(SHORT_MODULE_NAME, it)
@@ -46,6 +46,8 @@ class KonanConfigKeys {
= CompilerConfigurationKey.create<Map<String, String>>("mapping from library paths to cache paths")
val FILE_TO_CACHE: CompilerConfigurationKey<String?>
= CompilerConfigurationKey.create<String?>("which file should be compiled to cache")
val MAKE_PER_FILE_CACHE: CompilerConfigurationKey<Boolean>
= CompilerConfigurationKey.create<Boolean>("make per-file cache")
val FRAMEWORK_IMPORT_HEADERS: CompilerConfigurationKey<List<String>>
= CompilerConfigurationKey.create<List<String>>("headers imported to framework header")
val FRIEND_MODULES: CompilerConfigurationKey<List<String>>
@@ -5,19 +5,81 @@
package org.jetbrains.kotlin.backend.konan
import com.intellij.openapi.project.Project
import kotlinx.cinterop.usingJvmCInteropCallbacks
import org.jetbrains.kotlin.analyzer.AnalysisResult
import org.jetbrains.kotlin.backend.common.phaser.CompilerPhase
import org.jetbrains.kotlin.backend.common.phaser.invokeToplevel
import org.jetbrains.kotlin.backend.common.serialization.codedInputStream
import org.jetbrains.kotlin.backend.common.serialization.proto.IrFile
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
import org.jetbrains.kotlin.config.CommonConfigurationKeys
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.config.languageVersionSettings
import org.jetbrains.kotlin.konan.file.File
import org.jetbrains.kotlin.konan.library.impl.createKonanLibrary
import org.jetbrains.kotlin.konan.target.CompilerOutputKind
import org.jetbrains.kotlin.konan.util.usingNativeMemoryAllocator
import org.jetbrains.kotlin.library.uniqueName
import org.jetbrains.kotlin.protobuf.ExtensionRegistryLite
import org.jetbrains.kotlin.utils.addToStdlib.cast
fun runTopLevelPhases(konanConfig: KonanConfig, environment: KotlinCoreEnvironment) {
class KonanDriver(val project: Project, val environment: KotlinCoreEnvironment, val configuration: CompilerConfiguration) {
fun run() {
val fileNames = configuration.get(KonanConfigKeys.LIBRARY_TO_ADD_TO_CACHE)?.let { libPath ->
if (configuration.get(KonanConfigKeys.MAKE_PER_FILE_CACHE) != true)
null
else {
val lib = createKonanLibrary(File(libPath), "default", null, true)
(0 until lib.fileCount()).map { fileIndex ->
val proto = IrFile.parseFrom(lib.file(fileIndex).codedInputStream, ExtensionRegistryLite.newInstance())
proto.fileEntry.name
}
}
}
if (fileNames == null) {
KonanConfig(project, configuration).runTopLevelPhases()
} else {
fileNames.forEach { buildFileCache(it, CompilerOutputKind.PRELIMINARY_CACHE) }
fileNames.forEach { buildFileCache(it, configuration.get(KonanConfigKeys.PRODUCE)!!) }
}
}
private fun buildFileCache(fileName: String, cacheKind: CompilerOutputKind) {
val phaseConfig = configuration.get(CLIConfigurationKeys.PHASE_CONFIG)!!
val subConfiguration = configuration.copy()
subConfiguration.put(KonanConfigKeys.PRODUCE, cacheKind)
subConfiguration.put(KonanConfigKeys.FILE_TO_CACHE, fileName)
subConfiguration.put(KonanConfigKeys.MAKE_PER_FILE_CACHE, false)
subConfiguration.put(CLIConfigurationKeys.PHASE_CONFIG, phaseConfig.toBuilder().build())
KonanConfig(project, subConfiguration).runTopLevelPhases()
}
private fun KonanConfig.runTopLevelPhases() {
try {
ensureModuleName(this)
runTopLevelPhases(this, environment)
} finally {
dispose()
}
}
private fun ensureModuleName(config: KonanConfig) {
if (environment.getSourceFiles().isEmpty()) {
val libraries = config.resolvedLibraries.getFullList()
val moduleName = config.moduleId
if (libraries.any { it.uniqueName == moduleName }) {
val kexeModuleName = "${moduleName}_kexe"
config.configuration.put(KonanConfigKeys.MODULE_NAME, kexeModuleName)
assert(libraries.none { it.uniqueName == kexeModuleName })
}
}
}
}
private fun runTopLevelPhases(konanConfig: KonanConfig, environment: KotlinCoreEnvironment) {
val config = konanConfig.configuration