From ccf03e51face7d423b5777e1da307b77b9b0c4b9 Mon Sep 17 00:00:00 2001 From: Ilya Matveev Date: Fri, 17 Nov 2017 19:15:20 +0700 Subject: [PATCH] gradle-plugin Use a script-block to specify include directories Replace headerFilterAdditionalSearchPrefix cinterop option with includeDir script block: includeDir { allHeaders 'path' // Used for all headers (an analogue of -I) // Used only for headers in headerFilter // (replacement for headerFilterAdditionalSearchPrefix) headerFilterOnly 'path' } --- samples/gitchurn/build.gradle | 4 +- samples/libcurl/build.gradle | 4 +- samples/videoplayer/build.gradle | 4 +- .../gradle/plugin/KonanInteropLibrary.kt | 30 +++++++--- .../kotlin/gradle/plugin/KonanSpecs.kt | 16 ++++-- .../gradle/plugin/tasks/KonanInteropTask.kt | 55 ++++++++++--------- .../test/IncrementalSpecification.groovy | 19 ++++--- .../plugin/test/TaskSpecification.groovy | 19 ++++--- 8 files changed, 90 insertions(+), 61 deletions(-) diff --git a/samples/gitchurn/build.gradle b/samples/gitchurn/build.gradle index bcd4722a043..9e115e0244a 100644 --- a/samples/gitchurn/build.gradle +++ b/samples/gitchurn/build.gradle @@ -5,11 +5,11 @@ konan.targets = ['macbook', 'linux'] konanArtifacts { interop('libgit2') { target('linux') { - headerFilterAdditionalSearchPrefix '/usr/include' + includeDirs.headerFilterOnly '/usr/include' } target('macbook') { - headerFilterAdditionalSearchPrefixes '/opt/local/include', '/usr/local/include' + includeDirs.headerFilterOnly '/opt/local/include', '/usr/local/include' } } diff --git a/samples/libcurl/build.gradle b/samples/libcurl/build.gradle index ce35f8ad931..e7c8700eeb6 100644 --- a/samples/libcurl/build.gradle +++ b/samples/libcurl/build.gradle @@ -5,10 +5,10 @@ konan.targets = ['macbook', 'linux'] konanArtifacts { interop('libcurl') { target('linux') { - headerFilterAdditionalSearchPrefixes '/usr/include' + includeDirs.headerFilterOnly '/usr/include' } target('macbook') { - headerFilterAdditionalSearchPrefixes '/opt/local/include', '/usr/local/include' + includeDirs.headerFilterOnly '/opt/local/include', '/usr/local/include' } } diff --git a/samples/videoplayer/build.gradle b/samples/videoplayer/build.gradle index 32fae9097f9..b294d3d4901 100644 --- a/samples/videoplayer/build.gradle +++ b/samples/videoplayer/build.gradle @@ -7,11 +7,11 @@ konanArtifacts { defFile 'src/main/c_interop/ffmpeg.def' target 'linux', { - headerFilterAdditionalSearchPrefixes '/usr/include', '/usr/include/x86_64-linux-gnu' + includeDirs.headerFilterOnly '/usr/include', '/usr/include/x86_64-linux-gnu' } target 'macbook', { - headerFilterAdditionalSearchPrefixes '/opt/local/include', '/usr/local/include' + includeDirs.headerFilterOnly '/opt/local/include', '/usr/local/include' } target 'mingw', { diff --git a/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanInteropLibrary.kt b/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanInteropLibrary.kt index 2e4681d20ef..6e2ac5a0f23 100644 --- a/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanInteropLibrary.kt +++ b/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanInteropLibrary.kt @@ -16,11 +16,15 @@ package org.jetbrains.kotlin.gradle.plugin +import groovy.lang.Closure +import org.gradle.api.Action import org.gradle.api.Task import org.gradle.api.file.FileCollection import org.gradle.api.internal.project.ProjectInternal import org.gradle.internal.reflect.Instantiator +import org.gradle.util.ConfigureUtil import org.jetbrains.kotlin.gradle.plugin.tasks.KonanInteropTask +import org.jetbrains.kotlin.gradle.plugin.KonanInteropSpec.IncludeDirectoriesSpec import org.jetbrains.kotlin.konan.target.KonanTarget import java.io.File @@ -41,6 +45,20 @@ open class KonanInteropLibrary(name: String, project: ProjectInternal, instantia // DSL + inner class IncludeDirectoriesSpecImpl: IncludeDirectoriesSpec { + override fun allHeaders(vararg includeDirs: Any) = allHeaders(includeDirs.toList()) + override fun allHeaders(includeDirs: Collection) = forEach { + it.includeDirs.allHeaders(includeDirs) + } + + override fun headerFilterOnly(vararg includeDirs: Any) = headerFilterOnly(includeDirs.toList()) + override fun headerFilterOnly(includeDirs: Collection) = forEach { + it.includeDirs.headerFilterOnly(includeDirs) + } + } + + val includeDirs = IncludeDirectoriesSpecImpl() + override fun defFile(file: Any) = forEach { it.defFile(file) } override fun packageName(value: String) = forEach { it.packageName(value) } @@ -52,6 +70,9 @@ open class KonanInteropLibrary(name: String, project: ProjectInternal, instantia override fun headers(files: FileCollection) = forEach { it.headers(files) } override fun includeDirs(vararg values: Any) = forEach { it.includeDirs(*values) } + override fun includeDirs(closure: Closure) = includeDirs(ConfigureUtil.configureUsing(closure)) + override fun includeDirs(action: Action) = includeDirs { action.execute(this) } + override fun includeDirs(configure: IncludeDirectoriesSpec.() -> Unit) = includeDirs.configure() override fun linkerOpts(values: List) = forEach { it.linkerOpts(values) } override fun linkerOpts(vararg values: String) = linkerOpts(values.toList()) @@ -59,13 +80,4 @@ open class KonanInteropLibrary(name: String, project: ProjectInternal, instantia override fun link(vararg files: Any) = forEach { it.link(*files) } override fun link(files: FileCollection) = forEach { it.link(files) } - override fun headerFilterAdditionalSearchPrefix(path: Any) = - forEach { it.headerFilterAdditionalSearchPrefix(path) } - - override fun headerFilterAdditionalSearchPrefixes(vararg paths: Any) = - headerFilterAdditionalSearchPrefixes(paths.toList()) - - override fun headerFilterAdditionalSearchPrefixes(paths: Collection) = - forEach { it.headerFilterAdditionalSearchPrefix(paths) } - } \ No newline at end of file diff --git a/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanSpecs.kt b/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanSpecs.kt index f261046ac8c..5f47f8fe39a 100644 --- a/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanSpecs.kt +++ b/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanSpecs.kt @@ -69,6 +69,14 @@ interface KonanCompileSpec: KonanBuildingSpec { interface KonanInteropSpec: KonanBuildingSpec { + interface IncludeDirectoriesSpec { + fun allHeaders(vararg includeDirs: Any) + fun allHeaders(includeDirs: Collection) + + fun headerFilterOnly(vararg includeDirs: Any) + fun headerFilterOnly(includeDirs: Collection) + } + fun defFile(file: Any) fun packageName(value: String) @@ -81,13 +89,13 @@ interface KonanInteropSpec: KonanBuildingSpec { fun includeDirs(vararg values: Any) + fun includeDirs(closure: Closure) + fun includeDirs(action: Action) + fun includeDirs(configure: IncludeDirectoriesSpec.() -> Unit) + fun linkerOpts(vararg values: String) fun linkerOpts(values: List) fun link(vararg files: Any) fun link(files: FileCollection) - - fun headerFilterAdditionalSearchPrefix(path: Any) - fun headerFilterAdditionalSearchPrefixes(vararg paths: Any) - fun headerFilterAdditionalSearchPrefixes(paths: Collection) } \ No newline at end of file diff --git a/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/tasks/KonanInteropTask.kt b/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/tasks/KonanInteropTask.kt index 5f5f55ba484..b1a5ba5aa56 100644 --- a/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/tasks/KonanInteropTask.kt +++ b/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/tasks/KonanInteropTask.kt @@ -16,10 +16,13 @@ package org.jetbrains.kotlin.gradle.plugin.tasks -import org.gradle.api.InvalidUserDataException +import groovy.lang.Closure +import org.gradle.api.Action import org.gradle.api.file.FileCollection import org.gradle.api.tasks.* +import org.gradle.util.ConfigureUtil import org.jetbrains.kotlin.gradle.plugin.* +import org.jetbrains.kotlin.gradle.plugin.KonanInteropSpec.IncludeDirectoriesSpec import org.jetbrains.kotlin.konan.target.KonanTarget import java.io.File @@ -49,11 +52,11 @@ open class KonanInteropTask: KonanBuildingTask(), KonanInteropSpec { @Input val compilerOpts = mutableListOf() @Input val linkerOpts = mutableListOf() + @Nested val includeDirs = IncludeDirectoriesSpecImpl() + @InputFiles val headers = mutableSetOf() @InputFiles val linkFiles = mutableSetOf() - @Input val headerFilterAdditionalSearchDirectories = mutableSetOf() - override fun buildArgs() = mutableListOf().apply { addArg("-properties", "${project.konanHome}/konan/konan.properties") @@ -77,6 +80,9 @@ open class KonanInteropTask: KonanBuildingTask(), KonanInteropSpec { addArg("-lopt", it) } + addArgs("-copt", includeDirs.allHeadersDirs.map { "-I${it.absolutePath}" }) + addArgs("-headerFilterAdditionalSearchPrefix", includeDirs.headerFilterDirs.map { it.absolutePath }) + addArgs("-repo", libraries.repos.map { it.canonicalPath }) addFileArgs("-library", libraries.files) @@ -85,20 +91,26 @@ open class KonanInteropTask: KonanBuildingTask(), KonanInteropSpec { addKey("-nodefaultlibs", noDefaultLibs) - addArgs("-headerFilterAdditionalSearchPrefix", - headerFilterAdditionalSearchDirectories.map { - if (!it.isDirectory) { - throw InvalidUserDataException("headerFilterAdditionalSearchPrefix must be a directory: $it") - } - it.absolutePath - } - ) - addAll(extraOpts) } // region DSL. + inner class IncludeDirectoriesSpecImpl: IncludeDirectoriesSpec { + @Input val allHeadersDirs = mutableSetOf() + @Input val headerFilterDirs = mutableSetOf() + + override fun allHeaders(vararg includeDirs: Any) = allHeaders(includeDirs.toList()) + override fun allHeaders(includeDirs: Collection) { + allHeadersDirs.addAll(includeDirs.map { project.file(it) }) + } + + override fun headerFilterOnly(vararg includeDirs: Any) = headerFilterOnly(includeDirs.toList()) + override fun headerFilterOnly(includeDirs: Collection) { + headerFilterDirs.addAll(includeDirs.map { project.file(it) }) + } + } + override fun defFile(file: Any) { defFile = project.file(file) } @@ -119,9 +131,11 @@ open class KonanInteropTask: KonanBuildingTask(), KonanInteropSpec { headers.add(files) } - override fun includeDirs(vararg values: Any) { - compilerOpts.addAll(values.map { "-I${project.file(it).canonicalPath}" }) - } + override fun includeDirs(vararg values: Any) = includeDirs.allHeaders(values.toList()) + + override fun includeDirs(closure: Closure) = includeDirs(ConfigureUtil.configureUsing(closure)) + override fun includeDirs(action: Action) = includeDirs { action.execute(this) } + override fun includeDirs(configure: IncludeDirectoriesSpec.() -> Unit) = includeDirs.configure() override fun linkerOpts(vararg values: String) = linkerOpts(values.toList()) override fun linkerOpts(values: List) { @@ -135,17 +149,6 @@ open class KonanInteropTask: KonanBuildingTask(), KonanInteropSpec { linkFiles.add(files) } - override fun headerFilterAdditionalSearchPrefix(path: Any) { - headerFilterAdditionalSearchDirectories.add(project.file(path)) - } - - override fun headerFilterAdditionalSearchPrefixes(vararg paths: Any) = - headerFilterAdditionalSearchPrefixes(paths.toList()) - - override fun headerFilterAdditionalSearchPrefixes(paths: Collection) = paths.forEach { - headerFilterAdditionalSearchPrefix(it) - } - // endregion } diff --git a/tools/kotlin-native-gradle-plugin/src/test/groovy/org/jetbrains/kotlin/gradle/plugin/test/IncrementalSpecification.groovy b/tools/kotlin-native-gradle-plugin/src/test/groovy/org/jetbrains/kotlin/gradle/plugin/test/IncrementalSpecification.groovy index 5efb6661054..fd09fa825f3 100644 --- a/tools/kotlin-native-gradle-plugin/src/test/groovy/org/jetbrains/kotlin/gradle/plugin/test/IncrementalSpecification.groovy +++ b/tools/kotlin-native-gradle-plugin/src/test/groovy/org/jetbrains/kotlin/gradle/plugin/test/IncrementalSpecification.groovy @@ -187,22 +187,23 @@ class IncrementalSpecification extends BaseKonanSpecification { recompilationAndInteropProcessingHappened(*results) where: - parameter | value - "packageName" | "'org.sample'" - "compilerOpts" | "'-g'" - "linkerOpts" | "'--help'" - "includeDirs" | "'src'" - "extraOpts" | "'-shims', 'false'" - "noDefaultLibs" | "true" + parameter | value + "packageName" | "'org.sample'" + "compilerOpts" | "'-g'" + "linkerOpts" | "'--help'" + "includeDirs" | "'src'" + "includeDirs.allHeaders" | "'src'" + "extraOpts" | "'-shims', 'false'" + "noDefaultLibs" | "true" } - def 'headerFilterAdditionalSearchPrefix change should cause recompilation and interop reprocessing'() { + def 'includeDirs.headerFilterOnly change should cause recompilation and interop reprocessing'() { when: def project = KonanProject.createWithInterop(projectDirectory) { KonanProject it -> it.defFiles.first().write("headers = stdio.h\nheaderFilter = stdio.h") } def results = buildTwice(project) { KonanProject it -> - it.addSetting(KonanProject.DEFAULT_INTEROP_NAME, "headerFilterAdditionalSearchPrefix", "'.'") + it.addSetting(KonanProject.DEFAULT_INTEROP_NAME, "includeDirs.headerFilterOnly", "'.'") } then: diff --git a/tools/kotlin-native-gradle-plugin/src/test/groovy/org/jetbrains/kotlin/gradle/plugin/test/TaskSpecification.groovy b/tools/kotlin-native-gradle-plugin/src/test/groovy/org/jetbrains/kotlin/gradle/plugin/test/TaskSpecification.groovy index 34ef565ab6a..31bbb5e8ed5 100644 --- a/tools/kotlin-native-gradle-plugin/src/test/groovy/org/jetbrains/kotlin/gradle/plugin/test/TaskSpecification.groovy +++ b/tools/kotlin-native-gradle-plugin/src/test/groovy/org/jetbrains/kotlin/gradle/plugin/test/TaskSpecification.groovy @@ -2,6 +2,7 @@ package org.jetbrains.kotlin.gradle.plugin.test import org.gradle.testkit.runner.BuildResult import org.gradle.testkit.runner.TaskOutcome +import spock.lang.Unroll class TaskSpecification extends BaseKonanSpecification { @@ -34,20 +35,24 @@ class TaskSpecification extends BaseKonanSpecification { result.output.findAll(~/BACKEND:\s+\d+\s+msec/).size() == 1 } - def 'Plugin should support headerFilterAdditionalSearchPrefix option for cinterop'() { + @Unroll('Plugin should support #option option for cinterop') + def 'Plugin should support includeDir option for cinterop'() { expect: def project = KonanProject.createEmpty(projectDirectory) { KonanProject it -> - it.addCompilerArtifact("interopLib", "headers=foo.h\nheaderFilter=foo.h bar.h", ArtifactType.INTEROP) + it.addCompilerArtifact("interopLib", "headers=foo.h\n$headerFilter", ArtifactType.INTEROP) it.generateSrcFile(it.projectPath, "foo.h", "#include ") def fooDir = it.projectPath.resolve("foo") it.generateSrcFile(fooDir, "bar.h", "const int foo = 5;") - it.addSetting("interopLib", "headerFilterAdditionalSearchPrefix", fooDir.toFile()) - it.addSetting("interopLib", "headerFilterAdditionalSearchPrefix", it.projectDir) + it.addSetting("interopLib", option, fooDir.toFile()) + it.addSetting("interopLib", option, it.projectDir) } project.createRunner().withArguments("build").build() - def wrong_path = project.createFile("wrong_path", "") - project.addSetting("interopLib", "headerFilterAdditionalSearchPrefix", wrong_path) - project.createRunner().withArguments("build").buildAndFail() + + where: + option | headerFilter + "includeDirs.headerFilterOnly" | "headerFilter=foo.h bar.h" + "includeDirs.allHeaders" | "" + "includeDirs" | "" } BuildResult failOnPropertyAccess(KonanProject project, String property) {