diff --git a/GRADLE_PLUGIN.md b/GRADLE_PLUGIN.md index a60fdd59a06..5d277309bf6 100644 --- a/GRADLE_PLUGIN.md +++ b/GRADLE_PLUGIN.md @@ -1,10 +1,6 @@ # Kotlin/Native Gradle plugin -_Note: In the version 0.8 a new experimental plugin has been introduced. It is integrated with new Gradle support -for native languages and provides a new DSL which is much closer to the DSL of Kotlin/JVM and Kotlin/JS -plugins than the old one. The plugin is at an early stage so some things may be changed in upcoming releases. See -[this demo project](https://github.com/ilmat192/Kotlin-Native-Gradle-Experiments) or -[MPP http client](https://github.com/e5l/http-client-common/tree/master/samples/ios-test-application) for DSL example._ +_Note: For the experimental DSL see the [corresponding section](#experimental-plugin)_. ## Overview @@ -13,7 +9,7 @@ You may use the Gradle plugin to build _Kotlin/Native_ projects. Since version 0 using Gradle plugin DSL: plugins { - id "org.jetbrains.kotlin.konan" version "0.8" + id "org.jetbrains.kotlin.konan" version "0.9" } You also can get the plugin from a Bintray repository. In addition to releases, this repo contains old and development @@ -613,7 +609,7 @@ tables below. expectedBy project(':common') } -## Publishing to Maven. +## Publishing to Maven Publishing the Kotlin/Native artifacts depends on mechanisms which were introduced in Gradle Native support, e.g. Gradle's metadata feature. Thus some additional steps are required. First of all, the gradle version shouldn't be less @@ -648,3 +644,336 @@ platform x build types). To meet this requirement the Kotlin/Native plugin has f ```` In this example `name` and `description` tags will be added to each generated `pom` file for _libcurl_ published artifact. + +## Experimental plugin + + +In the version 0.8 a new experimental plugin has been introduced. It is integrated with new Gradle support +for native languages and provides a new DSL which is much closer to the DSL of Kotlin/JVM and Kotlin/JS +plugins than the old one. +The plugin available at Gradle plugin portal: + +``` +plugins { + id "org.jetbrains.kotlin.platform.native" version "0.9" +} +``` + +### Source management + +Source management in the `kotlin.platform.native` plugin is uniform with other Kotlin plugins and is based on source sets. Source set is a group of Kotlin/Native source which may contain both common and platform-specific code. The plugin provides a top-level script block `sourceSets` allowing one to configure source sets. Also it create default source sets `main` and `test` (for production and test code respectively). +By default the production sources are located in `src/main/kotlin` and the test sources - in `src/test/kotlin`. + +```` +sourceSets { + // Adding target-independent sources. + main.kotlin.srcDirs += 'src/main/mySources' + + // Adding Linux-specific code. It will be compiled in Linux binaries only. + main.target('linux_x64').srcDirs += 'src/main/linux' +} +```` + +### Targets and output kinds + +By default the plugin creates software components for main and test source sets. One can access them via `components` container provided by Gradle or via `component` property of a corresponding source set: + +```` +// Main component. +components.main +sourceSets.main.component + +// Test component. +components.test +sourceSets.test.component +```` + +Components allow one to specify: + +* targets (e.g. Linux/x64 or iOS/arm64 etc), +* output kinds (e.g. executable, library, framework etc), +* dependencies (including interop ones). + +Targets can be specified by setting a corresponding component property: + +```` +components.main { + // Compile this component for 64-bit MacOS, Linux and Windows. + targets = ['macos_x64', 'linux_x64', 'mingw_x64'] +} +```` + +The plugin uses the same notation as the compiler. By default test component uses the same targets as specified for the main one. + +Output kinds can also be specified using a special property: + +```` +components.main { + // Compile the component into an executable and a Kotlin/Native library. + outputKinds = [EXECUTABLE, KLIBRARY] +} +```` +All constants used here are available inside a component configuration script block. +The plugin supports producing binaries of the following kinds: + +* `EXECUTABLE` - an executable file; +* `KLIBRARY` - a Kotlin/Native library (*.klib); +* `FRAMEWORK` - an Objective-C framework; +* `DYNAMIC` - shared native library; +* `STATIC` - static native library. + +Also each binary is built in two variants (build types): `debug` (debuggable, not optimized) and `release` (not debuggable, optimized). + +### Compile tasks + +The plugin creates a compilation task for each combination of target, output kind and build type. The tasks has the following naming convention: + + compileKotlinNative + +For example `compileDebugKlibraryMacos_x64KotlinNative`, `compileTestDebugKotlinNative`. + +The name contains the following parts (some of them may be empty): + +* `` - name of a component. Empty for the main component. +* `` - `Debug` or `Release`. +* `` - output kind name, e.g. `Executabe` or `Dynamic`. Empty if the component has only one output kind. +* `` - target the component is built for, e.g. `Macos_x64` or `Wasm32`. Empty if the component is built only for one target. + +Also the plugin create number of aggregate tasks allowing one to build all binaries for some build type (e.g. +`assembleAllDebug`) or all binaries for a particular target (e.g. `assembleAllWasm32`). + +Basic lifecycle tasks like `assemble`, `build` and `clean` are also available. + +### Running tests + +The plugin builds a test executables for all targets specified for the `test` component. If the current host platform is +included in this list the test running tasks is also created. To run tests, execute the standard lifecycle `check` task: + + ./gradlew check + +### Dependencies + +The plugin allows one to declare dependencies on files and other projects using traditional Gradle's mechanism of +configurations. The plugin supports Kotlin multiplatform projects allowing one to declare `expectedBy` dependencies + +```` +dependencies { + implementation files('path/to/file/dependencies') + implementation project('library') + testImplementation project('testLibrary') + expectedBy project('common') +} +```` + +It's possible to depend on a Kotlin/Native library published earlier in a maven repo. The plugin relies on Gradle's +[metadata](https://github.com/gradle/gradle/blob/master/subprojects/docs/src/docs/design/gradle-module-metadata-specification.md) +support so the corresponding feature must be enabled. Add the following line in your `settings.gralde`: + +```` +enableFeaturePreview('GRADLE_METADATA') +```` + +Now you can declare a dependency on a Kotlin/Native library in the traditional `group:artifact:version` notation: + +```` +dependencies { + implementation 'org.sample.test:mylibrary:1.0' + testImplementation 'org.sample.test:testlibrary:1.0' +} +```` + +`implementation`-dependencies are also available in the component block: + +```` +components.main { + dependencies { + implementation 'org.sample.test:mylibrary:1.0' + } +} + +components.test { + dependencies { + implementation org.sample.test:testlibrary:1.0' + } +} +```` + + +### Using cinterop + +It's possible to declare a cinterop dependency for a component. The DSL here is similar to the one used in the `konan` plugin: + +```` +component.main { + dependencies { + cinterop('mystdio') { + // src/main/c_interop/mystdio.def is used as a def file. + + // Set up compiler options + compilerOpts '-I/my/include/path' + + // It's possible to set up different options for different targets + target('linux') { + compilerOpts '-I/linux/include/path' + } + } + } +} +```` + +Here an interop library will be built and added in the component dependencies. + +Often it's necessary to specify target-specific linker options for a Kotlin/Native binary using an interop. It can be +done using the `target` script block: + +```` +components.main { + target('linux') { + linkerOpts '-L/path/to/linux/libs' + } +} +```` + +Also the `allTargets` block is available + +```` +components.main { + // Configure all targets. + allTargets { + linkerOpts '-L/path/to/libs' + } +} +```` + +### Publishing + +In presence of `maven-publish` plugin publications for all the binaries built are created. The plugin uses Gradle +metadata to publish the artifacts so this feature must be enabled (see the [dependencies](#dependencies) section). + +Now one can publish the artifacts with the standard Gradle's `publish` task: + + ./gradlew publish + +Only `EXECUTABLE` and `KLIBRARY` binaries are published at the moment. + +The plugin allows one to customize the pom generated for the publication with the `pom` code block available for every component: + +```` +components.main { + pom { + withXml { + def root = asNode() + root.appendNode('name', 'My library') + root.appendNode('description', 'A Kotlin/Native library') + } + } +} +```` + +### DSL example + +In this section a commented DSL is shown. +See also projects using this plugin, e.g. +[Kotlinx.coroutines](https://github.com/Kotlin/kotlinx.coroutines), +[MPP http client](https://github.com/e5l/http-client-common/tree/master/samples/ios-test-application) + +```` +plugins { + id "org.jetbrains.kotlin.platform.native" version "0.9" +} + +sourceSets.main { + // Plugin uses Gradle's source directory sets here, + // so all the DSL methods available in SourceDirectorySet can be called here. + // Platform independent sources. + kotlin.srcDirs += 'src/main/customDir' + + // Linux-specific sources + target('linux').srcDirs += 'src/main/linux' +} + +component.main { + + // Set up targets + targets = ['linux_x64', 'macos_x64', 'mingw_x64'] + + // Set up output kinds + outputKinds = [EXECUTABLE, KLIBRARY, FRAMEWORK, DYNAMIC, STATIC] + + // Target-specific options + target('linux_x64') { + linkerOpts '-L/linux/lib/path' + } + + // Targets independent options + allTargets { + linkerOpts '-L/common/lib/path' + } + + dependnecies { + + // Dependency on a published Kotlin/Native library. + implementation 'org.test:mylib:1.0' + + // Dependency on a project + implementation project('library') + + // Cinterop dependency + cinterop('interop-name') { + // Def-file describing the native API. + // The default path is src/main/c_interop/.def + defFile project.file("deffile.def") + + // Package to place the Kotlin API generated. + packageName 'org.sample' + + // Options to be passed to compiler and linker by cinterop tool. + compilerOpts 'Options for native stubs compilation' + linkerOpts 'Options for native stubs' + + // Additional headers to parse. + headers project.files('header1.h', 'header2.h') + + // Directories to look for headers. + includeDirs { + // All objects accepted by the Project.file method may be used with both options. + + // Directories for header search (an analogue of the -I compiler option). + allHeaders 'path1', 'path2' + + // Additional directories to search headers listed in the 'headerFilter' def-file option. + // -headerFilterAdditionalSearchPrefix command line option analogue. + headerFilterOnly 'path1', 'path2' + } + // A shortcut for includeDirs.allHeaders. + includeDirs "include/directory" "another/directory" + + // Pass additional command line options to the cinterop tool. + extraOpts '-shims', 'true' + + // Additional configuration for Linux. + target('linux') { + compilerOpts 'Linux-specific options' + } + } + } + + // Additional pom settings for publication. + pom { + withXml { + def root = asNode() + root.appendNode('name', 'My library') + root.appendNode('description', 'A Kotlin/Native library') + } + } + + // Additional options passed to the compiler. + extraOpts '--time' +} +```` + + + + + + diff --git a/samples/csvparser/README.md b/samples/csvparser/README.md index 8bc0e9ac6cb..1987f9e8015 100644 --- a/samples/csvparser/README.md +++ b/samples/csvparser/README.md @@ -4,7 +4,7 @@ A sample data [European Mammals Red List for 2009](https://data.europa.eu/euodp/en/data/dataset?res_format=CSV) from EU is being used. -To build use `../gradlew build` or `./build.sh`. +To build use `../gradlew assemble` or `./build.sh`. Now you can run artifact directly diff --git a/samples/curl/README.md b/samples/curl/README.md index 7e7eb4334c6..632e68216a0 100644 --- a/samples/curl/README.md +++ b/samples/curl/README.md @@ -4,7 +4,7 @@ This example shows how to communicate with libcurl, HTTP/HTTPS/FTP/etc client li depend on an artifact published in a maven repository. The sample depends on a library built by [libcurl sample](../libcurl) so you need to run it first. -To build use `../gradlew build`. +To build use `../gradlew assemble`. Now you can run the client directly diff --git a/samples/gitchurn/README.md b/samples/gitchurn/README.md index 42e05f05e5d..941e02cecd9 100644 --- a/samples/gitchurn/README.md +++ b/samples/gitchurn/README.md @@ -3,7 +3,7 @@ This example shows how one could perform statistics on Git repository. libgit2 is required for this to work (`apt-get install libgit2-dev`). -To build use `../gradlew build` or `./build.sh`. +To build use `../gradlew assemble` or `./build.sh`. Now you can run the program directly diff --git a/samples/globalState/README.md b/samples/globalState/README.md index 52083045cce..fd8614482e7 100644 --- a/samples/globalState/README.md +++ b/samples/globalState/README.md @@ -2,7 +2,7 @@ This example shows how one could implement global shared state using interop mechanisms. -To build use `../gradlew build`. +To build use `../gradlew assemble`. To run use `./build/exe/main/release//globalState.kexe`. diff --git a/samples/gtk/README.md b/samples/gtk/README.md index c472bfaf8f6..f7dc2947f3a 100644 --- a/samples/gtk/README.md +++ b/samples/gtk/README.md @@ -3,7 +3,7 @@ This example shows how one may use _Kotlin/Native_ to build GUI applications with the GTK toolkit. -To build use `../gradlew build` or `./build.sh [-I=/include/path]`. +To build use `../gradlew assemble` or `./build.sh [-I=/include/path]`. Do not forget to install GTK3. See bellow. diff --git a/samples/libcurl/README.md b/samples/libcurl/README.md index 16f32b87482..103dd69391b 100644 --- a/samples/libcurl/README.md +++ b/samples/libcurl/README.md @@ -4,7 +4,7 @@ This example shows how to build and publish an interop library to communicate wi HTTP/HTTPS/FTP/etc client library. Debian-like distros may need to `apt-get install libcurl4-openssl-dev`. -To build use `../gradlew build` +To build use `../gradlew assemble` To publish the library into a local repo use `../gradlew publish` diff --git a/samples/nonBlockingEchoServer/README.md b/samples/nonBlockingEchoServer/README.md index 0e14f5150ad..bdcdbfb678b 100644 --- a/samples/nonBlockingEchoServer/README.md +++ b/samples/nonBlockingEchoServer/README.md @@ -7,7 +7,7 @@ are being suspended and resumed whenever relevant. Thus, while server can process multiple connections concurrently, each individual connection handler is written in simple linear manner. -To build use `../gradlew build` or `./build.sh`. +To build use `../gradlew assemble` or `./build.sh`. Now you can run the server diff --git a/samples/opengl/README.md b/samples/opengl/README.md index e2940a8168d..3e9bac9d8d5 100644 --- a/samples/opengl/README.md +++ b/samples/opengl/README.md @@ -3,7 +3,7 @@ This example shows interaction with OpenGL library, to render classical 3D test model. Linux build requires `apt-get install freeglut3-dev` or similar, MacOS shall work as is. -To build use `../gradlew build` or `./build.sh`. +To build use `../gradlew assemble` or `./build.sh`. Now you can run the application diff --git a/samples/tetris/README.md b/samples/tetris/README.md index f9951cc7584..38237d4a7b2 100644 --- a/samples/tetris/README.md +++ b/samples/tetris/README.md @@ -13,7 +13,7 @@ use `apt-get install libsdl2-dev`. For Windows - `pacman -S mingw-w64-x86_64-SDL2` in MinGW64 console, if you do not have MSYS2-MinGW64 installed - install it first as described in http://www.msys2.org -To build Tetris application for your host platform (Mac or Linux) use `../gradlew build`. +To build Tetris application for your host platform (Mac or Linux) use `../gradlew assemble`. Aleternatively for Mac and Linux `./build.sh`. diff --git a/samples/videoplayer/README.md b/samples/videoplayer/README.md index d1660f1e19e..6e4c771fd71 100644 --- a/samples/videoplayer/README.md +++ b/samples/videoplayer/README.md @@ -11,7 +11,7 @@ ffmpeg and SDL2 is needed for that to work, i.e. apt install libsdl2-dev pacman -S mingw-w64-x86_64-SDL2 mingw-w64-x86_64-ffmpeg -To build use `../gradlew build`. +To build use `../gradlew assemble`. To run use `./build/exe/main/release//Player.kexe file.mp4`. diff --git a/samples/win32/README.md b/samples/win32/README.md index 49240b21c39..a7b86d6242f 100644 --- a/samples/win32/README.md +++ b/samples/win32/README.md @@ -1,5 +1,5 @@ # WIN32 Hello World -To build use `..\gradlew build` or `build.bat`. +To build use `..\gradlew assemble` or `build.bat`. To run use `.\build\exe\main\release\MessageBox.exe`. diff --git a/samples/workers/README.md b/samples/workers/README.md index 82e1969f9fa..85ab38fceee 100644 --- a/samples/workers/README.md +++ b/samples/workers/README.md @@ -34,6 +34,6 @@ Then it continues execution, and waits on future objects encapsulating the computation results. Afterwards, worker execution termination is requested with the `requestTermination()` operation. -To build use `./build.sh` or `./gradlew build` +To build use `./build.sh` or `./gradlew assemble` To run use `./build/exe/main/release/workers.kexe`