Restore tasks outputs to pre-execution state in worker.
Workers usually execute later than task action and does not raise exception to the task. Such behaviour skips task outputs restoration to the pre-execution state. Kotlin compiler on incremental compilation error leaves 'dirty*' files in the build output, forcing Gradle to run non-incrementally on the next build. Fixed it by moving task outputs reset logic into worker as well. ^KT-46406 In Progress
This commit is contained in:
+2
-1
@@ -5,9 +5,10 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.build.report.metrics
|
package org.jetbrains.kotlin.build.report.metrics
|
||||||
|
|
||||||
|
import java.io.Serializable
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class BuildMetricsReporterImpl : BuildMetricsReporter {
|
class BuildMetricsReporterImpl : BuildMetricsReporter, Serializable {
|
||||||
private val myBuildTimeStartNs: EnumMap<BuildTime, Long> =
|
private val myBuildTimeStartNs: EnumMap<BuildTime, Long> =
|
||||||
EnumMap(
|
EnumMap(
|
||||||
BuildTime::class.java
|
BuildTime::class.java
|
||||||
|
|||||||
+42
-7
@@ -5,13 +5,19 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.compilerRunner
|
package org.jetbrains.kotlin.compilerRunner
|
||||||
|
|
||||||
|
import org.gradle.api.GradleException
|
||||||
|
import org.gradle.api.file.ConfigurableFileCollection
|
||||||
|
import org.gradle.api.provider.MapProperty
|
||||||
import org.gradle.api.provider.Property
|
import org.gradle.api.provider.Property
|
||||||
import org.gradle.workers.WorkAction
|
import org.gradle.workers.WorkAction
|
||||||
import org.gradle.workers.WorkParameters
|
import org.gradle.workers.WorkParameters
|
||||||
import org.gradle.workers.WorkQueue
|
import org.gradle.workers.WorkQueue
|
||||||
import org.gradle.workers.WorkerExecutor
|
import org.gradle.workers.WorkerExecutor
|
||||||
import org.jetbrains.kotlin.gradle.logging.kotlinDebug
|
import org.jetbrains.kotlin.build.report.metrics.BuildMetricsReporter
|
||||||
|
import org.jetbrains.kotlin.build.report.metrics.BuildTime
|
||||||
|
import org.jetbrains.kotlin.build.report.metrics.measure
|
||||||
import org.jetbrains.kotlin.gradle.tasks.GradleCompileTaskProvider
|
import org.jetbrains.kotlin.gradle.tasks.GradleCompileTaskProvider
|
||||||
|
import org.jetbrains.kotlin.gradle.tasks.TaskOutputsBackup
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -21,28 +27,57 @@ internal class GradleCompilerRunnerWithWorkers(
|
|||||||
taskProvider: GradleCompileTaskProvider,
|
taskProvider: GradleCompileTaskProvider,
|
||||||
jdkToolsJar: File?,
|
jdkToolsJar: File?,
|
||||||
kotlinDaemonJvmArgs: List<String>?,
|
kotlinDaemonJvmArgs: List<String>?,
|
||||||
|
buildMetrics: BuildMetricsReporter,
|
||||||
private val workerExecutor: WorkerExecutor
|
private val workerExecutor: WorkerExecutor
|
||||||
) : GradleCompilerRunner(taskProvider, jdkToolsJar, kotlinDaemonJvmArgs) {
|
) : GradleCompilerRunner(taskProvider, jdkToolsJar, kotlinDaemonJvmArgs, buildMetrics) {
|
||||||
override fun runCompilerAsync(workArgs: GradleKotlinCompilerWorkArguments): WorkQueue {
|
override fun runCompilerAsync(
|
||||||
loggerProvider.kotlinDebug { "Starting Kotlin compiler work from task '${pathProvider}'" }
|
workArgs: GradleKotlinCompilerWorkArguments,
|
||||||
|
taskOutputsBackup: TaskOutputsBackup?
|
||||||
|
): WorkQueue {
|
||||||
|
|
||||||
val workQueue = workerExecutor.noIsolation()
|
val workQueue = workerExecutor.noIsolation()
|
||||||
workQueue.submit(GradleKotlinCompilerWorkAction::class.java) {
|
workQueue.submit(GradleKotlinCompilerWorkAction::class.java) {
|
||||||
it.compilerWorkArguments.set(workArgs)
|
it.compilerWorkArguments.set(workArgs)
|
||||||
|
if (taskOutputsBackup != null) {
|
||||||
|
it.taskOutputs.from(taskOutputsBackup.outputs)
|
||||||
|
it.taskOutputsSnapshot.set(taskOutputsBackup.previousOutputs)
|
||||||
|
it.metricsReporter.set(buildMetrics)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return workQueue
|
return workQueue
|
||||||
}
|
}
|
||||||
|
|
||||||
internal abstract class GradleKotlinCompilerWorkAction
|
internal abstract class GradleKotlinCompilerWorkAction
|
||||||
: WorkAction<GradleKotlinCompilerWorkParameters> {
|
: WorkAction<GradleKotlinCompilerWorkParameters> {
|
||||||
|
|
||||||
override fun execute() {
|
override fun execute() {
|
||||||
GradleKotlinCompilerWork(
|
try {
|
||||||
parameters.compilerWorkArguments.get()
|
GradleKotlinCompilerWork(
|
||||||
).run()
|
parameters.compilerWorkArguments.get()
|
||||||
|
).run()
|
||||||
|
} catch (e: GradleException) {
|
||||||
|
if (parameters.taskOutputsSnapshot.isPresent) {
|
||||||
|
val taskOutputsBackup = TaskOutputsBackup(
|
||||||
|
parameters.taskOutputs,
|
||||||
|
parameters.taskOutputsSnapshot.get()
|
||||||
|
)
|
||||||
|
// Currently, metrics are not reported as in the worker we are getting new instance of [BuildMetricsReporter]
|
||||||
|
// [BuildDataRecorder] knows nothing about this new instance. Possibly could be fixed in the future by migrating
|
||||||
|
// [BuildMetricsReporter] to be shared Gradle service.
|
||||||
|
parameters.metricsReporter.get().measure(BuildTime.RESTORE_OUTPUT_FROM_BACKUP) {
|
||||||
|
taskOutputsBackup.restoreOutputs()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw e
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal interface GradleKotlinCompilerWorkParameters : WorkParameters {
|
internal interface GradleKotlinCompilerWorkParameters : WorkParameters {
|
||||||
val compilerWorkArguments: Property<GradleKotlinCompilerWorkArguments>
|
val compilerWorkArguments: Property<GradleKotlinCompilerWorkArguments>
|
||||||
|
val taskOutputs: ConfigurableFileCollection
|
||||||
|
val taskOutputsSnapshot: MapProperty<File, Array<Byte>>
|
||||||
|
val metricsReporter: Property<BuildMetricsReporter>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+37
-13
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.compilerRunner
|
package org.jetbrains.kotlin.compilerRunner
|
||||||
|
|
||||||
|
import org.gradle.api.GradleException
|
||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
import org.gradle.api.invocation.Gradle
|
import org.gradle.api.invocation.Gradle
|
||||||
import org.gradle.api.logging.Logger
|
import org.gradle.api.logging.Logger
|
||||||
@@ -12,6 +13,9 @@ import org.gradle.api.plugins.JavaPluginConvention
|
|||||||
import org.gradle.api.tasks.bundling.AbstractArchiveTask
|
import org.gradle.api.tasks.bundling.AbstractArchiveTask
|
||||||
import org.gradle.jvm.tasks.Jar
|
import org.gradle.jvm.tasks.Jar
|
||||||
import org.gradle.workers.WorkQueue
|
import org.gradle.workers.WorkQueue
|
||||||
|
import org.jetbrains.kotlin.build.report.metrics.BuildMetricsReporter
|
||||||
|
import org.jetbrains.kotlin.build.report.metrics.BuildTime
|
||||||
|
import org.jetbrains.kotlin.build.report.metrics.measure
|
||||||
import org.jetbrains.kotlin.cli.common.arguments.*
|
import org.jetbrains.kotlin.cli.common.arguments.*
|
||||||
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
|
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
|
||||||
import org.jetbrains.kotlin.daemon.client.CompileServiceSession
|
import org.jetbrains.kotlin.daemon.client.CompileServiceSession
|
||||||
@@ -26,10 +30,9 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
|
|||||||
import org.jetbrains.kotlin.gradle.plugin.internal.state.TaskLoggers
|
import org.jetbrains.kotlin.gradle.plugin.internal.state.TaskLoggers
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinWithJavaTarget
|
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinWithJavaTarget
|
||||||
import org.jetbrains.kotlin.gradle.plugin.statistics.KotlinBuildStatsService
|
import org.jetbrains.kotlin.gradle.plugin.statistics.KotlinBuildStatsService
|
||||||
import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile
|
import org.jetbrains.kotlin.gradle.tasks.*
|
||||||
import org.jetbrains.kotlin.gradle.tasks.GradleCompileTaskProvider
|
|
||||||
import org.jetbrains.kotlin.gradle.tasks.InspectClassesForMultiModuleIC
|
import org.jetbrains.kotlin.gradle.tasks.InspectClassesForMultiModuleIC
|
||||||
import org.jetbrains.kotlin.gradle.tasks.Kotlin2JsCompile
|
import org.jetbrains.kotlin.gradle.tasks.TaskOutputsBackup
|
||||||
import org.jetbrains.kotlin.gradle.utils.archivePathCompatible
|
import org.jetbrains.kotlin.gradle.utils.archivePathCompatible
|
||||||
import org.jetbrains.kotlin.gradle.utils.newTmpFile
|
import org.jetbrains.kotlin.gradle.utils.newTmpFile
|
||||||
import org.jetbrains.kotlin.gradle.utils.relativeOrCanonical
|
import org.jetbrains.kotlin.gradle.utils.relativeOrCanonical
|
||||||
@@ -62,7 +65,8 @@ is not assignable to 'org.gradle.api.tasks.TaskProvider'" exception
|
|||||||
internal open class GradleCompilerRunner(
|
internal open class GradleCompilerRunner(
|
||||||
protected val taskProvider: GradleCompileTaskProvider,
|
protected val taskProvider: GradleCompileTaskProvider,
|
||||||
protected val jdkToolsJar: File?,
|
protected val jdkToolsJar: File?,
|
||||||
protected val kotlinDaemonJvmArgs: List<String>?
|
protected val kotlinDaemonJvmArgs: List<String>?,
|
||||||
|
protected val buildMetrics: BuildMetricsReporter
|
||||||
) {
|
) {
|
||||||
|
|
||||||
internal val pathProvider = taskProvider.path.get()
|
internal val pathProvider = taskProvider.path.get()
|
||||||
@@ -85,7 +89,8 @@ internal open class GradleCompilerRunner(
|
|||||||
javaPackagePrefix: String?,
|
javaPackagePrefix: String?,
|
||||||
args: K2JVMCompilerArguments,
|
args: K2JVMCompilerArguments,
|
||||||
environment: GradleCompilerEnvironment,
|
environment: GradleCompilerEnvironment,
|
||||||
jdkHome: File
|
jdkHome: File,
|
||||||
|
taskOutputsBackup: TaskOutputsBackup?
|
||||||
): WorkQueue? {
|
): WorkQueue? {
|
||||||
args.freeArgs += sourcesToCompile.map { it.absolutePath }
|
args.freeArgs += sourcesToCompile.map { it.absolutePath }
|
||||||
args.commonSources = commonSources.map { it.absolutePath }.toTypedArray()
|
args.commonSources = commonSources.map { it.absolutePath }.toTypedArray()
|
||||||
@@ -93,7 +98,7 @@ internal open class GradleCompilerRunner(
|
|||||||
args.javaPackagePrefix = javaPackagePrefix
|
args.javaPackagePrefix = javaPackagePrefix
|
||||||
if (args.jdkHome == null && !args.noJdk) args.jdkHome = jdkHome.absolutePath
|
if (args.jdkHome == null && !args.noJdk) args.jdkHome = jdkHome.absolutePath
|
||||||
loggerProvider.kotlinInfo("Kotlin compilation 'jdkHome' argument: ${args.jdkHome}")
|
loggerProvider.kotlinInfo("Kotlin compilation 'jdkHome' argument: ${args.jdkHome}")
|
||||||
return runCompilerAsync(KotlinCompilerClass.JVM, args, environment)
|
return runCompilerAsync(KotlinCompilerClass.JVM, args, environment, taskOutputsBackup)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -104,11 +109,12 @@ internal open class GradleCompilerRunner(
|
|||||||
kotlinSources: List<File>,
|
kotlinSources: List<File>,
|
||||||
kotlinCommonSources: List<File>,
|
kotlinCommonSources: List<File>,
|
||||||
args: K2JSCompilerArguments,
|
args: K2JSCompilerArguments,
|
||||||
environment: GradleCompilerEnvironment
|
environment: GradleCompilerEnvironment,
|
||||||
|
taskOutputsBackup: TaskOutputsBackup?
|
||||||
): WorkQueue? {
|
): WorkQueue? {
|
||||||
args.freeArgs += kotlinSources.map { it.absolutePath }
|
args.freeArgs += kotlinSources.map { it.absolutePath }
|
||||||
args.commonSources = kotlinCommonSources.map { it.absolutePath }.toTypedArray()
|
args.commonSources = kotlinCommonSources.map { it.absolutePath }.toTypedArray()
|
||||||
return runCompilerAsync(KotlinCompilerClass.JS, args, environment)
|
return runCompilerAsync(KotlinCompilerClass.JS, args, environment, taskOutputsBackup)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -127,7 +133,8 @@ internal open class GradleCompilerRunner(
|
|||||||
private fun runCompilerAsync(
|
private fun runCompilerAsync(
|
||||||
compilerClassName: String,
|
compilerClassName: String,
|
||||||
compilerArgs: CommonCompilerArguments,
|
compilerArgs: CommonCompilerArguments,
|
||||||
environment: GradleCompilerEnvironment
|
environment: GradleCompilerEnvironment,
|
||||||
|
taskOutputsBackup: TaskOutputsBackup? = null
|
||||||
): WorkQueue? {
|
): WorkQueue? {
|
||||||
if (compilerArgs.version) {
|
if (compilerArgs.version) {
|
||||||
loggerProvider.lifecycle(
|
loggerProvider.lifecycle(
|
||||||
@@ -192,12 +199,29 @@ internal open class GradleCompilerRunner(
|
|||||||
daemonJvmArgs = kotlinDaemonJvmArgs
|
daemonJvmArgs = kotlinDaemonJvmArgs
|
||||||
)
|
)
|
||||||
TaskLoggers.put(pathProvider, loggerProvider)
|
TaskLoggers.put(pathProvider, loggerProvider)
|
||||||
return runCompilerAsync(workArgs)
|
return runCompilerAsync(
|
||||||
|
workArgs,
|
||||||
|
taskOutputsBackup
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
protected open fun runCompilerAsync(workArgs: GradleKotlinCompilerWorkArguments): WorkQueue? {
|
protected open fun runCompilerAsync(
|
||||||
val kotlinCompilerRunnable = GradleKotlinCompilerWork(workArgs)
|
workArgs: GradleKotlinCompilerWorkArguments,
|
||||||
kotlinCompilerRunnable.run()
|
taskOutputsBackup: TaskOutputsBackup?
|
||||||
|
): WorkQueue? {
|
||||||
|
try {
|
||||||
|
val kotlinCompilerRunnable = GradleKotlinCompilerWork(workArgs)
|
||||||
|
kotlinCompilerRunnable.run()
|
||||||
|
} catch (e: GradleException) {
|
||||||
|
if (taskOutputsBackup != null) {
|
||||||
|
buildMetrics.measure(BuildTime.RESTORE_OUTPUT_FROM_BACKUP) {
|
||||||
|
taskOutputsBackup.restoreOutputs()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -176,8 +176,8 @@ abstract class KaptTask @Inject constructor(
|
|||||||
abstract val source: ConfigurableFileCollection
|
abstract val source: ConfigurableFileCollection
|
||||||
|
|
||||||
@get:Internal
|
@get:Internal
|
||||||
override val metrics: BuildMetricsReporter =
|
override val metrics: Property<BuildMetricsReporter> = objectFactory
|
||||||
BuildMetricsReporterImpl()
|
.property(BuildMetricsReporterImpl())
|
||||||
|
|
||||||
@get:Input
|
@get:Input
|
||||||
abstract val verbose: Property<Boolean>
|
abstract val verbose: Property<Boolean>
|
||||||
|
|||||||
+4
-3
@@ -11,7 +11,6 @@ import org.gradle.api.provider.ListProperty
|
|||||||
import org.gradle.api.provider.Property
|
import org.gradle.api.provider.Property
|
||||||
import org.gradle.api.provider.Provider
|
import org.gradle.api.provider.Provider
|
||||||
import org.gradle.api.tasks.*
|
import org.gradle.api.tasks.*
|
||||||
import org.gradle.api.tasks.incremental.IncrementalTaskInputs
|
|
||||||
import org.gradle.work.InputChanges
|
import org.gradle.work.InputChanges
|
||||||
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
|
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
|
||||||
import org.jetbrains.kotlin.compilerRunner.GradleCompilerEnvironment
|
import org.jetbrains.kotlin.compilerRunner.GradleCompilerEnvironment
|
||||||
@@ -122,7 +121,8 @@ abstract class KaptWithKotlincTask @Inject constructor(
|
|||||||
val compilerRunner = GradleCompilerRunner(
|
val compilerRunner = GradleCompilerRunner(
|
||||||
taskProvider.get(),
|
taskProvider.get(),
|
||||||
defaultKotlinJavaToolchain.get().currentJvmJdkToolsJar.orNull,
|
defaultKotlinJavaToolchain.get().currentJvmJdkToolsJar.orNull,
|
||||||
normalizedKotlinDaemonJvmArguments.orNull
|
normalizedKotlinDaemonJvmArguments.orNull,
|
||||||
|
metrics.get()
|
||||||
)
|
)
|
||||||
compilerRunner.runJvmCompilerAsync(
|
compilerRunner.runJvmCompilerAsync(
|
||||||
sourcesToCompile = emptyList(),
|
sourcesToCompile = emptyList(),
|
||||||
@@ -131,7 +131,8 @@ abstract class KaptWithKotlincTask @Inject constructor(
|
|||||||
javaPackagePrefix = javaPackagePrefix.orNull,
|
javaPackagePrefix = javaPackagePrefix.orNull,
|
||||||
args = args,
|
args = args,
|
||||||
environment = environment,
|
environment = environment,
|
||||||
jdkHome = defaultKotlinJavaToolchain.get().providedJvm.get().javaHome
|
jdkHome = defaultKotlinJavaToolchain.get().providedJvm.get().javaHome,
|
||||||
|
null
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.gradle.internal.tasks
|
|||||||
import org.gradle.api.Task
|
import org.gradle.api.Task
|
||||||
import org.gradle.api.file.ConfigurableFileCollection
|
import org.gradle.api.file.ConfigurableFileCollection
|
||||||
import org.gradle.api.file.FileCollection
|
import org.gradle.api.file.FileCollection
|
||||||
|
import org.gradle.api.provider.Property
|
||||||
import org.gradle.api.tasks.Internal
|
import org.gradle.api.tasks.Internal
|
||||||
import org.jetbrains.kotlin.build.report.metrics.BuildMetricsReporter
|
import org.jetbrains.kotlin.build.report.metrics.BuildMetricsReporter
|
||||||
|
|
||||||
@@ -16,7 +17,7 @@ internal interface TaskWithLocalState : Task {
|
|||||||
val localStateDirectories: ConfigurableFileCollection
|
val localStateDirectories: ConfigurableFileCollection
|
||||||
|
|
||||||
@get:Internal
|
@get:Internal
|
||||||
val metrics: BuildMetricsReporter
|
val metrics: Property<BuildMetricsReporter>
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun TaskWithLocalState.allOutputFiles(): FileCollection =
|
internal fun TaskWithLocalState.allOutputFiles(): FileCollection =
|
||||||
|
|||||||
+1
-1
@@ -95,7 +95,7 @@ private class TaskRecord(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (task is TaskWithLocalState) {
|
if (task is TaskWithLocalState) {
|
||||||
myBuildMetrics.addAll(task.metrics.getMetrics())
|
myBuildMetrics.addAll(task.metrics.get().getMetrics())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-3
@@ -34,6 +34,7 @@ import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinJsBinaryMode.DEVELOPMENT
|
|||||||
import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinJsBinaryMode.PRODUCTION
|
import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinJsBinaryMode.PRODUCTION
|
||||||
import org.jetbrains.kotlin.gradle.tasks.Kotlin2JsCompile
|
import org.jetbrains.kotlin.gradle.tasks.Kotlin2JsCompile
|
||||||
import org.jetbrains.kotlin.gradle.tasks.SourceRoots
|
import org.jetbrains.kotlin.gradle.tasks.SourceRoots
|
||||||
|
import org.jetbrains.kotlin.gradle.tasks.TaskOutputsBackup
|
||||||
import org.jetbrains.kotlin.gradle.utils.getAllDependencies
|
import org.jetbrains.kotlin.gradle.utils.getAllDependencies
|
||||||
import org.jetbrains.kotlin.gradle.utils.getCacheDirectory
|
import org.jetbrains.kotlin.gradle.utils.getCacheDirectory
|
||||||
import org.jetbrains.kotlin.gradle.utils.getDependenciesCacheDirectories
|
import org.jetbrains.kotlin.gradle.utils.getDependenciesCacheDirectories
|
||||||
@@ -100,7 +101,12 @@ abstract class KotlinJsIrLink @Inject constructor(
|
|||||||
return !entryModule.get().asFile.exists()
|
return !entryModule.get().asFile.exists()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun callCompilerAsync(args: K2JSCompilerArguments, sourceRoots: SourceRoots, inputChanges: InputChanges) {
|
override fun callCompilerAsync(
|
||||||
|
args: K2JSCompilerArguments,
|
||||||
|
sourceRoots: SourceRoots,
|
||||||
|
inputChanges: InputChanges,
|
||||||
|
taskOutputsBackup: TaskOutputsBackup?
|
||||||
|
) {
|
||||||
KotlinBuildStatsService.applyIfInitialised {
|
KotlinBuildStatsService.applyIfInitialised {
|
||||||
it.report(BooleanMetrics.JS_IR_INCREMENTAL, incrementalJsIr)
|
it.report(BooleanMetrics.JS_IR_INCREMENTAL, incrementalJsIr)
|
||||||
}
|
}
|
||||||
@@ -131,7 +137,7 @@ abstract class KotlinJsIrLink @Inject constructor(
|
|||||||
it.normalize().absolutePath
|
it.normalize().absolutePath
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
super.callCompilerAsync(args, sourceRoots, inputChanges)
|
super.callCompilerAsync(args, sourceRoots, inputChanges, taskOutputsBackup)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun visitCompilation(
|
private fun visitCompilation(
|
||||||
@@ -347,7 +353,8 @@ internal class CacheBuilder(
|
|||||||
emptyList(),
|
emptyList(),
|
||||||
emptyList(),
|
emptyList(),
|
||||||
compilerArgs,
|
compilerArgs,
|
||||||
environment
|
environment,
|
||||||
|
null
|
||||||
)?.await()
|
)?.await()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+7
-1
@@ -89,6 +89,7 @@ abstract class KotlinCompileCommon @Inject constructor(
|
|||||||
it,
|
it,
|
||||||
null,
|
null,
|
||||||
normalizedKotlinDaemonJvmArguments.orNull,
|
normalizedKotlinDaemonJvmArguments.orNull,
|
||||||
|
metrics.get(),
|
||||||
workerExecutor
|
workerExecutor
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -133,7 +134,12 @@ abstract class KotlinCompileCommon @Inject constructor(
|
|||||||
@get:Internal
|
@get:Internal
|
||||||
internal val expectActualLinker = objects.property(Boolean::class.java)
|
internal val expectActualLinker = objects.property(Boolean::class.java)
|
||||||
|
|
||||||
override fun callCompilerAsync(args: K2MetadataCompilerArguments, sourceRoots: SourceRoots, inputChanges: InputChanges) {
|
override fun callCompilerAsync(
|
||||||
|
args: K2MetadataCompilerArguments,
|
||||||
|
sourceRoots: SourceRoots,
|
||||||
|
inputChanges: InputChanges,
|
||||||
|
taskOutputsBackup: TaskOutputsBackup?
|
||||||
|
) {
|
||||||
val messageCollector = GradlePrintingMessageCollector(logger, args.allWarningsAsErrors)
|
val messageCollector = GradlePrintingMessageCollector(logger, args.allWarningsAsErrors)
|
||||||
val outputItemCollector = OutputItemsCollectorImpl()
|
val outputItemCollector = OutputItemsCollectorImpl()
|
||||||
val compilerRunner = compilerRunner.get()
|
val compilerRunner = compilerRunner.get()
|
||||||
|
|||||||
+46
-22
@@ -92,8 +92,8 @@ abstract class AbstractKotlinCompileTool<T : CommonToolArguments>
|
|||||||
}
|
}
|
||||||
|
|
||||||
@get:Internal
|
@get:Internal
|
||||||
override val metrics: BuildMetricsReporter =
|
override val metrics: Property<BuildMetricsReporter> = project.objects
|
||||||
BuildMetricsReporterImpl()
|
.property(BuildMetricsReporterImpl())
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* By default, should be set by plugin from [COMPILER_CLASSPATH_CONFIGURATION_NAME] configuration.
|
* By default, should be set by plugin from [COMPILER_CLASSPATH_CONFIGURATION_NAME] configuration.
|
||||||
@@ -315,7 +315,12 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments> : AbstractKotl
|
|||||||
internal open val compilerRunner: Provider<GradleCompilerRunner> =
|
internal open val compilerRunner: Provider<GradleCompilerRunner> =
|
||||||
objects.propertyWithConvention(
|
objects.propertyWithConvention(
|
||||||
gradleCompileTaskProvider.map {
|
gradleCompileTaskProvider.map {
|
||||||
GradleCompilerRunner(it, null, normalizedKotlinDaemonJvmArguments.orNull)
|
GradleCompilerRunner(
|
||||||
|
it,
|
||||||
|
null,
|
||||||
|
normalizedKotlinDaemonJvmArguments.orNull,
|
||||||
|
metrics.get()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -323,7 +328,8 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments> : AbstractKotl
|
|||||||
|
|
||||||
@TaskAction
|
@TaskAction
|
||||||
fun execute(inputChanges: InputChanges) {
|
fun execute(inputChanges: InputChanges) {
|
||||||
metrics.measure(BuildTime.GRADLE_TASK_ACTION) {
|
val buildMetrics = metrics.get()
|
||||||
|
buildMetrics.measure(BuildTime.GRADLE_TASK_ACTION) {
|
||||||
systemPropertiesService.get().startIntercept()
|
systemPropertiesService.get().startIntercept()
|
||||||
CompilerSystemProperties.KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY.value = "true"
|
CompilerSystemProperties.KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY.value = "true"
|
||||||
|
|
||||||
@@ -332,7 +338,7 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments> : AbstractKotl
|
|||||||
// To prevent this, we backup outputs before incremental build and restore when exception is thrown
|
// To prevent this, we backup outputs before incremental build and restore when exception is thrown
|
||||||
val outputsBackup: TaskOutputsBackup? =
|
val outputsBackup: TaskOutputsBackup? =
|
||||||
if (isIncrementalCompilationEnabled() && inputChanges.isIncremental)
|
if (isIncrementalCompilationEnabled() && inputChanges.isIncremental)
|
||||||
metrics.measure(BuildTime.BACKUP_OUTPUT) {
|
buildMetrics.measure(BuildTime.BACKUP_OUTPUT) {
|
||||||
TaskOutputsBackup(allOutputFiles())
|
TaskOutputsBackup(allOutputFiles())
|
||||||
}
|
}
|
||||||
else null
|
else null
|
||||||
@@ -343,16 +349,7 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments> : AbstractKotl
|
|||||||
clearLocalState("Task cannot run incrementally")
|
clearLocalState("Task cannot run incrementally")
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
executeImpl(inputChanges, outputsBackup)
|
||||||
executeImpl(inputChanges)
|
|
||||||
} catch (t: Throwable) {
|
|
||||||
if (outputsBackup != null) {
|
|
||||||
metrics.measure(BuildTime.RESTORE_OUTPUT_FROM_BACKUP) {
|
|
||||||
outputsBackup.restoreOutputs()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw t
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -369,7 +366,10 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments> : AbstractKotl
|
|||||||
commonSourceSet
|
commonSourceSet
|
||||||
)
|
)
|
||||||
|
|
||||||
private fun executeImpl(inputChanges: InputChanges) {
|
private fun executeImpl(
|
||||||
|
inputChanges: InputChanges,
|
||||||
|
taskOutputsBackup: TaskOutputsBackup?
|
||||||
|
) {
|
||||||
val sourceRoots = getSourceRoots()
|
val sourceRoots = getSourceRoots()
|
||||||
val allKotlinSources = sourceRoots.kotlinSourceFiles
|
val allKotlinSources = sourceRoots.kotlinSourceFiles
|
||||||
|
|
||||||
@@ -386,7 +386,12 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments> : AbstractKotl
|
|||||||
|
|
||||||
sourceRoots.log(this.name, logger)
|
sourceRoots.log(this.name, logger)
|
||||||
taskBuildDirectory.get().asFile.mkdirs()
|
taskBuildDirectory.get().asFile.mkdirs()
|
||||||
callCompilerAsync(args, sourceRoots, inputChanges)
|
callCompilerAsync(
|
||||||
|
args,
|
||||||
|
sourceRoots,
|
||||||
|
inputChanges,
|
||||||
|
taskOutputsBackup
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
protected fun getChangedFiles(
|
protected fun getChangedFiles(
|
||||||
@@ -420,7 +425,12 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments> : AbstractKotl
|
|||||||
* Compiler might be executed asynchronously. Do not do anything requiring end of compilation after this function is called.
|
* Compiler might be executed asynchronously. Do not do anything requiring end of compilation after this function is called.
|
||||||
* @see [GradleKotlinCompilerWork]
|
* @see [GradleKotlinCompilerWork]
|
||||||
*/
|
*/
|
||||||
internal abstract fun callCompilerAsync(args: T, sourceRoots: SourceRoots, inputChanges: InputChanges)
|
internal abstract fun callCompilerAsync(
|
||||||
|
args: T,
|
||||||
|
sourceRoots: SourceRoots,
|
||||||
|
inputChanges: InputChanges,
|
||||||
|
taskOutputsBackup: TaskOutputsBackup?
|
||||||
|
)
|
||||||
|
|
||||||
@get:Input
|
@get:Input
|
||||||
internal val multiPlatformEnabled: Property<Boolean> = objects.property(Boolean::class.java)
|
internal val multiPlatformEnabled: Property<Boolean> = objects.property(Boolean::class.java)
|
||||||
@@ -640,6 +650,7 @@ abstract class KotlinCompile @Inject constructor(
|
|||||||
it,
|
it,
|
||||||
toolchain.currentJvmJdkToolsJar.orNull,
|
toolchain.currentJvmJdkToolsJar.orNull,
|
||||||
normalizedKotlinDaemonJvmArguments.orNull,
|
normalizedKotlinDaemonJvmArguments.orNull,
|
||||||
|
metrics.get(),
|
||||||
workerExecutor
|
workerExecutor
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
@@ -693,7 +704,12 @@ abstract class KotlinCompile @Inject constructor(
|
|||||||
validateKotlinAndJavaHasSameTargetCompatibility(args)
|
validateKotlinAndJavaHasSameTargetCompatibility(args)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun callCompilerAsync(args: K2JVMCompilerArguments, sourceRoots: SourceRoots, inputChanges: InputChanges) {
|
override fun callCompilerAsync(
|
||||||
|
args: K2JVMCompilerArguments,
|
||||||
|
sourceRoots: SourceRoots,
|
||||||
|
inputChanges: InputChanges,
|
||||||
|
taskOutputsBackup: TaskOutputsBackup?
|
||||||
|
) {
|
||||||
sourceRoots as SourceRoots.ForJvm
|
sourceRoots as SourceRoots.ForJvm
|
||||||
|
|
||||||
val messageCollector = GradlePrintingMessageCollector(logger, args.allWarningsAsErrors)
|
val messageCollector = GradlePrintingMessageCollector(logger, args.allWarningsAsErrors)
|
||||||
@@ -738,7 +754,8 @@ abstract class KotlinCompile @Inject constructor(
|
|||||||
javaPackagePrefix,
|
javaPackagePrefix,
|
||||||
args,
|
args,
|
||||||
environment,
|
environment,
|
||||||
defaultKotlinJavaToolchain.get().providedJvm.get().javaHome
|
defaultKotlinJavaToolchain.get().providedJvm.get().javaHome,
|
||||||
|
taskOutputsBackup
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -944,6 +961,7 @@ abstract class Kotlin2JsCompile @Inject constructor(
|
|||||||
it,
|
it,
|
||||||
null,
|
null,
|
||||||
normalizedKotlinDaemonJvmArguments.orNull,
|
normalizedKotlinDaemonJvmArguments.orNull,
|
||||||
|
metrics.get(),
|
||||||
workerExecutor
|
workerExecutor
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -1052,7 +1070,12 @@ abstract class Kotlin2JsCompile @Inject constructor(
|
|||||||
override val incrementalProps: List<FileCollection>
|
override val incrementalProps: List<FileCollection>
|
||||||
get() = super.incrementalProps + listOf(friendDependencies)
|
get() = super.incrementalProps + listOf(friendDependencies)
|
||||||
|
|
||||||
override fun callCompilerAsync(args: K2JSCompilerArguments, sourceRoots: SourceRoots, inputChanges: InputChanges) {
|
override fun callCompilerAsync(
|
||||||
|
args: K2JSCompilerArguments,
|
||||||
|
sourceRoots: SourceRoots,
|
||||||
|
inputChanges: InputChanges,
|
||||||
|
taskOutputsBackup: TaskOutputsBackup?
|
||||||
|
) {
|
||||||
sourceRoots as SourceRoots.KotlinOnly
|
sourceRoots as SourceRoots.KotlinOnly
|
||||||
|
|
||||||
logger.debug("Calling compiler")
|
logger.debug("Calling compiler")
|
||||||
@@ -1104,7 +1127,8 @@ abstract class Kotlin2JsCompile @Inject constructor(
|
|||||||
sourceRoots.kotlinSourceFiles.files.toList(),
|
sourceRoots.kotlinSourceFiles.files.toList(),
|
||||||
commonSourceSet.toList(),
|
commonSourceSet.toList(),
|
||||||
args,
|
args,
|
||||||
environment
|
environment,
|
||||||
|
taskOutputsBackup
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+12
-13
@@ -10,21 +10,20 @@ import org.jetbrains.kotlin.utils.keysToMap
|
|||||||
import java.io.File
|
import java.io.File
|
||||||
import java.util.HashSet
|
import java.util.HashSet
|
||||||
|
|
||||||
internal class TaskOutputsBackup(private val outputs: FileCollection) {
|
internal class TaskOutputsBackup(
|
||||||
private val previousOutputs: Map<File, ByteArray>
|
val outputs: FileCollection,
|
||||||
|
val previousOutputs: Map<File, Array<Byte>> = outputs
|
||||||
init {
|
.flatMap {
|
||||||
val outputFiles = HashSet<File>()
|
|
||||||
outputs.forEach {
|
|
||||||
if (it.isDirectory) {
|
if (it.isDirectory) {
|
||||||
it.walk().filterTo(outputFiles, File::isFile)
|
it.walk().filter(File::isFile)
|
||||||
} else if (it.isFile) {
|
} else {
|
||||||
outputFiles.add(it)
|
sequenceOf(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.filter { it.exists() }
|
||||||
previousOutputs = outputFiles.keysToMap { it.readBytes() }
|
.toSet()
|
||||||
}
|
.keysToMap { it.readBytes().toTypedArray() }
|
||||||
|
) {
|
||||||
|
|
||||||
fun restoreOutputs() {
|
fun restoreOutputs() {
|
||||||
outputs.forEach {
|
outputs.forEach {
|
||||||
@@ -42,7 +41,7 @@ internal class TaskOutputsBackup(private val outputs: FileCollection) {
|
|||||||
if (dirs.add(dir)) {
|
if (dirs.add(dir)) {
|
||||||
dir.mkdirs()
|
dir.mkdirs()
|
||||||
}
|
}
|
||||||
file.writeBytes(bytes)
|
file.writeBytes(bytes.toByteArray())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -25,7 +25,7 @@ fun throwGradleExceptionIfError(exitCode: ExitCode) {
|
|||||||
|
|
||||||
internal fun TaskWithLocalState.clearLocalState(reason: String? = null) {
|
internal fun TaskWithLocalState.clearLocalState(reason: String? = null) {
|
||||||
val log = GradleKotlinLogger(logger)
|
val log = GradleKotlinLogger(logger)
|
||||||
clearLocalState(allOutputFiles(), log, metrics, reason)
|
clearLocalState(allOutputFiles(), log, metrics.get(), reason)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun clearLocalState(
|
internal fun clearLocalState(
|
||||||
|
|||||||
Reference in New Issue
Block a user