From a158d097682834a4434925863e3e3d7afcac3b20 Mon Sep 17 00:00:00 2001 From: Yahor Berdnikau Date: Sun, 30 Jul 2023 22:35:46 +0200 Subject: [PATCH] [Gradle] Introduce compilerOptions for Kotlin native target KotlinNativeTarget now exposes experimental compiler options DSL that are passed as a convention into target compilations compiler options. ^KT-57292 In Progress --- .../kotlin/gradle/CompilerOptionsIT.kt | 3 +- ...nCompilationCompilerOptionsConfigurator.kt | 21 +++++ .../native/KotlinNativeCompilationFactory.kt | 8 +- .../targets/native/KotlinNativeTarget.kt | 28 ++++++- .../native/KotlinNativeTargetConfigurator.kt | 1 - .../unitTests/ProjectCompilerOptionsTests.kt | 80 +++++++++++++++++++ 6 files changed, 135 insertions(+), 6 deletions(-) create mode 100644 libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/ProjectCompilerOptionsTests.kt diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/CompilerOptionsIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/CompilerOptionsIT.kt index d4ad4c77f7d..b0b670122e8 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/CompilerOptionsIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/CompilerOptionsIT.kt @@ -491,8 +491,7 @@ internal class CompilerOptionsIT : KGPBaseTest() { gradleVersion = gradleVersion, // We need to get specific task output as commonizer may run first producing // arguments as well in output - // TODO Yahor: remove 'configurationCache = false' once it will be merged into `master` - issue due to the build reports error - buildOptions = defaultBuildOptions.copy(logLevel = LogLevel.DEBUG, configurationCache = false) + buildOptions = defaultBuildOptions.copy(logLevel = LogLevel.DEBUG) ) { buildGradle.modify { val buildScript = """ diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/KotlinCompilationCompilerOptionsConfigurator.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/KotlinCompilationCompilerOptionsConfigurator.kt index beca255b202..b4ff7d4f6c6 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/KotlinCompilationCompilerOptionsConfigurator.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/KotlinCompilationCompilerOptionsConfigurator.kt @@ -7,6 +7,8 @@ package org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl import org.jetbrains.kotlin.gradle.dsl.KotlinJvmCompilerOptions import org.jetbrains.kotlin.gradle.dsl.KotlinJvmCompilerOptionsHelper +import org.jetbrains.kotlin.gradle.dsl.KotlinNativeCompilerOptions +import org.jetbrains.kotlin.gradle.dsl.KotlinNativeCompilerOptionsHelper import org.jetbrains.kotlin.gradle.plugin.mpp.DecoratedKotlinCompilation import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.factory.KotlinCompilationImplFactory import org.jetbrains.kotlin.gradle.plugin.mpp.moduleNameForCompilation @@ -29,3 +31,22 @@ internal class KotlinCompilationJvmCompilerOptionsFromTargetConfigurator( ) } } + +internal class KotlinCompilationNativeCompilerOptionsFromTargetConfigurator( + private val targetCompilerOptions: KotlinNativeCompilerOptions +) : KotlinCompilationImplFactory.PostConfigure { + override fun configure(compilation: DecoratedKotlinCompilation<*>) { + val nativeCompilerOptions = compilation.compilerOptions.options as KotlinNativeCompilerOptions + KotlinNativeCompilerOptionsHelper.syncOptionsAsConvention( + targetCompilerOptions, + nativeCompilerOptions + ) + + nativeCompilerOptions.moduleName.convention( + moduleNameForCompilation( + compilation.compilationName, + targetCompilerOptions.moduleName + ) + ) + } +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/KotlinNativeCompilationFactory.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/KotlinNativeCompilationFactory.kt index 82cd7120fe8..985d81c5a53 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/KotlinNativeCompilationFactory.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/KotlinNativeCompilationFactory.kt @@ -6,6 +6,8 @@ @file:Suppress("PackageDirectoryMismatch") // Old package for compatibility package org.jetbrains.kotlin.gradle.plugin.mpp +import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.DefaultKotlinCompilationPostConfigure +import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.KotlinCompilationNativeCompilerOptionsFromTargetConfigurator import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.KotlinCompilationSourceSetInclusion import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.KotlinNativeCompilationAssociator import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.factory.KotlinCompilationImplFactory @@ -14,7 +16,7 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.factory.NativeKotl import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.factory.NativeKotlinCompilationTaskNamesContainerFactory open class KotlinNativeCompilationFactory internal constructor( - override val target: KotlinNativeTarget + final override val target: KotlinNativeTarget ) : KotlinCompilationFactory { override val itemClass: Class @@ -29,6 +31,10 @@ open class KotlinNativeCompilationFactory internal constructor( compilationSourceSetInclusion = KotlinCompilationSourceSetInclusion( KotlinCompilationSourceSetInclusion.NativeAddSourcesToCompileTask ), + postConfigureAction = KotlinCompilationImplFactory.PostConfigure.composite( + DefaultKotlinCompilationPostConfigure, + KotlinCompilationNativeCompilerOptionsFromTargetConfigurator(target.compilerOptions) + ) ) override fun create(name: String): KotlinNativeCompilation { diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/KotlinNativeTarget.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/KotlinNativeTarget.kt index 60d88228d77..d938f080974 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/KotlinNativeTarget.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/KotlinNativeTarget.kt @@ -6,14 +6,15 @@ @file:Suppress("PackageDirectoryMismatch") // Old package for compatibility package org.jetbrains.kotlin.gradle.plugin.mpp +import org.gradle.api.Action import org.gradle.api.NamedDomainObjectContainer import org.gradle.api.Project import org.gradle.api.artifacts.Dependency import org.gradle.api.attributes.Attribute import org.gradle.api.plugins.BasePlugin import org.gradle.jvm.tasks.Jar -import org.jetbrains.kotlin.gradle.dsl.KotlinNativeBinaryContainer -import org.jetbrains.kotlin.gradle.dsl.kotlinExtension +import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi +import org.jetbrains.kotlin.gradle.dsl.* import org.jetbrains.kotlin.gradle.plugin.* import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.* import org.jetbrains.kotlin.gradle.plugin.sources.awaitPlatformCompilations @@ -26,6 +27,8 @@ import org.jetbrains.kotlin.gradle.targets.native.NativeBinaryTestRunSource import org.jetbrains.kotlin.gradle.targets.native.internal.includeCommonizedCInteropMetadata import org.jetbrains.kotlin.gradle.tasks.locateOrRegisterTask import org.jetbrains.kotlin.gradle.utils.dashSeparatedName +import org.jetbrains.kotlin.gradle.utils.klibModuleName +import org.jetbrains.kotlin.gradle.utils.newInstance import org.jetbrains.kotlin.konan.target.HostManager import org.jetbrains.kotlin.konan.target.KonanTarget import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly @@ -133,6 +136,27 @@ abstract class KotlinNativeTarget @Inject constructor( override val publishable: Boolean get() = konanTarget.enabledOnCurrentHost + @ExperimentalKotlinGradlePluginApi + override val compilerOptions: KotlinNativeCompilerOptions = project.objects + .newInstance() + .apply { + moduleName.convention( + project.klibModuleName( + project.baseModuleName() + ) + ) + } + + @ExperimentalKotlinGradlePluginApi + fun compilerOptions(configure: KotlinNativeCompilerOptions.() -> Unit) { + configure(compilerOptions) + } + + @ExperimentalKotlinGradlePluginApi + fun compilerOptions(configure: Action) { + configure.execute(compilerOptions) + } + // User-visible constants val DEBUG = NativeBuildType.DEBUG val RELEASE = NativeBuildType.RELEASE diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/KotlinNativeTargetConfigurator.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/KotlinNativeTargetConfigurator.kt index 415bb3972a5..a2c78c71d66 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/KotlinNativeTargetConfigurator.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/KotlinNativeTargetConfigurator.kt @@ -404,7 +404,6 @@ open class KotlinNativeTargetConfigurator : AbstractKotl if (propertiesProvider.useK2 == true) { it.compilerOptions.useK2.set(true) } - it.compilerOptions.useK2.disallowChanges() it.runViaBuildToolsApi.value(false).disallowChanges() // K/N is not yet supported it.explicitApiMode diff --git a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/ProjectCompilerOptionsTests.kt b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/ProjectCompilerOptionsTests.kt new file mode 100644 index 00000000000..87622185b5b --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/ProjectCompilerOptionsTests.kt @@ -0,0 +1,80 @@ +/* + * Copyright 2010-2023 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.unitTests + +import org.gradle.api.Project +import org.jetbrains.kotlin.gradle.dsl.KotlinNativeCompilerOptions +import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension +import org.jetbrains.kotlin.gradle.tasks.KotlinCompilationTask +import org.jetbrains.kotlin.gradle.tasks.withType +import org.jetbrains.kotlin.gradle.util.buildProjectWithMPP +import org.jetbrains.kotlin.gradle.utils.named +import kotlin.test.Test +import kotlin.test.assertEquals + +class ProjectCompilerOptionsTests { + + @Test + fun nativeTargetCompilerOptionsDSL() { + val project = buildProjectWithMPP { + with(multiplatformExtension) { + linuxX64 { + compilerOptions { + progressiveMode.set(true) + } + } + + iosX64 { + compilerOptions { + suppressWarnings.set(true) + } + } + + applyDefaultHierarchyTemplate() + } + } + + project.evaluate() + + assertEquals(true, project.kotlinNativeTask("compileKotlinLinuxX64").compilerOptions.progressiveMode.get()) + assertEquals(false, project.kotlinNativeTask("compileKotlinLinuxX64").compilerOptions.suppressWarnings.get()) + assertEquals(true, project.kotlinNativeTask("compileTestKotlinLinuxX64").compilerOptions.progressiveMode.get()) + assertEquals(false, project.kotlinNativeTask("compileTestKotlinLinuxX64").compilerOptions.suppressWarnings.get()) + assertEquals(true, project.kotlinNativeTask("compileKotlinIosX64").compilerOptions.suppressWarnings.get()) + assertEquals(false, project.kotlinNativeTask("compileKotlinIosX64").compilerOptions.progressiveMode.get()) + assertEquals(true, project.kotlinNativeTask("compileTestKotlinIosX64").compilerOptions.suppressWarnings.get()) + assertEquals(false, project.kotlinNativeTask("compileTestKotlinIosX64").compilerOptions.progressiveMode.get()) + } + + @Test + fun nativeTaskOverridesTargetOptions() { + val project = buildProjectWithMPP { + tasks.withType>().configureEach { + if (it.name == "compileKotlinLinuxX64") { + it.compilerOptions.progressiveMode.set(false) + } + } + + with(multiplatformExtension) { + linuxX64 { + compilerOptions { + progressiveMode.set(true) + } + } + + applyDefaultHierarchyTemplate() + } + } + + project.evaluate() + + assertEquals(false, project.kotlinNativeTask("compileKotlinLinuxX64").compilerOptions.progressiveMode.get()) + } + + private fun Project.kotlinNativeTask(name: String): KotlinCompilationTask = tasks + .named>(name) + .get() +} \ No newline at end of file