Compile multiplatform projects with daemon

This commit is contained in:
Alexey Tsvetkov
2016-12-18 11:21:36 +03:00
parent d303bdaa0e
commit 69e8cf6a25
7 changed files with 34 additions and 25 deletions
@@ -47,6 +47,7 @@ interface KotlinLogger {
abstract class KotlinCompilerRunner<in Env : CompilerEnvironment> {
protected val K2JVM_COMPILER = "org.jetbrains.kotlin.cli.jvm.K2JVMCompiler"
protected val K2JS_COMPILER = "org.jetbrains.kotlin.cli.js.K2JSCompiler"
protected val K2METADATA_COMPILER = "org.jetbrains.kotlin.cli.metadata.K2MetadataCompiler"
protected val INTERNAL_ERROR = ExitCode.INTERNAL_ERROR.toString()
protected abstract val log: KotlinLogger
@@ -148,6 +149,7 @@ abstract class KotlinCompilerRunner<in Env : CompilerEnvironment> {
val targetPlatform = when (compilerClassName) {
K2JVM_COMPILER -> CompileService.TargetPlatform.JVM
K2JS_COMPILER -> CompileService.TargetPlatform.JS
K2METADATA_COMPILER -> CompileService.TargetPlatform.METADATA
else -> throw IllegalArgumentException("Unknown compiler type $compilerClassName")
}
@@ -31,7 +31,8 @@ interface CompileService : Remote {
enum class TargetPlatform : Serializable {
JVM,
JS
JS,
METADATA
}
companion object {
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.daemon
import org.jetbrains.kotlin.cli.common.CLICompiler
import org.jetbrains.kotlin.cli.js.K2JSCompiler
import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler
import org.jetbrains.kotlin.cli.metadata.K2MetadataCompiler
import org.jetbrains.kotlin.daemon.common.*
import java.io.File
import java.io.IOException
@@ -125,9 +126,11 @@ object KotlinCompileDaemon {
val compilerSelector = object : CompilerSelector {
private val jvm by lazy { K2JVMCompiler() }
private val js by lazy { K2JSCompiler() }
private val metadata by lazy { K2MetadataCompiler() }
override fun get(targetPlatform: CompileService.TargetPlatform): CLICompiler<*> = when (targetPlatform) {
CompileService.TargetPlatform.JVM -> jvm
CompileService.TargetPlatform.JS -> js
CompileService.TargetPlatform.METADATA -> metadata
}
}
// timer with a daemon thread, meaning it should not prevent JVM to exit normally
@@ -22,22 +22,18 @@ import org.gradle.api.Project
import org.jetbrains.kotlin.cli.common.ExitCode
import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
import org.jetbrains.kotlin.cli.common.arguments.K2MetadataCompilerArguments
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
import org.jetbrains.kotlin.config.Services
import org.jetbrains.kotlin.daemon.client.RemoteOutputStreamServer
import org.jetbrains.kotlin.daemon.common.IncrementalCompilationServicesFacade
import org.jetbrains.kotlin.daemon.common.LoopbackNetworkInterface
import org.jetbrains.kotlin.daemon.common.SOCKET_ANY_FREE_PORT
import org.jetbrains.kotlin.gradle.plugin.ParentLastURLClassLoader
import org.jetbrains.kotlin.gradle.plugin.kotlinDebug
import org.jetbrains.kotlin.incremental.ChangedFiles
import org.jetbrains.kotlin.incremental.classpathAsList
import org.jetbrains.kotlin.incremental.destinationAsFile
import org.jetbrains.kotlin.incremental.makeModuleFile
import java.io.*
import java.rmi.server.UnicastRemoteObject
import kotlin.concurrent.thread
internal const val KOTLIN_COMPILER_EXECUTION_STRATEGY_PROPERTY = "kotlin.compiler.execution.strategy"
@@ -101,6 +97,15 @@ internal class GradleCompilerRunner(private val project: Project) : KotlinCompil
return runCompiler(K2JS_COMPILER, args, additionalArguments, environment)
}
fun runMetadataCompiler(
kotlinSources: List<File>,
args: K2MetadataCompilerArguments,
environment: GradleCompilerEnvironment
): ExitCode {
val additionalArguments = kotlinSources.joinToString(separator = " ") { it.absolutePath }
return runCompiler(K2METADATA_COMPILER, args, additionalArguments, environment)
}
override fun doRunCompiler(compilerClassName: String, argsArray: Array<String>, environment: GradleCompilerEnvironment): ExitCode {
with (project.logger) {
kotlinDebug { "Kotlin compiler class: $compilerClassName" }
@@ -16,22 +16,25 @@
package org.jetbrains.kotlin.gradle.tasks
import org.gradle.api.Project
import org.gradle.api.tasks.compile.AbstractCompile
import org.jetbrains.kotlin.cli.common.arguments.K2MetadataCompilerArguments
import org.jetbrains.kotlin.cli.metadata.K2MetadataCompiler
import org.jetbrains.kotlin.config.Services
import org.jetbrains.kotlin.compilerRunner.GradleCompilerEnvironment
import org.jetbrains.kotlin.compilerRunner.GradleCompilerRunner
import org.jetbrains.kotlin.compilerRunner.OutputItemsCollectorImpl
import org.jetbrains.kotlin.incremental.ChangedFiles
import java.io.File
internal open class KotlinCompileCommon : AbstractKotlinCompile<K2MetadataCompilerArguments>() {
override val compiler = K2MetadataCompiler()
override fun populateCompilerArguments(): K2MetadataCompilerArguments =
K2MetadataCompilerArguments()
override fun getSourceRoots(): SourceRoots =
SourceRoots.KotlinOnly.create(getSource())
override fun findKotlinCompilerJar(project: Project): File? =
findKotlinMetadataCompilerJar(project)
override fun callCompiler(args: K2MetadataCompilerArguments, sourceRoots: SourceRoots, changedFiles: ChangedFiles) {
val classpathList = classpath.files.toMutableList()
val friendTask = friendTaskName?.let { project.tasks.findByName(it) } as? AbstractCompile
@@ -43,8 +46,11 @@ internal open class KotlinCompileCommon : AbstractKotlinCompile<K2MetadataCompil
freeArgs = sourceRoots.kotlinSourceFiles.map { it.canonicalPath }
}
val messageCollector = GradleMessageCollector(project.logger)
val exitCode = compiler.exec(messageCollector, Services.EMPTY, args)
val messageCollector = GradleMessageCollector(logger)
val outputItemCollector = OutputItemsCollectorImpl()
val compilerRunner = GradleCompilerRunner(project)
val environment = GradleCompilerEnvironment(compilerJar, messageCollector, outputItemCollector)
val exitCode = compilerRunner.runMetadataCompiler(sourceRoots.kotlinSourceFiles, args, environment)
throwGradleExceptionIfError(exitCode)
}
}
@@ -58,7 +58,6 @@ const val KOTLIN_BUILD_DIR_NAME = "kotlin"
const val USING_EXPERIMENTAL_INCREMENTAL_MESSAGE = "Using experimental kotlin incremental compilation"
abstract class AbstractKotlinCompile<T : CommonCompilerArguments>() : AbstractCompile() {
abstract protected val compiler: CLICompiler<T>
abstract protected fun populateCompilerArguments(): T
// indicates that task should compile kotlin incrementally if possible
@@ -130,8 +129,6 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments>() : AbstractCo
}
open class KotlinCompile : AbstractKotlinCompile<K2JVMCompilerArguments>(), KotlinJvmCompile {
override val compiler = K2JVMCompiler()
internal var parentKotlinOptionsImpl: KotlinJvmOptionsImpl? = null
private val kotlinOptionsImpl = KotlinJvmOptionsImpl()
override val kotlinOptions: KotlinJvmOptions
@@ -317,7 +314,6 @@ internal fun compileJvmNotIncrementally(
}
open class Kotlin2JsCompile() : AbstractKotlinCompile<K2JSCompilerArguments>(), KotlinJsCompile {
override val compiler = K2JSCompiler()
private val kotlinOptionsImpl = KotlinJsOptionsImpl()
override val kotlinOptions: KotlinJsOptions
get() = kotlinOptionsImpl
@@ -378,15 +374,7 @@ open class Kotlin2JsCompile() : AbstractKotlinCompile<K2JSCompilerArguments>(),
val compilerRunner = GradleCompilerRunner(project)
val environment = GradleCompilerEnvironment(compilerJar, messageCollector, outputItemCollector)
val exitCode = compilerRunner.runJsCompiler(sourceRoots.kotlinSourceFiles, args, environment)
when (exitCode) {
ExitCode.OK -> {
logger.kotlinInfo("Compilation succeeded")
}
ExitCode.COMPILATION_ERROR -> throw GradleException("Compilation error. See log for more details")
ExitCode.INTERNAL_ERROR -> throw GradleException("Internal compiler error. See log for more details")
else -> throw GradleException("Unexpected exit code: $exitCode")
}
throwGradleExceptionIfError(exitCode)
}
}
@@ -22,6 +22,7 @@ import java.util.zip.ZipFile
private val K2JVM_COMPILER_CLASS = "org.jetbrains.kotlin.cli.jvm.K2JVMCompiler"
private val K2JS_COMPILER_CLASS = "org.jetbrains.kotlin.cli.js.K2JSCompiler"
private val K2METADATA_COMPILER_CLASS = "org.jetbrains.kotlin.cli.metadata.K2MetadataCompiler"
internal fun findKotlinJvmCompilerJar(project: Project): File? =
findKotlinCompilerJar(project, K2JVM_COMPILER_CLASS)
@@ -29,6 +30,9 @@ internal fun findKotlinJvmCompilerJar(project: Project): File? =
internal fun findKotlinJsCompilerJar(project: Project): File? =
findKotlinCompilerJar(project, K2JS_COMPILER_CLASS)
internal fun findKotlinMetadataCompilerJar(project: Project): File? =
findKotlinCompilerJar(project, K2METADATA_COMPILER_CLASS)
private fun findKotlinCompilerJar(project: Project, compilerClassName: String): File? {
fun Project.classpathJars(): Sequence<File> =
buildscript.configurations.findByName("classpath")?.files?.asSequence() ?: emptySequence()