From cef46a9dd1cd6664ff4583d109def6653d12d03d Mon Sep 17 00:00:00 2001 From: Dmitrii Krasnov Date: Wed, 13 Dec 2023 17:52:21 +0100 Subject: [PATCH] [Gradle Native] Made definitionFile Optional for cinterop task ^KT-62800 Fixed --- .../kotlin/gradle/native/CinteropIT.kt | 63 +++++++++++++++++++ .../native/NativeIncrementalCompilationIT.kt | 2 +- .../cinterop-with-header/build.gradle.kts | 25 ++++++++ .../cinterop-with-header/libs/include/dummy.h | 1 + .../src/nativeMain/kotlin/nativeMain.kt | 8 +++ .../targets/native/DefaultCInteropSettings.kt | 8 ++- .../targets/native/tasks/KotlinNativeTasks.kt | 5 +- 7 files changed, 107 insertions(+), 5 deletions(-) create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/cinterop-with-header/build.gradle.kts create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/cinterop-with-header/libs/include/dummy.h create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/cinterop-with-header/src/nativeMain/kotlin/nativeMain.kt 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 79e376b9ae5..55ee16f5914 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 @@ -9,6 +9,8 @@ import org.gradle.util.GradleVersion import org.jetbrains.kotlin.gradle.testbase.* import org.junit.jupiter.api.DisplayName import org.junit.jupiter.api.condition.OS +import kotlin.io.path.createDirectories +import kotlin.io.path.createFile @NativeGradlePluginTests class CinteropIT : KGPBaseTest() { @@ -75,4 +77,65 @@ class CinteropIT : KGPBaseTest() { } } } + + @DisplayName("KT-62800: passing header to cinterop instead of passing def file") + @GradleTest + fun cinteropWithExplicitPassingHeader(gradleVersion: GradleVersion) { + nativeProject("cinterop-with-header", gradleVersion = gradleVersion) { + val dummyHeaderPath = projectPath.resolve("libs").resolve("include").resolve("dummy.h").toFile().canonicalPath + build(":assemble") { + assertTasksExecuted(":cinteropCinteropNative") + extractNativeTasksCommandLineArgumentsFromOutput(":cinteropCinteropNative", toolName = NativeToolKind.C_INTEROP) { + assertCommandLineArgumentsContainSequentially("-header", dummyHeaderPath) + assertCommandLineArgumentsContainSequentially("-Ilibs/include") + assertCommandLineArgumentsContainSequentially("-pkg", "cinterop") + assertCommandLineArgumentsDoNotContain("-def") + } + } + } + } + + @DisplayName("KT-62800: check that optional .def file in cinterop works well with configuration cache") + @GradleTestVersions(minVersion = TestVersions.Gradle.G_8_1) // Gradle supports checking file existence with configuration cache only since 8.1 version + @GradleTest + fun cinteropWithOptionalDefFileAndConfigurationCache(gradleVersion: GradleVersion) { + nativeProject( + "cinterop-with-header", + gradleVersion = gradleVersion, + buildOptions = defaultBuildOptions.copy( + configurationCache = true + ) + ) { + val dummyHeaderPath = projectPath.resolve("libs").resolve("include").resolve("dummy.h").toFile().canonicalPath + // first build with non-existing .def file and configuration cache enabled + build(":assemble") { + assertTasksExecuted(":cinteropCinteropNative") + extractNativeTasksCommandLineArgumentsFromOutput(":cinteropCinteropNative", toolName = NativeToolKind.C_INTEROP) { + assertCommandLineArgumentsContainSequentially("-header", dummyHeaderPath) + assertCommandLineArgumentsContainSequentially("-Ilibs/include") + assertCommandLineArgumentsContainSequentially("-pkg", "cinterop") + assertCommandLineArgumentsDoNotContain("-def") + } + } + + // adding cinterop.def to default path + val cinteropDefFile = projectPath.resolve("src") + .resolve("nativeInterop") + .resolve("cinterop") + .createDirectories() + .resolve("cinterop.def") + .createFile() + + // second build with existing .def file and configuration cache enabled + build(":assemble") { + assertTasksExecuted(":cinteropCinteropNative") + extractNativeTasksCommandLineArgumentsFromOutput(":cinteropCinteropNative", toolName = NativeToolKind.C_INTEROP) { + assertCommandLineArgumentsContainSequentially("-header", dummyHeaderPath) + assertCommandLineArgumentsContainSequentially("-Ilibs/include") + assertCommandLineArgumentsContainSequentially("-pkg", "cinterop") + assertCommandLineArgumentsContainSequentially("-def", cinteropDefFile.toFile().canonicalPath) + } + } + } + } } \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/native/NativeIncrementalCompilationIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/native/NativeIncrementalCompilationIT.kt index 84d88d5cde5..a494180718a 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/native/NativeIncrementalCompilationIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/native/NativeIncrementalCompilationIT.kt @@ -31,7 +31,7 @@ class NativeIncrementalCompilationIT : KGPBaseTest() { ) @DisplayName("KT-63742: Check that kotlinNativeLink task passes all required args for cache orchestration and ic") - @GradleTestVersions(minVersion = TestVersions.Gradle.G_7_4) // DefaultResolvedComponentResult is supported after 7.4 only + @GradleTestVersions(minVersion = TestVersions.Gradle.G_7_4) // DefaultResolvedComponentResult with configuration cache is supported only after 7.4 @GradleTest fun checkArgumentsForIncrementalCache(gradleVersion: GradleVersion) { nativeProject("native-incremental-simple", gradleVersion) { diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/cinterop-with-header/build.gradle.kts b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/cinterop-with-header/build.gradle.kts new file mode 100644 index 00000000000..0307fde994e --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/cinterop-with-header/build.gradle.kts @@ -0,0 +1,25 @@ +plugins { + kotlin("multiplatform") +} + +repositories { + mavenCentral() + mavenLocal() +} + +kotlin { + ("native") { + binaries { + executable() + } + compilations.getByName("main") { + cinterops { + val cinterop by creating { + headers("libs/include/dummy.h") + compilerOpts.add("-Ilibs/include") + packageName("cinterop") + } + } + } + } +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/cinterop-with-header/libs/include/dummy.h b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/cinterop-with-header/libs/include/dummy.h new file mode 100644 index 00000000000..8c2c1f0b6e0 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/cinterop-with-header/libs/include/dummy.h @@ -0,0 +1 @@ +void dummyFunction(); \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/cinterop-with-header/src/nativeMain/kotlin/nativeMain.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/cinterop-with-header/src/nativeMain/kotlin/nativeMain.kt new file mode 100644 index 00000000000..ab358deea93 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/cinterop-with-header/src/nativeMain/kotlin/nativeMain.kt @@ -0,0 +1,8 @@ +import cinterop.dummyFunction + +@OptIn(kotlinx.cinterop.ExperimentalForeignApi::class) +fun nativeMainUsingCInterop() = dummyFunction() + +fun main() { + +} \ No newline at end of file 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 9732468557d..1c9e3568d14 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 @@ -27,7 +27,7 @@ import java.io.File import javax.inject.Inject abstract class DefaultCInteropSettings @Inject internal constructor( - private val params: Params + private val params: Params, ) : CInteropSettings { internal data class Params( @@ -35,7 +35,7 @@ abstract class DefaultCInteropSettings @Inject internal constructor( val identifier: CInteropIdentifier, val dependencyConfigurationName: String, val interopProcessingTaskName: String, - val services: Services + val services: Services, ) { open class Services @Inject constructor( val providerFactory: ProviderFactory, @@ -74,9 +74,11 @@ abstract class DefaultCInteropSettings @Inject internal constructor( @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 + getDefaultCinteropDefinitionFile().takeIf { it.exists() } ) + private fun getDefaultCinteropDefinitionFile(): File = params.services.projectLayout.projectDirectory.file("src/nativeInterop/cinterop/$name.def").asFile + val definitionFile: RegularFileProperty = params.services.objectFactory.fileProperty().convention( params.services.projectLayout.file(defFileProperty) ) 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 9e2496c324f..c30cd2e828c 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 @@ -1097,6 +1097,7 @@ abstract class CInteropProcess @Inject internal constructor(params: Params) : @get:InputFile @get:PathSensitive(PathSensitivity.RELATIVE) @get:NormalizeLineEndings + @get:Optional abstract val definitionFile: RegularFileProperty @get:Internal @@ -1158,7 +1159,9 @@ abstract class CInteropProcess @Inject internal constructor(params: Params) : addArg("-o", outputFile.absolutePath) addArgIfNotNull("-target", konanTarget.visibleName) - addArgIfNotNull("-def", definitionFile.getFile().canonicalPath) + if (definitionFile.isPresent) { + addArgIfNotNull("-def", definitionFile.getFile().canonicalPath) + } addArgIfNotNull("-pkg", packageName) addFileArgs("-header", headers)