From 331ec5318d7f2e69e0f1336e0b477300809abcbc Mon Sep 17 00:00:00 2001 From: Dmitrii Krasnov Date: Fri, 8 Dec 2023 12:56:52 +0000 Subject: [PATCH] [Gradle] Added definitionFile RegularFileProperty in cinterop task ^KT-62795 Fixed Merge-request: KT-MR-13307 Merged-by: Dmitrii Krasnov --- .../kotlin/gradle/native/CinteropIT.kt | 22 +++++++++++++++ .../build.gradle.kts | 27 +++++++++++++++++++ .../buildSrc/build.gradle.kts | 7 +++++ .../src/main/kotlin/CreateDefFileTask.kt | 9 +++++++ .../def/cinterop.def | 6 +++++ .../CreateCInteropTasksSideEffect.kt | 1 + .../targets/native/DefaultCInteropSettings.kt | 17 ++++++++---- .../native/cocoapods/KotlinCocoapodsPlugin.kt | 14 +++++----- .../native/cocoapods/tasks/DefFileTask.kt | 10 +++---- .../targets/native/tasks/KotlinNativeTasks.kt | 12 +++++++-- .../gradle/unitTests/CInteropTaskTest.kt | 3 ++- 11 files changed, 107 insertions(+), 21 deletions(-) create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/cinterop-with-def-creation-task/build.gradle.kts create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/cinterop-with-def-creation-task/buildSrc/build.gradle.kts create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/cinterop-with-def-creation-task/buildSrc/src/main/kotlin/CreateDefFileTask.kt create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/cinterop-with-def-creation-task/def/cinterop.def diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/native/CinteropIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/native/CinteropIT.kt index e8dd8fd465d..79e376b9ae5 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/native/CinteropIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/native/CinteropIT.kt @@ -7,6 +7,7 @@ package org.jetbrains.kotlin.gradle.native import org.gradle.util.GradleVersion import org.jetbrains.kotlin.gradle.testbase.* +import org.junit.jupiter.api.DisplayName import org.junit.jupiter.api.condition.OS @NativeGradlePluginTests @@ -53,4 +54,25 @@ class CinteropIT : KGPBaseTest() { } } } + + @DisplayName("KT-62795: checking that we can pass def file to cinterop task as a output file property from another task") + @GradleTest + fun cinteropWithDefFileFromTaskOutput(gradleVersion: GradleVersion) { + nativeProject("cinterop-with-def-creation-task", gradleVersion = gradleVersion) { + + val defFilePath = projectPath.resolve("def/cinterop.def").toFile().canonicalFile.absolutePath + + build(":assemble") { + assertTasksUpToDate(":createDefFileTask") // this task does not have any action, so it always just UpToDate + extractNativeTasksCommandLineArgumentsFromOutput(":cinteropCinteropNative", toolName = NativeToolKind.C_INTEROP) { + assertCommandLineArgumentsContainSequentially("-def", defFilePath) + } + } + + build(":assemble") { + assertTasksUpToDate(":createDefFileTask") + assertTasksUpToDate(":cinteropCinteropNative") + } + } + } } \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/cinterop-with-def-creation-task/build.gradle.kts b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/cinterop-with-def-creation-task/build.gradle.kts new file mode 100644 index 00000000000..4452b0262e3 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/cinterop-with-def-creation-task/build.gradle.kts @@ -0,0 +1,27 @@ +plugins { + kotlin("multiplatform") +} + +repositories { + mavenCentral() + mavenLocal() +} + +val createDefFileTask = project.tasks.register("createDefFileTask", CreateDefFileTask::class) { + defFile.set(project.layout.buildDirectory.file(project.file("def/cinterop.def").absolutePath)) +} + +kotlin { + ("native") { + binaries { + executable() + } + compilations.getByName("main") { + cinterops { + val cinterop by creating { + definitionFile.set(createDefFileTask.flatMap { it.defFile }) + } + } + } + } +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/cinterop-with-def-creation-task/buildSrc/build.gradle.kts b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/cinterop-with-def-creation-task/buildSrc/build.gradle.kts new file mode 100644 index 00000000000..b22ed732fde --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/cinterop-with-def-creation-task/buildSrc/build.gradle.kts @@ -0,0 +1,7 @@ +plugins { + `kotlin-dsl` +} + +repositories { + mavenCentral() +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/cinterop-with-def-creation-task/buildSrc/src/main/kotlin/CreateDefFileTask.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/cinterop-with-def-creation-task/buildSrc/src/main/kotlin/CreateDefFileTask.kt new file mode 100644 index 00000000000..61799ecb302 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/cinterop-with-def-creation-task/buildSrc/src/main/kotlin/CreateDefFileTask.kt @@ -0,0 +1,9 @@ +import org.gradle.api.DefaultTask +import org.gradle.api.file.RegularFileProperty +import org.gradle.api.tasks.OutputFile + +abstract class CreateDefFileTask : DefaultTask() { + + @get:OutputFile + abstract val defFile: RegularFileProperty +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/cinterop-with-def-creation-task/def/cinterop.def b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/cinterop-with-def-creation-task/def/cinterop.def new file mode 100644 index 00000000000..a1b5b8314f4 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/cinterop-with-def-creation-task/def/cinterop.def @@ -0,0 +1,6 @@ +package = my.cinterop +--- + +static int foo() { + return 42; +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/CreateCInteropTasksSideEffect.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/CreateCInteropTasksSideEffect.kt index f2cf885e2eb..a0aea300aa6 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/CreateCInteropTasksSideEffect.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/CreateCInteropTasksSideEffect.kt @@ -45,6 +45,7 @@ internal val KotlinCreateNativeCInteropTasksSideEffect = KotlinCompilationSideEf "for compilation '${compilation.compilationName}'" + "of target '${it.konanTarget.name}'." it.enabled = compilation.konanTarget.enabledOnCurrentHost + it.definitionFile.set(params.settings.definitionFile) } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/DefaultCInteropSettings.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/DefaultCInteropSettings.kt index 9c32d539216..9732468557d 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/DefaultCInteropSettings.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/DefaultCInteropSettings.kt @@ -10,6 +10,7 @@ import org.gradle.api.Action import org.gradle.api.NamedDomainObjectFactory import org.gradle.api.file.FileCollection import org.gradle.api.file.ProjectLayout +import org.gradle.api.file.RegularFileProperty import org.gradle.api.internal.file.FileOperations import org.gradle.api.model.ObjectFactory import org.gradle.api.provider.ListProperty @@ -19,9 +20,8 @@ import org.jetbrains.kotlin.gradle.plugin.CInteropSettings import org.jetbrains.kotlin.gradle.plugin.CInteropSettings.IncludeDirectories import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation import org.jetbrains.kotlin.gradle.targets.native.internal.CInteropIdentifier -import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName -import org.jetbrains.kotlin.gradle.utils.newInstance -import org.jetbrains.kotlin.gradle.utils.property +import org.jetbrains.kotlin.gradle.utils.* +import org.jetbrains.kotlin.gradle.utils.getFile import org.jetbrains.kotlin.util.capitalizeDecapitalize.capitalizeAsciiOnly import java.io.File import javax.inject.Inject @@ -71,12 +71,19 @@ abstract class DefaultCInteropSettings @Inject internal constructor( val interopProcessingTaskName get() = params.interopProcessingTaskName - val defFileProperty: Property = params.services.objectFactory.property().value( + + @Deprecated("Deprecated. Please, use definitionFile.", ReplaceWith("definitionFile")) + val defFileProperty: Property = params.services.objectFactory.property().convention( params.services.projectLayout.projectDirectory.file("src/nativeInterop/cinterop/$name.def").asFile ) + val definitionFile: RegularFileProperty = params.services.objectFactory.fileProperty().convention( + params.services.projectLayout.file(defFileProperty) + ) + + @Deprecated("Deprecated because it is a non-lazy property.", ReplaceWith("definitionFile")) var defFile: File - get() = defFileProperty.get() + get() = definitionFile.getFile() set(value) { defFileProperty.set(value) } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/cocoapods/KotlinCocoapodsPlugin.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/cocoapods/KotlinCocoapodsPlugin.kt index 8c5cc0e9a8a..c64b62712a9 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/cocoapods/KotlinCocoapodsPlugin.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/cocoapods/KotlinCocoapodsPlugin.kt @@ -310,9 +310,13 @@ open class KotlinCocoapodsPlugin : Plugin { val defTask = project.registerTask( lowerCamelCaseName("generateDef", pod.moduleName).asValidTaskName() - ) { - it.pod.set(pod) - it.description = "Generates a def file for CocoaPods dependencies with module ${pod.moduleName}" + ) {task -> + task.pod.set(pod) + val defFileAbsolutePath = project.layout.cocoapodsBuildDirs.defs.map { + it.asFile.resolve("${task.pod.get().moduleName}.def").absolutePath + } + task.defFile.set(project.layout.projectDirectory.file(defFileAbsolutePath)) + task.description = "Generates a def file for CocoaPods dependencies with module ${pod.moduleName}" // This task is an implementation detail so we don't add it in any group // to avoid showing it in the `tasks` output. } @@ -325,14 +329,12 @@ open class KotlinCocoapodsPlugin : Plugin { interopTask.onlyIf { HostManager.hostIsMac } - interopTask.dependsOn(defTask) - pod.interopBindingDependencies.forEach { dependencyName -> addPodDependencyToInterop(project, cocoapodsExtension, pod, cinterops, interop, dependencyName) } with(interop) { - defFileProperty.set(defTask.flatMap { it.defFile.mapToFile() }) + defFileProperty.set(defTask.flatMap { it.defFile.asFile }) _packageNameProp.set(project.provider { pod.packageName }) _extraOptsProp.addAll(project.provider { pod.extraOpts }) } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/cocoapods/tasks/DefFileTask.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/cocoapods/tasks/DefFileTask.kt index e0db50f7bec..2fdae767b15 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/cocoapods/tasks/DefFileTask.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/cocoapods/tasks/DefFileTask.kt @@ -7,33 +7,29 @@ package org.jetbrains.kotlin.gradle.tasks import org.gradle.api.DefaultTask -import org.gradle.api.file.ProjectLayout -import org.gradle.api.file.RegularFile +import org.gradle.api.file.RegularFileProperty import org.gradle.api.provider.Property -import org.gradle.api.provider.Provider import org.gradle.api.tasks.Internal import org.gradle.api.tasks.Nested import org.gradle.api.tasks.OutputFile import org.gradle.api.tasks.TaskAction import org.gradle.work.DisableCachingByDefault import org.jetbrains.kotlin.gradle.plugin.cocoapods.CocoapodsExtension.CocoapodsDependency -import org.jetbrains.kotlin.gradle.plugin.cocoapods.cocoapodsBuildDirs import org.jetbrains.kotlin.gradle.utils.appendLine import org.jetbrains.kotlin.gradle.utils.getFile import java.io.File -import javax.inject.Inject /** * Generates a def-file for the given CocoaPods dependency. */ @DisableCachingByDefault -abstract class DefFileTask @Inject constructor(projectLayout: ProjectLayout) : DefaultTask() { +abstract class DefFileTask : DefaultTask() { @get:Nested abstract val pod: Property @get:OutputFile - val defFile: Provider = projectLayout.cocoapodsBuildDirs.defs.map { it.file("${pod.get().moduleName}.def") } + abstract val defFile: RegularFileProperty @get:Internal @Deprecated("Use `defFile` instead", replaceWith = ReplaceWith("defFile.get().asFile")) diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/KotlinNativeTasks.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/KotlinNativeTasks.kt index b6c1c68bb8b..deefa65e0c9 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/KotlinNativeTasks.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/KotlinNativeTasks.kt @@ -1094,7 +1094,15 @@ abstract class CInteropProcess @Inject internal constructor(params: Params) : @get:InputFile @get:PathSensitive(PathSensitivity.RELATIVE) @get:NormalizeLineEndings - val defFile: File get() = settings.defFileProperty.get() + abstract val definitionFile: RegularFileProperty + + @get:Internal + @Deprecated( + "This eager parameter is deprecated.", + replaceWith = ReplaceWith("definitionFile") + ) + val defFile: File get() = definitionFile.asFile.get() + @get:Optional @get:Input @@ -1147,7 +1155,7 @@ abstract class CInteropProcess @Inject internal constructor(params: Params) : addArg("-o", outputFile.absolutePath) addArgIfNotNull("-target", konanTarget.visibleName) - addArgIfNotNull("-def", defFile.canonicalPath) + addArgIfNotNull("-def", definitionFile.getFile().canonicalPath) addArgIfNotNull("-pkg", packageName) addFileArgs("-header", headers) diff --git a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/CInteropTaskTest.kt b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/CInteropTaskTest.kt index ce310fa0b3b..f7dc6ec00fb 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/CInteropTaskTest.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/CInteropTaskTest.kt @@ -10,6 +10,7 @@ package org.jetbrains.kotlin.gradle.unitTests import org.jetbrains.kotlin.gradle.util.MultiplatformExtensionTest import org.jetbrains.kotlin.gradle.plugin.mpp.DefaultCInteropSettings import org.jetbrains.kotlin.gradle.tasks.CInteropProcess +import org.jetbrains.kotlin.gradle.utils.getFile import kotlin.test.Test import kotlin.test.assertEquals @@ -48,7 +49,7 @@ class CInteropTaskTest : MultiplatformExtensionTest() { project.evaluate() assertEquals("updated-dependencyFile", cinteropTask.libraries.files.single().name) - assertEquals("updated-defFile", cinteropTask.defFile.name) + assertEquals("updated-defFile", cinteropTask.definitionFile.getFile().name) assertEquals("updated-packageName", cinteropTask.packageName) assertEquals(listOf("default-compilerOpts", "updated-compilerOpts"), cinteropTask.compilerOpts) assertEquals(listOf("default-linkerOpts", "updated-linkerOpts"), cinteropTask.linkerOpts)