diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/compilerRunner/nativeToolRunners.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/compilerRunner/nativeToolRunners.kt index d459b4c503d..f51a3bd7005 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/compilerRunner/nativeToolRunners.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/compilerRunner/nativeToolRunners.kt @@ -71,8 +71,8 @@ internal abstract class KotlinNativeToolRunner( } listOfNotNull( - if (konanHomeRequired) "konan.home" to project.konanHome else null, - MessageRenderer.PROPERTY_KEY to MessageRenderer.GRADLE_STYLE.name + if (konanHomeRequired) "konan.home" to project.konanHome else null, + MessageRenderer.PROPERTY_KEY to MessageRenderer.GRADLE_STYLE.name ).toMap() } @@ -140,7 +140,19 @@ internal abstract class AbstractKotlinNativeCInteropRunner(toolName: String, pro } /** Kotlin/Native C-interop tool runner */ -internal class KotlinNativeCInteropRunner(project: Project) : AbstractKotlinNativeCInteropRunner("cinterop", project) +internal class KotlinNativeCInteropRunner private constructor(project: Project) : AbstractKotlinNativeCInteropRunner("cinterop", project) { + interface ExecutionContext { + val project: Project + fun runWithContext(action: () -> Unit) + } + + companion object { + fun ExecutionContext.run(args: List) { + val runner = KotlinNativeCInteropRunner(project) + runWithContext { runner.run(args) } + } + } +} /** Kotlin/Native compiler runner */ internal class KotlinNativeCompilerRunner(project: Project) : KotlinNativeToolRunner("konanc", project) { @@ -172,8 +184,7 @@ internal class KotlinNativeKlibRunner(project: Project) : KotlinNativeToolRunner /** Platform libraries generation tool. Runs the cinterop tool under the hood. */ internal class KotlinNativeLibraryGenerationRunner(project: Project) : - AbstractKotlinNativeCInteropRunner("generatePlatformLibraries", project) -{ + AbstractKotlinNativeCInteropRunner("generatePlatformLibraries", project) { // The library generator works for a long time so enabling C2 can improve performance. override val disableC2: Boolean = false -} \ No newline at end of file +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/CInteropRunnerExecutionContextFactory.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/CInteropRunnerExecutionContextFactory.kt new file mode 100644 index 00000000000..49a2c0d7caa --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/CInteropRunnerExecutionContextFactory.kt @@ -0,0 +1,40 @@ +/* + * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. + * 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.targets.native.tasks + +import org.gradle.api.Project +import org.gradle.api.Task +import org.jetbrains.kotlin.compilerRunner.KotlinNativeCInteropRunner +import org.jetbrains.kotlin.gradle.internal.isInIdeaSync + +internal fun KotlinNativeCInteropRunner.Companion.createExecutionContext( + task: Task +): KotlinNativeCInteropRunner.ExecutionContext { + return if (task.project.isInIdeaSync) IdeaSyncKotlinNativeCInteropRunnerExecutionContext(task) + else DefaultKotlinNativeCInteropRunnerExecutionContext(task.project) +} + +private class DefaultKotlinNativeCInteropRunnerExecutionContext( + override val project: Project +) : KotlinNativeCInteropRunner.ExecutionContext { + override fun runWithContext(action: () -> Unit) = action() +} + +private class IdeaSyncKotlinNativeCInteropRunnerExecutionContext( + private val task: Task +) : KotlinNativeCInteropRunner.ExecutionContext { + + override val project: Project = task.project + + override fun runWithContext(action: () -> Unit) { + try { + action() + } catch (t: Throwable) { + task.logger.warn("Warning: Failed to generate cinterop for ${task.path}: ${t.message ?: ""}", t) + task.outputs.files.forEach { file -> file.deleteRecursively() } + } + } +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/KotlinNativeTasks.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/KotlinNativeTasks.kt index 15f3e8b151b..498e4a90e8d 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/KotlinNativeTasks.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/KotlinNativeTasks.kt @@ -21,6 +21,7 @@ import org.gradle.api.provider.Provider import org.gradle.api.tasks.* import org.gradle.api.tasks.compile.AbstractCompile import org.jetbrains.kotlin.compilerRunner.* +import org.jetbrains.kotlin.compilerRunner.KotlinNativeCInteropRunner.Companion.run import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions import org.jetbrains.kotlin.gradle.dsl.KotlinCommonToolOptions import org.jetbrains.kotlin.gradle.dsl.KotlinCompile @@ -35,6 +36,7 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.isMainCompilationData import org.jetbrains.kotlin.gradle.plugin.sources.DefaultLanguageSettingsBuilder import org.jetbrains.kotlin.gradle.targets.native.KonanPropertiesBuildService import org.jetbrains.kotlin.gradle.targets.native.internal.isAllowCommonizer +import org.jetbrains.kotlin.gradle.targets.native.tasks.createExecutionContext import org.jetbrains.kotlin.gradle.utils.* import org.jetbrains.kotlin.gradle.utils.listFilesOrEmpty import org.jetbrains.kotlin.konan.CompilerVersion @@ -1136,6 +1138,10 @@ open class CInteropProcess @Inject constructor(@get:Internal val settings: Defau val outputFile: File get() = outputFileProvider.get() + init { + outputs.upToDateWhen { outputFile.isFile } + } + // Inputs and outputs. @OutputFile @@ -1214,6 +1220,6 @@ open class CInteropProcess @Inject constructor(@get:Internal val settings: Defau } outputFile.parentFile.mkdirs() - KotlinNativeCInteropRunner(project).run(args) + KotlinNativeCInteropRunner.createExecutionContext(this).run(args) } }