From 8957320504fcc9d04dd2da2a13a7d972c3588529 Mon Sep 17 00:00:00 2001 From: Ilya Matveev Date: Thu, 24 Aug 2017 13:28:16 +0700 Subject: [PATCH] gradle-plugin: Allow compile time measurement --- GRADLE_PLUGIN.md | 58 +++++++++++++------ .../kotlin/gradle/plugin/KonanCompileTask.kt | 7 +++ .../kotlin/gradle/plugin/KonanInteropTask.kt | 6 +- .../plugin/test/TaskSpecification.groovy | 27 +++++++++ 4 files changed, 78 insertions(+), 20 deletions(-) diff --git a/GRADLE_PLUGIN.md b/GRADLE_PLUGIN.md index 467f645d207..c25cf2d267e 100644 --- a/GRADLE_PLUGIN.md +++ b/GRADLE_PLUGIN.md @@ -67,12 +67,24 @@ Each element (interop) in this block corresponds to some native library describe Each interop is processed by the plugin in two steps: -1. Stub generation. In this step the plugin uses `cinterop` tool to generate Kotlin and bitcode (*.bc) stubs for the +1. **Stub generation.** In this step the plugin uses `cinterop` tool to generate Kotlin and bitcode (*.bc) stubs for the library. You can specify additional parameters for this tool in the interop block (e.g. a custom def-file is specified in the example above). See [**Plugin DSL**](#plugin-dsl) section below for available parameters and [`INTEROP.md`](INTEROP.md) for `cinterop` tool description. -2. Stub compilation. In this step the plugin uses Kotlin/Native compiler to compile the stubs generated by the step (1) +2. **Stub compilation.** In this step the plugin uses Kotlin/Native compiler to compile the stubs generated by the step (1) into a klib which can be linked with a Kotlin/Native application. +Usually there is no need to specify additional compilation options for this stage. But if for some reason you need to do +it, you can use `compileStubsConfig` property of an interop. This property provides an access to a `KonanCompileConfig` +object containing the same methods as an artifact in the `konanArtifacts` block. E.g. this sample enables time measurement +for compilation of stubs: + + ``` + konanInterop { + stdio { + compileStubsConfig.measureTime true + } + } + ``` To build some artifact with an interop add `useInterop` command in the artifact section: @@ -99,11 +111,11 @@ You can also pass additional command line keys to the compiler or cinterop tool available an artifact or interop block. For example this sample enables a verbose output for a link and bitcode generation stages and prints execution time for all compiler phases: - konanArtifacts - foo { - extraOpts '--verbose', 'linker', '--verbose', 'bitcode', '--time' - } - } + konanArtifacts + foo { + extraOpts '--verbose', 'linker', '--verbose', 'bitcode', '--time' + } + } Any command line key supported by the according tool (compiler or cinterop) can be used. Some of them are listed in the tables below. @@ -154,6 +166,7 @@ You may get this task using the `compilationTask` property of an artifact or by |`noMain `|`boolean` |Is the `main` function provided by a library used | |`enableOptimization`|`boolean` |Is the optimization enabled | |`enableAssertions `|`boolean` |Is the assertion support enabled | + |`measureTime `|`boolean` |Does the compiler print phase time | * __gen*InteropName*InteropStubs__. The plugin creates such a task for each an interop defined in a `konanInterop` block. You may get this task using `generateStubsTask` property of an interop object or by its name: @@ -166,15 +179,16 @@ You may get this task using `generateStubsTask` property of an interop object or Such a task generates stubs for the library defined by the interop and has the following properties accessible from a build script - |Property |Type |Description | - |-------------- |----------------------------|--------------------------------------------------| - |`stubsDir `|`File` |An output directory for the Kotlin stubs generated| - |`libsDir `|`File` |An output directory for the compiled stubs | - |`defFile `|`File` |Def-file used by the interop | - |`compilerOpts `|`List` |Additional options passed to clang | - |`linkerOpts `|`List` |Additional options passed to a linker | - |`headers `|`Collection`|Additional headers used for stub generation | - |`linkFiles `|`Collection`|Additional files linked with the stubs | + |Property |Type |Description | + |-------------- |----------------------------|--------------------------------------------------------| + |`stubsDir `|`File` |An output directory for the Kotlin stubs generated | + |`libsDir `|`File` |An output directory for the compiled stubs | + |`defFile `|`File` |Def-file used by the interop | + |`compilerOpts `|`List` |Additional options passed to clang | + |`linkerOpts `|`List` |Additional options passed to a linker | + |`headers `|`Collection`|Additional headers used for stub generation | + |`linkFiles `|`Collection`|Additional files linked with the stubs | + |`measureTime `|`boolean` |Does the compiler print phase time for stubs compilation| * __compile*InteropName*InteropStubs__. The plugin creates such a task for each interop defined in a `konanInterop` block. You may get this task using `compileStubsTask` property of an interop object or by its name: @@ -271,7 +285,10 @@ For this project the task graph will be the following: useInterop "interopName" // Print all parameters during the build. - dumpParameters(true) + dumpParameters true + + // Print time of compilation phases (equivalent of the `--time` command line option). + measureTime true // Add the `anotherTask` to the compilation task dependencies. dependsOn anotherTask @@ -294,10 +311,13 @@ For this project the task graph will be the following: headers project.files('header1.h', 'header2.h') // Additional headers to parse. includeDirs "include/directory" "another/directory" // Directories to look for headers. - link // Additional files to link with native stubs. + link // Additional files to link with native stubs. - dumpParameters(true) // Print all parameters during the build. + dumpParameters true // Print all parameters during the build. + // Print time of stub compilation phases (equivalent of the `--time` command line option). + measureTime true + // Add the `anotherTask` to the stub generation task dependencies. dependsOn anotherTask diff --git a/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanCompileTask.kt b/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanCompileTask.kt index 2bf0a0930cd..81c4e99c1dc 100644 --- a/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanCompileTask.kt +++ b/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanCompileTask.kt @@ -95,6 +95,8 @@ open class KonanCompileTask: KonanTargetableTask() { internal set @Input var enableAssertions = false internal set + @Console var measureTime = false + internal set @Optional @Input var languageVersion : String? = null internal set @@ -130,6 +132,7 @@ open class KonanCompileTask: KonanTargetableTask() { addKey("-nomain", noMain) addKey("-opt", enableOptimization) addKey("-ea", enableAssertions) + addKey("--time", measureTime) addAll(extraOpts) @@ -286,6 +289,10 @@ open class KonanCompileConfig( enableAssertions = true } + fun measureTime(value: Boolean) = with(compilationTask) { + measureTime = value + } + fun dumpParameters(value: Boolean) = with(compilationTask) { dumpParameters = value } diff --git a/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanInteropTask.kt b/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanInteropTask.kt index 357a50ddad9..4c677632282 100644 --- a/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanInteropTask.kt +++ b/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanInteropTask.kt @@ -66,7 +66,9 @@ open class KonanInteropTask: KonanTargetableTask() { @Optional @Input var manifest: String? = null internal set - @Input var dumpParameters: Boolean = false + @Input var dumpParameters = false + internal set + @Input val compilerOpts = mutableListOf() @Input val linkerOpts = mutableListOf() @Input val extraOpts = mutableListOf() @@ -207,6 +209,8 @@ open class KonanInteropConfig( compileStubsTask.dumpParameters = value } + fun measureTime(value: Boolean) = compileStubsConfig.measureTime(value) + fun dependsOn(dependency: Any) = generateStubsTask.dependsOn(dependency) fun extraOpts(vararg values: Any) = extraOpts(values.asList()) 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 e38f8cbcf71..237dd854a06 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 @@ -82,4 +82,31 @@ class TaskSpecification extends BaseKonanSpecification { result.output.contains("[-lpthread]$ls[$expectedKlibPath]$ls[$expectedBcPath]".stripIndent().trim()) } + def 'Compiler should print time measurements if measureTime flag is set'() { + when: + def project = KonanInteropProject.createEmpty(projectDirectory) + project.generateSrcFile("main.kt") + project.addInteropSetting("measureTime", "true") + project.addCompilationSetting("measureTime", "true") + def result = project.createRunner().withArguments('build').build() + + then: + result.output.findAll(~/FRONTEND:\s+\d+\s+msec/).size() == 2 + result.output.findAll(~/BACKEND:\s+\d+\s+msec/).size() == 2 + result.output.findAll(~/LINK_STAGE:\s+\d+\s+msec/).size() == 1 + } + + def 'Interop should provide access to stub compilation config'() { + when: + def project = KonanInteropProject.createEmpty(projectDirectory) + project.generateSrcFile("main.kt") + project.addInteropSetting("compileStubsConfig.measureTime", "true") + def result = project.createRunner().withArguments('build').build() + + then: + result.output.findAll(~/FRONTEND:\s+\d+\s+msec/).size() == 1 + result.output.findAll(~/BACKEND:\s+\d+\s+msec/).size() == 1 + result.output.findAll(~/LINK_STAGE:\s+\d+\s+msec/).size() == 0 + } + }