Skip to content

Latest commit

 

History

History
304 lines (227 loc) · 13.1 KB

GRADLE_PLUGIN.md

File metadata and controls

304 lines (227 loc) · 13.1 KB

Kotlin/Native Gradle plugin

Note: The new processInteropNameInterop task is used for interop processing instead of the old ones (genInteropNameInteropStubs and compileInteropNameInteropStubs, see Tasks)

Overview

You may use the Gradle plugin to build Kotlin/Native projects. To use it you need to include the following snippet in a build script (see projects in samples directory):

buildscript {
   repositories {
       mavenCentral()
       maven {
           url  "https://dl.bintray.com/jetbrains/kotlin-native-dependencies"
       }
   }

   dependencies {
       classpath "org.jetbrains.kotlin:kotlin-native-gradle-plugin:0.3"
   }
}

apply plugin: 'konan'

The plugin downloads the compiler during its first run. You may specify a version of the compiler using konan.version project property:

konan.version=0.3

If you already downloaded the compiler manually you may specify the path to its root directory using konan.home project property (e.g. in gradle.properties). Note: the plugin ignores the konan.version property in this case.

konan.home=/home/user/kotlin-native-0.3

In this case the compiler will not be downloaded by the plugin.

To use the plugin you need to define artifacts you want to build in the konanArtifacts block. Here you can specify source files and compilation parameters (e.g. a target platform) for each artifact (see Plugin DSL section below for details). The plugin uses src/main/kotlin/ as a default directory for sources.

konanArtifacts {
   foo {
       inputFiles fileTree('foo/src')
   }

   bar {
       inputFiles fileTree('bar/src')
       target iphone
   }
}

Using C interop

Kotlin/Native provides an easy interaction with native C libraries. The detailed description of this mechanism can be found in INTEROP.md while this section describes how to use Gradle to build Kotlin/Native apps using C libraries.

All the C libraies used should be defined in konanInterop block.

konanInterop {
   stdio {
       defFile 'stdio.def'
   }
}

Each element (interop) in this block corresponds to some native library described by a def-file (see INTEROP.md to read more about def-files). The default path to the def-file of an interop is src/main/c_interop/<interop-name>.def.

Each library is processed by the cinterop tool (see INTEROP.md for details). 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 section below for available parameters.

To build an artifact using an interop add useInterop command in the artifact section:

konanArtifacts {
   CsvParser {
       inputFiles project.file('CsvParser.kt')
       useInterop 'stdio'
   }
}

You also can use an interop from another project:

evaluationDependsOn 'anotherProject'

konanArtifacts {
   Foo {
       useInterop project('anotherProject').konanInterop['someInterop']
   }
}            

Additional options

You can also pass additional command line keys to the compiler or cinterop tool using the extraOpts expression 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'
    }
}

Any command line key supported by the according tool (compiler or cinterop) can be used. Some of them are listed in the tables below.

Compiler additional options
Key Description
--disable <Phase> Disable backend phase
--enable <Phase> Enable backend phase
--list_phases List all backend phases
--time Report execution time for compiler phases
--verbose <Phase> Trace phase execution
-verbose Enable verbose logging output
Cinterop additional options
Key Description
-verbose <boolean> Increase verbosity
-shims <boolean> Add generation of shims tracing native library calls

Tasks

The Kotlin/Native plugin creates the following tasks:

  • compileKonanArtifactName. The plugin creates such a task for each an artifact defined in a konanArtifacts block. You may get this task using the compilationTask property of an artifact or by its name:

    // The task name is "compileKonanFoo"
    konanArtifacts['foo'].compilationTask
    

    Such a task compiles its artifact and has the following properties accessible from a build script:

    Property Type Description
    outputDir File Directory to place the output artifact
    artifact File The output artifact
    artifactPath String Absolute path to the artifact
    produce String Kind of the artifact (executable, klib or bitcode)
    inputFiles Collection<FileCollection> Compiled files
    libraries Collection<FileCollection> *.klib libraries used by the artifact
    nativeLibraries Collection<FileCollection> *.bc libraries used by the artifact
    interops Collection<Interop> All the interops used by the artifact
    linkerOpts List<String> Additional options passed to the linker
    enableDebug boolean Is the debugging support enabled
    noStdLib boolean Is the artifact not linked with stdlib
    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
  • processInteropNameInterop. The plugin creates such a task for each an interop defined in a konanInterop block. You may get this task using interopProcessingTask property of an interop object or by its name:

    // The task name is "processFooInterop"
    konanInterop['foo']. interopProcessingTask
    

    Such a task processes the library defined by the interop and creates a *.klib for it. The task has the following properties accessible from a build script:

    Property Type Description
    outputDir File An output directory for the *.klib built
    klib File The *.klib built
    defFile File Def-file used by the interop
    compilerOpts List<String> Additional options passed to clang
    linkerOpts List<String> Additional options passed to a linker
    headers Collection<FileCollection> Additional headers used for stub generation
    linkFiles Collection<FileCollection> Additional files linked with the stubs
    measureTime boolean Does the compiler print phase time for stubs compilation

    Note: In versions before 0.3.4 two tasks for each an interop were used: genInteropNameInteropStubs and compileInteropNameInteropStubs. Now actions of both of them are performed by the processInteropNameInterop task described above.

  • compileKonan. This task is dependent on all compilation tasks and allows one to build all the artifacts supported by the current host. The task has no properties to use by a build script.

  • run. This task builds and runs all the executable artifacts supported by the current host. Additional run parameters can be passed using the runArgs project property:

    ./gradlew run -PrunArgs='foo bar'
    

    The task has no properties to use by a build script.

The plugin also edits the default build and clean tasks so that the first one allows one to build all the artifacts supported (it's dependent on the compileKonan task) and the second one removes the files created by the Kotlin/Native build.

Task graph

A task dependency structure is simple. Consider a following project:

konanArtifacts {
    fooArtifact { useInterop 'foo' ... }
    barArtifact { useInterop 'bar' ... }
}
 
 konanInterop {
    foo { ... }
    bar { ... }
 }

For this project the task graph will be the following:

run
    build
        compileKonan
            compileKonanFooArtifact
                processFooInterop
            compileKonanBarArtifact
                processBarInterop
clean

Plugin DSL

 konanArtifacts {
     artifactName {
         // Source files
         inputFiles project.fileTree('src')

         // Directory for output artifact (default: build/konan/bin/<artifactName>).
         outputDir 'path/to/output/dir'

         // *.klib library for linking.
         library project.file('path/to/library')
         
         // library project
         library project(':lib')
         
         // artifect in a library project
         library(project(':lib'), 'artefactName')

         // naitve library for linking.
         nativeLibrary project.file('path/to/native/library/')

         // Produce either a 'program' or a 'library' or a bare 'bitcode'.
         produce 'library'     

         noStdLib()            // Don't link with stdlib.
         enableOptimization()  // Enable compiler optimizations.
         enableAssertions()    // Enable assertions in binaries generated.
         enableDebug()         // Enable debugging for binaries generated.

         // Arguments to be passed to a linker.
         linkerOpts 'Some linker opts'

         // Target platform. Available values: "macbook", "linux", "iphone", "raspberrypi".
         target 'macbook'

         // Language and API version.
         languageVersion 'version'
         apiVersion 'version'

         // Native interop to use in the artifact.
         useInterop "interopName"
         
         // Print all parameters during the build.
         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
         
         // Pass additional command line options to the compiler.
         extraOpts '--time', '--verbose', 'linker'
    }
 }

 konanInterop {
     interopName {
         defFile project.file("deffile.def")                    // Def-file for stub generation.
         pkg 'org.sample'                                       // Package to place stubs generated.
         target 'macbook'                                       // Target platform.

         // Options to be passed to compiler and linker by cinterop tool.
         compilerOpts 'Options for native stubs compilation'
         linkerOpts 'Options for native stubs'

         headers project.files('header1.h', 'header2.h')       // Additional headers to parse.
         includeDirs "include/directory" "another/directory"   // Directories to look for headers.

         link <files which will be linked with native stubs>   // Additional files to link with native stubs.
         
         dumpParameters true                                   // Print all parameters during the build. 
                                           
         // Add the `anotherTask` to the stub generation task dependencies.
         dependsOn anotherTask
         
         // Pass additional command line options to the cinterop tool.
         extraOpts '-shims', 'true'
     }
 }