[Gradle] Make Kotlin Native tool runners GCC friendly
Remove project usage with either GradleExecutionContext or associated Settings class. Set of Setting classes are meant to be created upon configuration phase. Therefore, they have to be easily serializable without heavy payload. They also annotated for Input/Output checks. ^KT-43293
This commit is contained in:
+6
-1
@@ -34,6 +34,11 @@ abstract class KotlinToolRunner(
|
|||||||
val logger: Logger,
|
val logger: Logger,
|
||||||
) {
|
) {
|
||||||
companion object {
|
companion object {
|
||||||
|
/**
|
||||||
|
* Executing [KotlinToolRunner] during Gradle Configuration Phase is undesired behaviour.
|
||||||
|
* Currently only [KotlinNativeLibraryGenerationRunner] used in this way.
|
||||||
|
* It should be fixed as part of KT-51255
|
||||||
|
*/
|
||||||
@Deprecated(
|
@Deprecated(
|
||||||
"Building execution context from Project object isn't compatible with Gradle Configuration Cache",
|
"Building execution context from Project object isn't compatible with Gradle Configuration Cache",
|
||||||
ReplaceWith("fromTaskContext()"),
|
ReplaceWith("fromTaskContext()"),
|
||||||
@@ -41,7 +46,7 @@ abstract class KotlinToolRunner(
|
|||||||
)
|
)
|
||||||
fun fromProject(project: Project) = GradleExecutionContext(
|
fun fromProject(project: Project) = GradleExecutionContext(
|
||||||
filesProvider = project::files,
|
filesProvider = project::files,
|
||||||
javaexec = project::javaexec,
|
javaexec = { spec -> project.javaexec(spec) }, // project::javaexec won't work due to different Classloaders
|
||||||
logger = project.logger
|
logger = project.logger
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
+94
-28
@@ -6,6 +6,10 @@
|
|||||||
package org.jetbrains.kotlin.compilerRunner
|
package org.jetbrains.kotlin.compilerRunner
|
||||||
|
|
||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
|
import org.gradle.api.tasks.Classpath
|
||||||
|
import org.gradle.api.tasks.Input
|
||||||
|
import org.gradle.api.tasks.InputFile
|
||||||
|
import org.gradle.api.tasks.Nested
|
||||||
import org.jetbrains.kotlin.cli.common.messages.MessageRenderer
|
import org.jetbrains.kotlin.cli.common.messages.MessageRenderer
|
||||||
import org.jetbrains.kotlin.gradle.dsl.NativeCacheKind
|
import org.jetbrains.kotlin.gradle.dsl.NativeCacheKind
|
||||||
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider
|
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider
|
||||||
@@ -18,6 +22,7 @@ import org.jetbrains.kotlin.konan.properties.resolvablePropertyString
|
|||||||
import org.jetbrains.kotlin.konan.target.HostManager
|
import org.jetbrains.kotlin.konan.target.HostManager
|
||||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||||
import org.jetbrains.kotlin.konan.util.DependencyDirectories
|
import org.jetbrains.kotlin.konan.util.DependencyDirectories
|
||||||
|
import java.io.File
|
||||||
import java.nio.file.Files
|
import java.nio.file.Files
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
@@ -45,10 +50,46 @@ internal fun Project.getKonanCacheKind(target: KonanTarget): NativeCacheKind {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val Project.kotlinNativeCompilerJar: String
|
||||||
|
get() = if (nativeUseEmbeddableCompilerJar)
|
||||||
|
"$konanHome/konan/lib/kotlin-native-compiler-embeddable.jar"
|
||||||
|
else
|
||||||
|
"$konanHome/konan/lib/kotlin-native.jar"
|
||||||
|
|
||||||
internal abstract class KotlinNativeToolRunner(
|
internal abstract class KotlinNativeToolRunner(
|
||||||
protected val toolName: String,
|
protected val toolName: String,
|
||||||
project: Project
|
private val settings: Settings,
|
||||||
) : KotlinToolRunner(project) {
|
executionContext: GradleExecutionContext
|
||||||
|
) : KotlinToolRunner(executionContext) {
|
||||||
|
|
||||||
|
class Settings(
|
||||||
|
@get:Input
|
||||||
|
val konanVersion: CompilerVersion,
|
||||||
|
@get:Input
|
||||||
|
val konanHome: String,
|
||||||
|
@get:InputFile
|
||||||
|
val konanPropertiesFile: File,
|
||||||
|
@get:Input
|
||||||
|
val jvmArgs: List<String>,
|
||||||
|
classpathProvider: () -> Set<File>,
|
||||||
|
) {
|
||||||
|
@get:Classpath
|
||||||
|
val classpath by lazy(classpathProvider)
|
||||||
|
|
||||||
|
constructor(project: Project) : this(
|
||||||
|
konanVersion = project.konanVersion,
|
||||||
|
konanHome = project.konanHome,
|
||||||
|
konanPropertiesFile = project.file("${project.konanHome}/konan/konan.properties"),
|
||||||
|
jvmArgs = project.jvmArgs,
|
||||||
|
classpathProvider = {
|
||||||
|
project.files(
|
||||||
|
project.kotlinNativeCompilerJar,
|
||||||
|
"${project.konanHome}/konan/lib/trove4j.jar"
|
||||||
|
).files
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
final override val displayName get() = toolName
|
final override val displayName get() = toolName
|
||||||
|
|
||||||
final override val mainClass get() = "org.jetbrains.kotlin.cli.utilities.MainKt"
|
final override val mainClass get() = "org.jetbrains.kotlin.cli.utilities.MainKt"
|
||||||
@@ -65,29 +106,18 @@ internal abstract class KotlinNativeToolRunner(
|
|||||||
|
|
||||||
final override val execSystemProperties by lazy {
|
final override val execSystemProperties by lazy {
|
||||||
// Still set konan.home for versions prior to 1.4-M3.
|
// Still set konan.home for versions prior to 1.4-M3.
|
||||||
val konanHomeRequired = project.konanVersion.let {
|
val konanHomeRequired = settings.konanVersion.let {
|
||||||
!it.isAtLeast(1, 4, 0) ||
|
!it.isAtLeast(1, 4, 0) ||
|
||||||
it.toString(showMeta = false, showBuild = false) in listOf("1.4-M1", "1.4-M2")
|
it.toString(showMeta = false, showBuild = false) in listOf("1.4-M1", "1.4-M2")
|
||||||
}
|
}
|
||||||
|
|
||||||
listOfNotNull(
|
listOfNotNull(
|
||||||
if (konanHomeRequired) "konan.home" to project.konanHome else null,
|
if (konanHomeRequired) "konan.home" to settings.konanHome else null,
|
||||||
MessageRenderer.PROPERTY_KEY to MessageRenderer.GRADLE_STYLE.name
|
MessageRenderer.PROPERTY_KEY to MessageRenderer.GRADLE_STYLE.name
|
||||||
).toMap()
|
).toMap()
|
||||||
}
|
}
|
||||||
|
|
||||||
final override val classpath by lazy {
|
final override val classpath get() = settings.classpath
|
||||||
project.files(
|
|
||||||
project.kotlinNativeCompilerJar,
|
|
||||||
"${project.konanHome}/konan/lib/trove4j.jar"
|
|
||||||
).files
|
|
||||||
}
|
|
||||||
|
|
||||||
private val Project.kotlinNativeCompilerJar: String
|
|
||||||
get() = if (nativeUseEmbeddableCompilerJar)
|
|
||||||
"$konanHome/konan/lib/kotlin-native-compiler-embeddable.jar"
|
|
||||||
else
|
|
||||||
"$konanHome/konan/lib/kotlin-native.jar"
|
|
||||||
|
|
||||||
final override fun checkClasspath() =
|
final override fun checkClasspath() =
|
||||||
check(classpath.isNotEmpty()) {
|
check(classpath.isNotEmpty()) {
|
||||||
@@ -98,18 +128,23 @@ internal abstract class KotlinNativeToolRunner(
|
|||||||
""".trimIndent()
|
""".trimIndent()
|
||||||
}
|
}
|
||||||
|
|
||||||
data class IsolatedClassLoaderCacheKey(val classpath: Set<java.io.File>)
|
data class IsolatedClassLoaderCacheKey(val classpath: Set<File>)
|
||||||
|
|
||||||
// TODO: can't we use this for other implementations too?
|
// TODO: can't we use this for other implementations too?
|
||||||
final override val isolatedClassLoaderCacheKey get() = IsolatedClassLoaderCacheKey(classpath)
|
final override val isolatedClassLoaderCacheKey get() = IsolatedClassLoaderCacheKey(classpath)
|
||||||
|
|
||||||
override fun transformArgs(args: List<String>) = listOf(toolName) + args
|
override fun transformArgs(args: List<String>) = listOf(toolName) + args
|
||||||
|
|
||||||
final override fun getCustomJvmArgs() = project.jvmArgs
|
final override fun getCustomJvmArgs() = settings.jvmArgs
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A common ancestor for all runners that run the cinterop tool. */
|
/** A common ancestor for all runners that run the cinterop tool. */
|
||||||
internal abstract class AbstractKotlinNativeCInteropRunner(toolName: String, project: Project) : KotlinNativeToolRunner(toolName, project) {
|
internal abstract class AbstractKotlinNativeCInteropRunner(
|
||||||
|
toolName: String,
|
||||||
|
settings: Settings,
|
||||||
|
executionContext: GradleExecutionContext
|
||||||
|
) : KotlinNativeToolRunner(toolName, settings, executionContext) {
|
||||||
|
|
||||||
override val mustRunViaExec get() = true
|
override val mustRunViaExec get() = true
|
||||||
|
|
||||||
override val execEnvironment by lazy {
|
override val execEnvironment by lazy {
|
||||||
@@ -126,7 +161,7 @@ internal abstract class AbstractKotlinNativeCInteropRunner(toolName: String, pro
|
|||||||
if (HostManager.host == KonanTarget.MINGW_X64) {
|
if (HostManager.host == KonanTarget.MINGW_X64) {
|
||||||
// TODO: Read it from Platform properties when it is accessible.
|
// TODO: Read it from Platform properties when it is accessible.
|
||||||
val konanProperties = Properties().apply {
|
val konanProperties = Properties().apply {
|
||||||
project.file("${project.konanHome}/konan/konan.properties").inputStream().use(::load)
|
settings.konanPropertiesFile.inputStream().use(::load)
|
||||||
}
|
}
|
||||||
|
|
||||||
konanProperties.resolvablePropertyString("llvmHome.mingw_x64")?.let { toolchainDir ->
|
konanProperties.resolvablePropertyString("llvmHome.mingw_x64")?.let { toolchainDir ->
|
||||||
@@ -140,25 +175,47 @@ internal abstract class AbstractKotlinNativeCInteropRunner(toolName: String, pro
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Kotlin/Native C-interop tool runner */
|
/** Kotlin/Native C-interop tool runner */
|
||||||
internal class KotlinNativeCInteropRunner private constructor(project: Project) : AbstractKotlinNativeCInteropRunner("cinterop", project) {
|
internal class KotlinNativeCInteropRunner
|
||||||
|
private constructor(
|
||||||
|
private val settings: Settings,
|
||||||
|
gradleExecutionContext: GradleExecutionContext,
|
||||||
|
) : AbstractKotlinNativeCInteropRunner("cinterop", settings, gradleExecutionContext) {
|
||||||
|
|
||||||
interface ExecutionContext {
|
interface ExecutionContext {
|
||||||
val project: Project
|
val runnerSettings: Settings
|
||||||
|
val gradleExecutionContext: GradleExecutionContext
|
||||||
fun runWithContext(action: () -> Unit)
|
fun runWithContext(action: () -> Unit)
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun ExecutionContext.run(args: List<String>) {
|
fun ExecutionContext.run(args: List<String>) {
|
||||||
val runner = KotlinNativeCInteropRunner(project)
|
val runner = KotlinNativeCInteropRunner(runnerSettings, gradleExecutionContext)
|
||||||
runWithContext { runner.run(args) }
|
runWithContext { runner.run(args) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Kotlin/Native compiler runner */
|
/** Kotlin/Native compiler runner */
|
||||||
internal class KotlinNativeCompilerRunner(project: Project) : KotlinNativeToolRunner("konanc", project) {
|
internal class KotlinNativeCompilerRunner(
|
||||||
private val useArgFile get() = project.disableKonanDaemon
|
private val settings: Settings,
|
||||||
|
executionContext: GradleExecutionContext
|
||||||
|
) : KotlinNativeToolRunner("konanc", settings.parent, executionContext) {
|
||||||
|
class Settings(
|
||||||
|
@get:Nested
|
||||||
|
val parent: KotlinNativeToolRunner.Settings,
|
||||||
|
|
||||||
override val mustRunViaExec get() = project.disableKonanDaemon
|
@get:Input
|
||||||
|
val disableKonanDaemon: Boolean,
|
||||||
|
) {
|
||||||
|
constructor(project: Project) : this(
|
||||||
|
parent = KotlinNativeToolRunner.Settings(project),
|
||||||
|
disableKonanDaemon = project.disableKonanDaemon,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private val useArgFile get() = settings.disableKonanDaemon
|
||||||
|
|
||||||
|
override val mustRunViaExec get() = settings.disableKonanDaemon
|
||||||
|
|
||||||
override fun transformArgs(args: List<String>): List<String> {
|
override fun transformArgs(args: List<String>): List<String> {
|
||||||
if (!useArgFile) return super.transformArgs(args)
|
if (!useArgFile) return super.transformArgs(args)
|
||||||
@@ -178,8 +235,17 @@ internal class KotlinNativeCompilerRunner(project: Project) : KotlinNativeToolRu
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Platform libraries generation tool. Runs the cinterop tool under the hood. */
|
/** Platform libraries generation tool. Runs the cinterop tool under the hood. */
|
||||||
internal class KotlinNativeLibraryGenerationRunner(project: Project) :
|
internal class KotlinNativeLibraryGenerationRunner(
|
||||||
AbstractKotlinNativeCInteropRunner("generatePlatformLibraries", project) {
|
private val settings: Settings,
|
||||||
|
executionContext: GradleExecutionContext
|
||||||
|
) :
|
||||||
|
AbstractKotlinNativeCInteropRunner("generatePlatformLibraries", settings, executionContext) {
|
||||||
|
|
||||||
|
constructor(project: Project): this(
|
||||||
|
settings = Settings(project),
|
||||||
|
executionContext = GradleExecutionContext.fromProject(project)
|
||||||
|
)
|
||||||
|
|
||||||
// The library generator works for a long time so enabling C2 can improve performance.
|
// The library generator works for a long time so enabling C2 can improve performance.
|
||||||
override val disableC2: Boolean = false
|
override val disableC2: Boolean = false
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user