Fix toolchain does not configure project level jvm target convention
Now JDK toolchain configures project level compiler options jvm target convention and does not override convention for task. For use case when toolchain is configured via task DSL jvm target convention overrides project level convention. ^KT-57393 Fixed
This commit is contained in:
committed by
Space Team
parent
aa5261395e
commit
ac2d00916c
+56
@@ -12,6 +12,7 @@ import org.gradle.internal.jvm.Jvm
|
||||
import org.gradle.testkit.runner.BuildResult
|
||||
import org.gradle.util.GradleVersion
|
||||
import org.jetbrains.kotlin.gradle.testbase.*
|
||||
import org.jetbrains.kotlin.test.TestMetadata
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
import java.io.File
|
||||
import kotlin.io.path.appendText
|
||||
@@ -702,6 +703,61 @@ class KotlinJavaToolchainTest : KGPBaseTest() {
|
||||
}
|
||||
}
|
||||
|
||||
@DisplayName("Toolchain should not override Jvm target configured in project level DSL")
|
||||
@TestMetadata("kotlin-java-toolchain/simple")
|
||||
@GradleTest
|
||||
fun toolchainNotOverrideProjectJvmTarget(gradleVersion: GradleVersion) {
|
||||
project(
|
||||
projectName = "simple".fullProjectName,
|
||||
gradleVersion = gradleVersion,
|
||||
buildOptions = defaultBuildOptions.copy(logLevel = LogLevel.DEBUG)
|
||||
) {
|
||||
buildGradle.appendText(
|
||||
//language=groovy
|
||||
"""
|
||||
|
|
||||
|kotlin.compilerOptions.jvmTarget.set(org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_11)
|
||||
|
|
||||
""".trimMargin()
|
||||
)
|
||||
|
||||
build(":compileKotlin") {
|
||||
assertTasksExecuted(":compileKotlin")
|
||||
assertCompilerArgument(":compileKotlin", "-jvm-target 11")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@AndroidGradlePluginTests
|
||||
@DisplayName("Toolchain should not override Jvm taget configured via kotlinOptions in android project")
|
||||
@AndroidTestVersions(minVersion = TestVersions.AGP.AGP_42)
|
||||
@GradleAndroidTest
|
||||
internal fun kotlinOptionsAndroidAndToolchainNotOverrideJvmTarget(
|
||||
gradleVersion: GradleVersion,
|
||||
agpVersion: String,
|
||||
providedJdk: JdkVersions.ProvidedJdk
|
||||
) {
|
||||
project(
|
||||
"android".fullProjectName,
|
||||
gradleVersion,
|
||||
buildOptions = defaultBuildOptions.copy(androidVersion = agpVersion, logLevel = LogLevel.DEBUG),
|
||||
buildJdk = providedJdk.location
|
||||
) {
|
||||
buildGradle.appendText(
|
||||
//language=groovy
|
||||
"""
|
||||
|
|
||||
|android.kotlinOptions.jvmTarget = "11"
|
||||
""".trimMargin()
|
||||
)
|
||||
|
||||
build(":compileDebugKotlin") {
|
||||
assertTasksExecuted(":compileDebugKotlin")
|
||||
assertCompilerArgument(":compileDebugKotlin", "-jvm-target 11")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun BuildResult.assertJdkHomeIsUsingJdk(
|
||||
javaexecPath: String
|
||||
) = assertOutputContains("[KOTLIN] Kotlin compilation 'jdkHome' argument: $javaexecPath")
|
||||
|
||||
+1
-1
@@ -75,7 +75,7 @@ abstract class KotlinTopLevelExtension(internal val project: Project) : KotlinTo
|
||||
|
||||
override lateinit var coreLibrariesVersion: String
|
||||
|
||||
private val toolchainSupport = ToolchainSupport.createToolchain(project)
|
||||
private val toolchainSupport = ToolchainSupport.createToolchain(project, this)
|
||||
|
||||
/**
|
||||
* Configures [Java toolchain](https://docs.gradle.org/current/userguide/toolchains.html) both for Kotlin JVM and Java tasks.
|
||||
|
||||
+23
-3
@@ -14,6 +14,7 @@ import org.gradle.api.tasks.TaskContainer
|
||||
import org.gradle.jvm.toolchain.JavaToolchainService
|
||||
import org.gradle.jvm.toolchain.JavaToolchainSpec
|
||||
import org.jetbrains.kotlin.gradle.tasks.DefaultKotlinJavaToolchain
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile
|
||||
import org.jetbrains.kotlin.gradle.tasks.UsesKotlinJavaToolchain
|
||||
import org.jetbrains.kotlin.gradle.tasks.withType
|
||||
import org.jetbrains.kotlin.gradle.utils.newInstance
|
||||
@@ -24,12 +25,14 @@ internal interface ToolchainSupport {
|
||||
|
||||
companion object {
|
||||
internal fun createToolchain(
|
||||
project: Project
|
||||
project: Project,
|
||||
kotlinExtension: KotlinTopLevelExtensionConfig
|
||||
): ToolchainSupport {
|
||||
return project.objects.newInstance<DefaultToolchainSupport>(
|
||||
project.extensions,
|
||||
project.tasks,
|
||||
project.plugins
|
||||
project.plugins,
|
||||
kotlinExtension
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -38,7 +41,8 @@ internal interface ToolchainSupport {
|
||||
internal abstract class DefaultToolchainSupport @Inject constructor(
|
||||
private val extensions: ExtensionContainer,
|
||||
private val tasks: TaskContainer,
|
||||
private val plugins: PluginContainer
|
||||
private val plugins: PluginContainer,
|
||||
private val kotlinExtension: KotlinTopLevelExtensionConfig
|
||||
) : ToolchainSupport {
|
||||
private val toolchainSpec: JavaToolchainSpec
|
||||
get() = extensions
|
||||
@@ -60,12 +64,28 @@ internal abstract class DefaultToolchainSupport @Inject constructor(
|
||||
val toolchainService = extensions.findByType(JavaToolchainService::class.java)
|
||||
?: error("Gradle JavaToolchainService is not available!")
|
||||
val javaLauncher = toolchainService.launcherFor(toolchainSpec)
|
||||
|
||||
tasks
|
||||
.withType<UsesKotlinJavaToolchain>()
|
||||
.configureEach {
|
||||
(it.kotlinJavaToolchain.toolchain as DefaultKotlinJavaToolchain.DefaultJavaToolchainSetter)
|
||||
.useAsConvention(javaLauncher)
|
||||
}
|
||||
|
||||
if (kotlinExtension !is KotlinJvmProjectExtension &&
|
||||
kotlinExtension !is KotlinAndroidProjectExtension
|
||||
) {
|
||||
tasks
|
||||
.withType<UsesKotlinJavaToolchain>()
|
||||
.configureEach { task ->
|
||||
if (task is KotlinJvmCompile) {
|
||||
DefaultKotlinJavaToolchain.wireJvmTargetToJvm(
|
||||
task.compilerOptions,
|
||||
(task.kotlinJavaToolchain as DefaultKotlinJavaToolchain).providedJvm
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+4
@@ -33,6 +33,10 @@ internal open class KotlinJvmPlugin(
|
||||
) {
|
||||
extensionCompilerOptions.verbose.convention(logger.isDebugEnabled)
|
||||
extensionCompilerOptions.moduleName.convention(baseModuleName())
|
||||
DefaultKotlinJavaToolchain.wireJvmTargetToToolchain(
|
||||
extensionCompilerOptions,
|
||||
project
|
||||
)
|
||||
compilationsContainer.configureEach {
|
||||
val jvmCompilerOptions = it.compilerOptions.options as KotlinJvmCompilerOptions
|
||||
KotlinJvmCompilerOptionsHelper.syncOptionsAsConvention(
|
||||
|
||||
+65
-25
@@ -7,15 +7,18 @@ package org.jetbrains.kotlin.gradle.tasks
|
||||
|
||||
import org.gradle.api.GradleException
|
||||
import org.gradle.api.JavaVersion
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.file.ProjectLayout
|
||||
import org.gradle.api.file.RegularFileProperty
|
||||
import org.gradle.api.model.ObjectFactory
|
||||
import org.gradle.api.plugins.JavaPluginExtension
|
||||
import org.gradle.api.provider.Property
|
||||
import org.gradle.api.provider.Provider
|
||||
import org.gradle.api.tasks.Internal
|
||||
import org.gradle.internal.jvm.Jvm
|
||||
import org.gradle.jvm.toolchain.*
|
||||
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmCompilerOptions
|
||||
import org.jetbrains.kotlin.gradle.utils.*
|
||||
import org.jetbrains.kotlin.gradle.utils.chainedFinalizeValueOnRead
|
||||
import org.jetbrains.kotlin.gradle.utils.property
|
||||
@@ -27,7 +30,7 @@ import javax.inject.Inject
|
||||
internal abstract class DefaultKotlinJavaToolchain @Inject constructor(
|
||||
private val objects: ObjectFactory,
|
||||
projectLayout: ProjectLayout,
|
||||
private val kotlinCompileTaskProvider: () -> KotlinCompile?
|
||||
jvmCompilerOptions: () -> KotlinJvmCompilerOptions?
|
||||
) : KotlinJavaToolchain {
|
||||
|
||||
@get:Internal
|
||||
@@ -60,27 +63,6 @@ internal abstract class DefaultKotlinJavaToolchain @Inject constructor(
|
||||
)
|
||||
.chainedFinalizeValueOnRead()
|
||||
|
||||
init {
|
||||
wireJvmTargetToToolchain()
|
||||
}
|
||||
|
||||
private fun wireJvmTargetToToolchain() {
|
||||
kotlinCompileTaskProvider()?.let { task ->
|
||||
task.compilerOptions.jvmTarget.convention(
|
||||
providedJvm.map { jvm ->
|
||||
// For Java 9 and Java 10 JavaVersion returns "1.9" or "1.10" accordingly
|
||||
// that is not accepted by Kotlin compiler
|
||||
val normalizedVersion = when (jvm.javaVersion) {
|
||||
JavaVersion.VERSION_1_9 -> "9"
|
||||
JavaVersion.VERSION_1_10 -> "10"
|
||||
else -> jvm.javaVersion.toString()
|
||||
}
|
||||
JvmTarget.fromTarget(normalizedVersion)
|
||||
}.orElse(JvmTarget.DEFAULT)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@get:Internal
|
||||
internal val javaExecutable: RegularFileProperty = objects
|
||||
.fileProperty()
|
||||
@@ -134,15 +116,20 @@ internal abstract class DefaultKotlinJavaToolchain @Inject constructor(
|
||||
|
||||
final override val jdk: KotlinJavaToolchain.JdkSetter = DefaultJdkSetter(
|
||||
providedJvm,
|
||||
objects
|
||||
objects,
|
||||
jvmCompilerOptions
|
||||
)
|
||||
|
||||
final override val toolchain: KotlinJavaToolchain.JavaToolchainSetter =
|
||||
DefaultJavaToolchainSetter(providedJvm)
|
||||
DefaultJavaToolchainSetter(
|
||||
providedJvm,
|
||||
jvmCompilerOptions
|
||||
)
|
||||
|
||||
private class DefaultJdkSetter(
|
||||
private val providedJvm: Property<Jvm>,
|
||||
private val objects: ObjectFactory,
|
||||
private val jvmCompilerOptions: () -> KotlinJvmCompilerOptions?
|
||||
) : KotlinJavaToolchain.JdkSetter {
|
||||
|
||||
override fun use(
|
||||
@@ -161,11 +148,16 @@ internal abstract class DefaultKotlinJavaToolchain @Inject constructor(
|
||||
Jvm.discovered(jdkHomeLocation, null, jdkVersion)
|
||||
}
|
||||
)
|
||||
|
||||
jvmCompilerOptions()?.let {
|
||||
wireJvmTargetToJvm(it, providedJvm)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class DefaultJavaToolchainSetter(
|
||||
private val providedJvm: Property<Jvm>
|
||||
private val providedJvm: Property<Jvm>,
|
||||
private val jvmCompilerOptions: () -> KotlinJvmCompilerOptions?
|
||||
) : KotlinJavaToolchain.JavaToolchainSetter {
|
||||
|
||||
internal fun useAsConvention(
|
||||
@@ -178,6 +170,54 @@ internal abstract class DefaultKotlinJavaToolchain @Inject constructor(
|
||||
javaLauncher: Provider<JavaLauncher>
|
||||
) {
|
||||
providedJvm.set(javaLauncher.map(::mapToJvm))
|
||||
|
||||
jvmCompilerOptions()?.let {
|
||||
wireJvmTargetToJvm(it, providedJvm)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
internal fun wireJvmTargetToJvm(
|
||||
jvmCompilerOptions: KotlinJvmCompilerOptions,
|
||||
toolchainJvm: Provider<Jvm>
|
||||
) {
|
||||
jvmCompilerOptions.jvmTarget.convention(
|
||||
toolchainJvm.map { jvm ->
|
||||
// For Java 9 and Java 10 JavaVersion returns "1.9" or "1.10" accordingly
|
||||
// that is not accepted by Kotlin compiler
|
||||
val normalizedVersion = when (jvm.javaVersion) {
|
||||
JavaVersion.VERSION_1_9 -> "9"
|
||||
JavaVersion.VERSION_1_10 -> "10"
|
||||
else -> jvm.javaVersion.toString()
|
||||
}
|
||||
JvmTarget.fromTarget(normalizedVersion)
|
||||
}.orElse(JvmTarget.DEFAULT)
|
||||
)
|
||||
}
|
||||
|
||||
private fun wireJvmTargetToToolchain(
|
||||
jvmCompilerOptions: KotlinJvmCompilerOptions,
|
||||
javaLauncher: Provider<JavaLauncher>
|
||||
): Unit = wireJvmTargetToJvm(
|
||||
jvmCompilerOptions,
|
||||
javaLauncher.map(::mapToJvm)
|
||||
)
|
||||
|
||||
internal fun wireJvmTargetToToolchain(
|
||||
compilerOptions: KotlinJvmCompilerOptions,
|
||||
project: Project,
|
||||
) {
|
||||
project.plugins.withId("org.gradle.java-base") {
|
||||
val toolchainService = project.extensions.findByType(JavaToolchainService::class.java)
|
||||
?: error("Gradle JavaToolchainService is not available!")
|
||||
val toolchainSpec = project.extensions
|
||||
.getByType(JavaPluginExtension::class.java)
|
||||
.toolchain
|
||||
val javaLauncher = toolchainService.launcherFor(toolchainSpec)
|
||||
wireJvmTargetToToolchain(compilerOptions, javaLauncher)
|
||||
}
|
||||
}
|
||||
|
||||
private fun mapToJvm(javaLauncher: JavaLauncher): Jvm {
|
||||
|
||||
+1
-1
@@ -144,7 +144,7 @@ abstract class KotlinCompile @Inject constructor(
|
||||
|
||||
@get:Internal
|
||||
final override val defaultKotlinJavaToolchain: Provider<DefaultKotlinJavaToolchain> = objectFactory
|
||||
.propertyWithNewInstance({ this })
|
||||
.propertyWithNewInstance({ compilerOptions })
|
||||
|
||||
final override val kotlinJavaToolchainProvider: Provider<KotlinJavaToolchain> = defaultKotlinJavaToolchain.cast()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user