Add build reports for diagnosing build problems in Gradle

#KT-12700 Fixed

To turn build reports, add 'kotlin.build.report.enable=true' to
gradle.properties file
(or pass it in CLI via`-Pkotlin.build.report.enable=true`).
By default build reports are created in
`rootProject/build/reports/kotlin-build`.
Build report dir can be customized via `kotlin.build.report.dir`
property.
This commit is contained in:
Alexey Tsvetkov
2019-01-28 15:35:26 +03:00
parent 8fc8b95d83
commit 98ef00b957
15 changed files with 375 additions and 27 deletions
@@ -26,5 +26,6 @@ interface CompilationResults : Remote {
}
enum class CompilationResultCategory(val code: Int) {
IC_COMPILE_ITERATION(0)
IC_COMPILE_ITERATION(0),
IC_LOG(1)
}
@@ -511,13 +511,18 @@ class CompileServiceImpl(
val workingDir = incrementalCompilationOptions.workingDir
val modulesApiHistory = ModulesApiHistoryJs(incrementalCompilationOptions.modulesInfo)
val compiler = IncrementalJsCompilerRunner(
workingDir = workingDir,
reporter = reporter,
buildHistoryFile = incrementalCompilationOptions.multiModuleICSettings.buildHistoryFile,
modulesApiHistory = modulesApiHistory
)
return compiler.compile(allKotlinFiles, args, compilerMessageCollector, changedFiles)
return try {
compiler.compile(allKotlinFiles, args, compilerMessageCollector, changedFiles)
} finally {
reporter.flush()
}
}
private fun execIncrementalCompiler(
@@ -570,6 +575,8 @@ class CompileServiceImpl(
val workingDir = incrementalCompilationOptions.workingDir
val modulesApiHistory = incrementalCompilationOptions.run {
reporter.report { "Use module detection: ${multiModuleICSettings.useModuleDetection}" }
if (!multiModuleICSettings.useModuleDetection) {
ModulesApiHistoryJvm(modulesInfo)
} else {
@@ -587,7 +594,11 @@ class CompileServiceImpl(
modulesApiHistory = modulesApiHistory,
kotlinSourceFilesExtensions = allKotlinExtensions
)
return compiler.compile(allKotlinFiles, k2jvmArgs, compilerMessageCollector, changedFiles)
return try {
compiler.compile(allKotlinFiles, k2jvmArgs, compilerMessageCollector, changedFiles)
} finally {
reporter.flush()
}
}
override fun leaseReplSession(
@@ -22,26 +22,54 @@ import org.jetbrains.kotlin.incremental.ICReporter
import java.io.File
internal class RemoteICReporter(
private val servicesFacade: CompilerServicesFacadeBase,
private val compilationResults: CompilationResults,
compilationOptions: CompilationOptions
private val servicesFacade: CompilerServicesFacadeBase,
private val compilationResults: CompilationResults,
compilationOptions: IncrementalCompilationOptions
) : ICReporter {
private val rootDir = compilationOptions.modulesInfo.projectRoot
private val shouldReportMessages = ReportCategory.IC_MESSAGE.code in compilationOptions.reportCategories
private val isVerbose = compilationOptions.reportSeverity == ReportSeverity.DEBUG.code
private val shouldReportCompileIteration = CompilationResultCategory.IC_COMPILE_ITERATION.code in compilationOptions.requestedCompilationResults
private val shouldReportCompileIteration =
CompilationResultCategory.IC_COMPILE_ITERATION.code in compilationOptions.requestedCompilationResults
private val shouldReportICLog = CompilationResultCategory.IC_LOG.code in compilationOptions.requestedCompilationResults
private val icLogLines = arrayListOf<String>()
override fun report(message: () -> String) {
val lazyMessage = lazy { message() }
if (shouldReportMessages && isVerbose) {
servicesFacade.report(ReportCategory.IC_MESSAGE, ReportSeverity.DEBUG, message())
servicesFacade.report(ReportCategory.IC_MESSAGE, ReportSeverity.DEBUG, lazyMessage.value)
}
if (shouldReportICLog) {
icLogLines.add(lazyMessage.value)
}
}
override fun reportCompileIteration(sourceFiles: Collection<File>, exitCode: ExitCode) {
if (shouldReportCompileIteration) {
compilationResults.add(CompilationResultCategory.IC_COMPILE_ITERATION.code,
CompileIterationResult(sourceFiles, exitCode.toString())
compilationResults.add(
CompilationResultCategory.IC_COMPILE_ITERATION.code,
CompileIterationResult(sourceFiles, exitCode.toString())
)
}
if (shouldReportICLog) {
icLogLines.add("compile iteration:")
sourceFiles.relativePaths(rootDir).forEach {
icLogLines.add(" $it")
}
}
}
fun flush() {
if (shouldReportICLog) {
compilationResults.add(CompilationResultCategory.IC_LOG.code, icLogLines)
}
}
private fun File.relativeOrCanonical(base: File): String =
relativeToOrNull(base)?.path ?: canonicalPath
private fun Iterable<File>.relativePaths(base: File): List<String> =
map { it.relativeOrCanonical(base) }.sorted()
}
@@ -21,18 +21,27 @@ internal class GradleCompilationResults(
LoopbackNetworkInterface.clientLoopbackSocketFactory,
LoopbackNetworkInterface.serverLoopbackSocketFactory
) {
var icLogLines: List<String>? = null
@Throws(RemoteException::class)
override fun add(compilationResultCategory: Int, value: Serializable) {
if (compilationResultCategory == CompilationResultCategory.IC_COMPILE_ITERATION.code) {
@Suppress("UNCHECKED_CAST")
val compileIterationResult = value as? CompileIterationResult
if (compileIterationResult != null) {
val sourceFiles = compileIterationResult.sourceFiles
if (sourceFiles.any()) {
log.kotlinDebug { "compile iteration: ${sourceFiles.pathsAsStringRelativeTo(projectRootFile)}" }
when (compilationResultCategory) {
CompilationResultCategory.IC_COMPILE_ITERATION.code -> {
@Suppress("UNCHECKED_CAST")
val compileIterationResult = value as? CompileIterationResult
if (compileIterationResult != null) {
val sourceFiles = compileIterationResult.sourceFiles
if (sourceFiles.any()) {
log.kotlinDebug { "compile iteration: ${sourceFiles.pathsAsStringRelativeTo(projectRootFile)}" }
}
val exitCode = compileIterationResult.exitCode
log.kotlinDebug { "compiler exit code: $exitCode" }
}
val exitCode = compileIterationResult.exitCode
log.kotlinDebug { "compiler exit code: $exitCode" }
}
CompilationResultCategory.IC_LOG.code -> {
@Suppress("UNCHECKED_CAST")
icLogLines = value as? List<String>
}
}
}
@@ -16,6 +16,7 @@ internal class GradleCompilerEnvironment(
messageCollector: GradlePrintingMessageCollector,
outputItemsCollector: OutputItemsCollector,
val outputFiles: FileCollection,
val reportExecutionResult: Boolean,
val incrementalCompilationEnvironment: IncrementalCompilationEnvironment? = null
) : CompilerEnvironment(Services.EMPTY, messageCollector, outputItemsCollector) {
val toolsJar: File? by lazy { findToolsJar() }
@@ -141,7 +141,8 @@ internal open class GradleCompilerRunner(protected val task: Task) {
incrementalModuleInfo = modulesInfo,
buildFile = buildFile,
outputFiles = environment.outputFiles.toList(),
taskPath = task.path
taskPath = task.path,
reportExecutionResult = environment.reportExecutionResult
)
TaskLoggers.put(task.path, task.logger)
runCompilerAsync(workArgs)
@@ -11,7 +11,9 @@ import org.jetbrains.kotlin.cli.common.messages.MessageCollector
import org.jetbrains.kotlin.config.Services
import org.jetbrains.kotlin.daemon.common.*
import org.jetbrains.kotlin.gradle.logging.*
import org.jetbrains.kotlin.gradle.plugin.internal.state.TaskExecutionResults
import org.jetbrains.kotlin.gradle.plugin.internal.state.TaskLoggers
import org.jetbrains.kotlin.gradle.report.TaskExecutionResult
import org.jetbrains.kotlin.gradle.tasks.throwGradleExceptionIfError
import org.jetbrains.kotlin.gradle.utils.stackTraceAsString
import org.jetbrains.kotlin.incremental.ChangedFiles
@@ -20,6 +22,7 @@ import org.slf4j.LoggerFactory
import java.io.*
import java.net.URLClassLoader
import java.rmi.RemoteException
import java.util.*
import java.util.concurrent.Callable
import java.util.concurrent.Executors
import javax.inject.Inject
@@ -50,7 +53,8 @@ internal class GradleKotlinCompilerWorkArguments(
val incrementalModuleInfo: IncrementalModuleInfo?,
val buildFile: File?,
val outputFiles: List<File>,
val taskPath: String
val taskPath: String,
val reportExecutionResult: Boolean
) : Serializable {
companion object {
const val serialVersionUID: Long = 0
@@ -88,6 +92,7 @@ internal class GradleKotlinCompilerWork @Inject constructor(
private val buildFile = config.buildFile
private val outputFiles = config.outputFiles
private val taskPath = config.taskPath
private val reportExecutionResult = config.reportExecutionResult
private val log: KotlinLogger =
TaskLoggers.get(taskPath)?.let { GradleKotlinLogger(it).apply { debug("Using '$taskPath' logger") } }
@@ -226,7 +231,16 @@ internal class GradleKotlinCompilerWork @Inject constructor(
requestedCompilationResults = emptyArray()
)
val servicesFacade = GradleCompilerServicesFacadeImpl(log, bufferingMessageCollector)
return daemon.compile(sessionId, compilerArgs, compilationOptions, servicesFacade, compilationResults = null)
return try {
daemon.compile(sessionId, compilerArgs, compilationOptions, servicesFacade, compilationResults = null)
} finally {
reportExecutionResultIfNeeded {
TaskExecutionResult(
executionStrategy = DAEMON_EXECUTION_STRATEGY,
icLogLines = nonIcBuildLog("incremental compilation is not enabled for '$taskPath'")
)
}
}
}
private fun incrementalCompilationWithDaemon(
@@ -238,6 +252,11 @@ internal class GradleKotlinCompilerWork @Inject constructor(
val icEnv = incrementalCompilationEnvironment ?: error("incrementalCompilationEnvironment is null!")
val knownChangedFiles = icEnv.changedFiles as? ChangedFiles.Known
val requestedCompilationResults = EnumSet.of(CompilationResultCategory.IC_COMPILE_ITERATION)
if (reportExecutionResult) {
requestedCompilationResults.add(CompilationResultCategory.IC_LOG)
}
val compilationOptions = IncrementalCompilationOptions(
areFileChangesKnown = knownChangedFiles != null,
modifiedFiles = knownChangedFiles?.modified,
@@ -245,7 +264,7 @@ internal class GradleKotlinCompilerWork @Inject constructor(
workingDir = icEnv.workingDir,
reportCategories = reportCategories(isVerbose),
reportSeverity = reportSeverity(isVerbose),
requestedCompilationResults = arrayOf(CompilationResultCategory.IC_COMPILE_ITERATION.code),
requestedCompilationResults = requestedCompilationResults.map { it.code }.toTypedArray(),
compilerMode = CompilerMode.INCREMENTAL_COMPILER,
targetPlatform = targetPlatform,
usePreciseJavaTracking = icEnv.usePreciseJavaTracking,
@@ -257,11 +276,29 @@ internal class GradleKotlinCompilerWork @Inject constructor(
log.info("Options for KOTLIN DAEMON: $compilationOptions")
val servicesFacade = GradleIncrementalCompilerServicesFacadeImpl(log, bufferingMessageCollector)
val compilationResults = GradleCompilationResults(log, projectRootFile)
return daemon.compile(sessionId, compilerArgs, compilationOptions, servicesFacade, compilationResults)
val result = daemon.compile(sessionId, compilerArgs, compilationOptions, servicesFacade, compilationResults)
reportExecutionResultIfNeeded {
TaskExecutionResult(
executionStrategy = DAEMON_EXECUTION_STRATEGY,
icLogLines = compilationResults.icLogLines
)
}
return result
}
private fun compileOutOfProcess(): ExitCode =
runToolInSeparateProcess(compilerArgs, compilerClassName, compilerFullClasspath, log)
try {
runToolInSeparateProcess(compilerArgs, compilerClassName, compilerFullClasspath, log)
} finally {
reportExecutionResultIfNeeded {
TaskExecutionResult(
executionStrategy = OUT_OF_PROCESS_EXECUTION_STRATEGY,
icLogLines = nonIcBuildLog("$OUT_OF_PROCESS_EXECUTION_STRATEGY execution strategy does not support incremental compilation")
)
}
}
private fun compileInProcess(messageCollector: MessageCollector): ExitCode {
// in-process compiler should always be run in a different thread
@@ -276,6 +313,13 @@ internal class GradleKotlinCompilerWork @Inject constructor(
} finally {
bufferingMessageCollector.flush(messageCollector)
threadPool.shutdown()
reportExecutionResultIfNeeded {
TaskExecutionResult(
executionStrategy = IN_PROCESS_EXECUTION_STRATEGY,
icLogLines = nonIcBuildLog("$IN_PROCESS_EXECUTION_STRATEGY execution strategy does not support incremental compilation")
)
}
}
}
@@ -320,4 +364,14 @@ internal class GradleKotlinCompilerWork @Inject constructor(
} else {
ReportSeverity.DEBUG.code
}
private inline fun reportExecutionResultIfNeeded(fn: () -> TaskExecutionResult) {
if (reportExecutionResult) {
val result = fn()
TaskExecutionResults[taskPath] = result
}
}
private fun nonIcBuildLog(reason: String): List<String> =
listOf("Performing non-incremental build: $reason")
}
@@ -64,6 +64,7 @@ open class KaptWithKotlincTask : KaptTask(), CompilerArgumentAwareWithInput<K2JV
val outputItemCollector = OutputItemsCollectorImpl()
val environment = GradleCompilerEnvironment(
compilerClasspath, messageCollector, outputItemCollector,
reportExecutionResult = kotlinCompileTask.reportExecutionResult,
outputFiles = allOutputFiles()
)
if (environment.toolsJar == null && !isAtLeastJava9) {
@@ -19,16 +19,26 @@ package org.jetbrains.kotlin.gradle.plugin
import org.gradle.BuildAdapter
import org.gradle.BuildResult
import org.gradle.api.invocation.Gradle
import org.gradle.api.logging.Logger
import org.gradle.api.logging.Logging
import org.jetbrains.kotlin.compilerRunner.DELETED_SESSION_FILE_PREFIX
import org.jetbrains.kotlin.compilerRunner.GradleCompilerRunner
import org.jetbrains.kotlin.gradle.plugin.internal.state.TaskLoggers
import org.jetbrains.kotlin.gradle.logging.kotlinDebug
import org.jetbrains.kotlin.gradle.plugin.internal.state.TaskExecutionResults
import org.jetbrains.kotlin.gradle.report.KotlinBuildReporter
import org.jetbrains.kotlin.gradle.report.configureBuildReporter
import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile
import org.jetbrains.kotlin.gradle.utils.relativeToRoot
import org.jetbrains.kotlin.utils.addToStdlib.sumByLong
import java.io.File
import java.lang.management.ManagementFactory
import java.text.SimpleDateFormat
import java.util.*
internal class KotlinGradleBuildServices private constructor(gradle: Gradle) : BuildAdapter() {
internal class KotlinGradleBuildServices private constructor(
private val gradle: Gradle
) : BuildAdapter() {
companion object {
private val CLASS_NAME = KotlinGradleBuildServices::class.java.simpleName
const val FORCE_SYSTEM_GC_MESSAGE = "Forcing System.gc()"
@@ -68,10 +78,17 @@ internal class KotlinGradleBuildServices private constructor(gradle: Gradle) : B
// but it is called before any plugin can attach build listener
fun buildStarted() {
startMemory = getUsedMemoryKb()
TaskLoggers.clear()
TaskExecutionResults.clear()
configureBuildReporter(gradle, log)
}
override fun buildFinished(result: BuildResult) {
TaskLoggers.clear()
TaskExecutionResults.clear()
val gradle = result.gradle!!
GradleCompilerRunner.clearBuildModulesInfo()
@@ -100,7 +117,6 @@ internal class KotlinGradleBuildServices private constructor(gradle: Gradle) : B
log.lifecycle("[KOTLIN][PERF] Used memory after build: $endMem kb (difference since build start: ${"%+d".format(endMem - startMem)} kb)")
}
TaskLoggers.clear()
gradle.removeListener(this)
instance = null
log.kotlinDebug(DISPOSE_MESSAGE)
@@ -122,3 +138,4 @@ internal class KotlinGradleBuildServices private constructor(gradle: Gradle) : B
private fun getGcCount(): Long =
ManagementFactory.getGarbageCollectorMXBeans().sumByLong { Math.max(0, it.collectionCount) }
}
@@ -18,9 +18,11 @@ package org.jetbrains.kotlin.gradle.plugin
import org.gradle.api.Project
import org.jetbrains.kotlin.gradle.dsl.Coroutines
import org.jetbrains.kotlin.gradle.report.BuildReportMode
import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile
import org.jetbrains.kotlin.gradle.tasks.Kotlin2JsCompile
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import java.io.File
import java.util.*
internal fun PropertiesProvider.mapKotlinTaskProperties(task: AbstractKotlinCompile<*>) {
@@ -54,6 +56,12 @@ internal class PropertiesProvider(private val project: Project) {
val coroutines: Coroutines?
get() = property("kotlin.coroutines")?.let { Coroutines.byCompilerArgument(it) }
val buildReportEnabled: Boolean
get() = booleanProperty("kotlin.build.report.enable") ?: false
val buildReportDir: File?
get() = property("kotlin.build.report.dir")?.let { File(it) }
val incrementalJvm: Boolean?
get() = booleanProperty("kotlin.incremental")
@@ -0,0 +1,24 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.gradle.plugin.internal.state
import org.jetbrains.kotlin.gradle.report.TaskExecutionResult
import java.util.concurrent.ConcurrentHashMap
internal object TaskExecutionResults {
private val results = ConcurrentHashMap<String, TaskExecutionResult>()
operator fun get(taskPath: String): TaskExecutionResult? =
results[taskPath]
operator fun set(taskPath: String, result: TaskExecutionResult) {
results[taskPath] = result
}
fun clear() {
results.clear()
}
}
@@ -0,0 +1,176 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.gradle.report
import org.gradle.BuildAdapter
import org.gradle.BuildResult
import org.gradle.api.Task
import org.gradle.api.execution.TaskExecutionListener
import org.gradle.api.invocation.Gradle
import org.gradle.api.logging.Logger
import org.gradle.api.tasks.TaskState
import org.jetbrains.kotlin.gradle.logging.kotlinDebug
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider
import org.jetbrains.kotlin.gradle.plugin.internal.state.TaskExecutionResults
import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile
import java.io.File
import java.lang.StringBuilder
import java.text.SimpleDateFormat
import java.util.*
import kotlin.math.max
internal fun configureBuildReporter(gradle: Gradle, log: Logger) {
val rootProject = gradle.rootProject
val properties = PropertiesProvider(rootProject)
if (!properties.buildReportEnabled) return
val perfLogDir = properties.buildReportDir
?: rootProject.buildDir.resolve("reports/kotlin-build").apply { mkdirs() }
if (perfLogDir.isFile) {
log.error("Kotlin build report cannot be created: '$perfLogDir' is a file")
return
}
perfLogDir.mkdirs()
val ts = SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(Calendar.getInstance().time)
val perfReportFile = perfLogDir.resolve("${gradle.rootProject.name}-build-$ts.txt")
val reporter = KotlinBuildReporter(perfReportFile)
gradle.addBuildListener(reporter)
gradle.taskGraph.whenReady { graph ->
graph.allTasks.asSequence()
.filterIsInstance<AbstractKotlinCompile<*>>()
.forEach { it.reportExecutionResult = true }
}
log.kotlinDebug { "Configured Kotlin build reporter" }
}
internal class KotlinBuildReporter(private val perfReportFile: File) : BuildAdapter(), TaskExecutionListener {
init {
val dir = perfReportFile.parentFile
check(dir.isDirectory) { "$dir does not exist or is a file" }
check(!perfReportFile.isFile) { "Build report log file $perfReportFile exists already" }
}
private val taskStartNs = HashMap<Task, Long>()
private val kotlinTaskTimeNs = HashMap<Task, Long>()
private val tasksSb = StringBuilder()
@Volatile
private var allTasksTimeNs: Long = 0L
@Synchronized
override fun beforeExecute(task: Task) {
taskStartNs[task] = System.nanoTime()
}
@Synchronized
override fun afterExecute(task: Task, state: TaskState) {
val startNs = taskStartNs[task] ?: return
val endNs = System.nanoTime()
val timeNs = endNs - startNs
allTasksTimeNs += timeNs
if (!task.javaClass.name.startsWith("org.jetbrains.kotlin")) {
return
}
kotlinTaskTimeNs[task] = timeNs
tasksSb.appendln()
val skipMessage = state.skipMessage
if (skipMessage != null) {
tasksSb.appendln("$task was skipped: $skipMessage")
} else {
tasksSb.appendln("$task finished in ${formatTime(timeNs)}")
}
val path = task.path
val executionResult = TaskExecutionResults[path]
if (executionResult != null) {
tasksSb.appendln("Execution strategy: ${executionResult.executionStrategy}")
executionResult.icLogLines?.let { lines ->
tasksSb.appendln("Compilation log for $task:")
lines.forEach { tasksSb.appendln(" $it") }
}
}
}
@Synchronized
override fun buildFinished(result: BuildResult) {
val logger = result.gradle?.rootProject?.logger
try {
perfReportFile.writeText(taskOverview() + tasksSb.toString())
logger?.lifecycle("Kotlin build report is written to ${perfReportFile.canonicalPath}")
} catch (e: Throwable) {
logger?.error("Could not write Kotlin build report to ${perfReportFile.canonicalPath}", e)
}
}
private fun taskOverview(): String {
val sb = StringBuilder()
val kotlinTotalTimeNs = kotlinTaskTimeNs.values.sum()
val ktTaskPercent = (kotlinTotalTimeNs.toDouble() / allTasksTimeNs * 100).asString(1)
sb.appendln("Total time for Kotlin tasks: ${formatTime(kotlinTotalTimeNs)} ($ktTaskPercent % of all tasks time)")
val table = TextTable("Time", "% of Kotlin time", "Task")
kotlinTaskTimeNs.entries
.sortedByDescending { (_, timeNs) -> timeNs }
.forEach { (task, timeNs) ->
val percent = (timeNs.toDouble() / kotlinTotalTimeNs * 100).asString(1)
table.addRow(formatTime(timeNs), "$percent %", task.path)
}
table.printTo(sb)
sb.appendln()
return sb.toString()
}
private fun formatTime(ns: Long): String {
val seconds = ns.toDouble() / 1_000_000_000
return seconds.asString(2) + " s"
}
private fun Double.asString(decPoints: Int): String =
String.format("%.${decPoints}f", this)
private class TextTable(vararg columnNames: String) {
private val rows = ArrayList<List<String>>()
private val columnsCount = columnNames.size
private val maxLengths = IntArray(columnsCount) { columnNames[it].length }
init {
rows.add(columnNames.toList())
}
fun addRow(vararg row: String) {
check(row.size == columnsCount) { "Row size ${row.size} differs from columns count $columnsCount" }
rows.add(row.toList())
for ((i, col) in row.withIndex()) {
maxLengths[i] = max(maxLengths[i], col.length)
}
}
fun printTo(sb: StringBuilder) {
for (row in rows) {
sb.appendln()
for ((i, col) in row.withIndex()) {
if (i > 0) sb.append("|")
sb.append(col.padEnd(maxLengths[i], ' '))
}
}
}
}
}
@@ -0,0 +1,11 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.gradle.report
internal class TaskExecutionResult(
val executionStrategy: String,
val icLogLines: List<String>?
)
@@ -71,6 +71,7 @@ open class KotlinCompileCommon : AbstractKotlinCompile<K2MetadataCompilerArgumen
val compilerRunner = compilerRunner()
val environment = GradleCompilerEnvironment(
computedCompilerClasspath, messageCollector, outputItemCollector,
reportExecutionResult = reportExecutionResult,
outputFiles = allOutputFiles()
)
compilerRunner.runMetadataCompilerAsync(sourceRoots.kotlinSourceFiles, args, environment)
@@ -132,6 +132,9 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments>() : AbstractKo
logger.kotlinDebug { "Set $this.incremental=$value" }
}
@get:Internal
var reportExecutionResult: Boolean = false
@get:Internal
internal val buildHistoryFile: File
get() = File(taskBuildDirectory, "build-history.bin")
@@ -436,6 +439,7 @@ open class KotlinCompile : AbstractKotlinCompile<K2JVMCompilerArguments>(), Kotl
val environment = GradleCompilerEnvironment(
computedCompilerClasspath, messageCollector, outputItemCollector,
outputFiles = allOutputFiles(),
reportExecutionResult = reportExecutionResult,
incrementalCompilationEnvironment = icEnv
)
compilerRunner.runJvmCompilerAsync(
@@ -593,6 +597,7 @@ open class Kotlin2JsCompile : AbstractKotlinCompile<K2JSCompilerArguments>(), Ko
val environment = GradleCompilerEnvironment(
computedCompilerClasspath, messageCollector, outputItemCollector,
outputFiles = allOutputFiles(),
reportExecutionResult = reportExecutionResult,
incrementalCompilationEnvironment = icEnv
)
compilerRunner.runJsCompilerAsync(sourceRoots.kotlinSourceFiles, commonSourceSet.toList(), args, environment)