Add workaround for external plugin modifying options on common task execution

Currently know problematic place is in 'common-configuration.gradle.kts'
 setting '-Xklib-relative-path-base'. This is done in task doFirst{}
 action to avoid remote build cache misses due to absolute path usage.

^KT-27301 In Progress
This commit is contained in:
Yahor Berdnikau
2022-09-17 14:49:40 +02:00
parent 5121db6e2c
commit c8472fb837
2 changed files with 57 additions and 4 deletions
@@ -28,6 +28,7 @@ import org.jetbrains.kotlin.compilerRunner.OutputItemsCollectorImpl
import org.jetbrains.kotlin.gradle.dsl.*
import org.jetbrains.kotlin.gradle.internal.tasks.allOutputFiles
import org.jetbrains.kotlin.gradle.logging.GradlePrintingMessageCollector
import org.jetbrains.kotlin.gradle.tasks.internal.KotlinMultiplatformCommonOptionsCompat
import java.io.File
import javax.inject.Inject
@@ -46,10 +47,20 @@ abstract class KotlinCompileCommon @Inject constructor(
@Suppress("DEPRECATION")
@Deprecated("Replaced by compilerOptions input", replaceWith = ReplaceWith("compilerOptions"))
override val kotlinOptions: KotlinMultiplatformCommonOptions = object : KotlinMultiplatformCommonOptions {
override val options: CompilerMultiplatformCommonOptions
get() = compilerOptions
}
override val kotlinOptions: KotlinMultiplatformCommonOptions = KotlinMultiplatformCommonOptionsCompat(
{ this },
compilerOptions
)
/**
* Workaround for those "nasty" plugins that are adding 'freeCompilerArgs' on task execution phase.
* With properties api it is not possible to update property value after task configuration is finished.
*
* Marking it as `@Internal` as anyway on the configuration phase, when Gradle does task inputs snapshot,
* this input will always be empty.
*/
@get:Internal
internal var additionalFreeCompilerArgs: List<String> = listOf()
override fun createCompilerArgs(): K2MetadataCompilerArguments =
K2MetadataCompilerArguments()
@@ -77,6 +88,10 @@ abstract class KotlinCompileCommon @Inject constructor(
}
(compilerOptions as CompilerMultiplatformCommonOptionsDefault).fillCompilerArguments(args)
if (additionalFreeCompilerArgs.isNotEmpty()) {
args.freeArgs = compilerOptions.freeCompilerArgs.get().union(additionalFreeCompilerArgs).toList()
}
}
@get:PathSensitive(PathSensitivity.RELATIVE)
@@ -0,0 +1,38 @@
/*
* Copyright 2010-2022 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.tasks.internal
import org.jetbrains.kotlin.gradle.dsl.*
import org.jetbrains.kotlin.gradle.tasks.KotlinCompileCommon
@Suppress("DEPRECATION")
class KotlinMultiplatformCommonOptionsCompat(
private val task: () -> KotlinCompileCommon,
override val options: CompilerMultiplatformCommonOptions
) : KotlinMultiplatformCommonOptions {
override var freeCompilerArgs: List<String>
get() = if (isTaskExecuting) {
options.freeCompilerArgs.get()
.union(task().additionalFreeCompilerArgs)
.toList()
} else {
options.freeCompilerArgs.get()
}
set(value) = if (isTaskExecuting) {
task().logger.warn(
"kotlinOptions.freeCompilerArgs were changed on task execution phase: ${value.joinToString()}\n" +
"This behaviour will be deprecated and become an error in future releases!"
)
task().additionalFreeCompilerArgs = value
} else {
options.freeCompilerArgs.set(value)
}
private val isTaskExecuting: Boolean
get() = task().state.executing
}