diff --git a/.gitignore b/.gitignore index ba6baa0b118..01e2413a384 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ /dependencies/all dist kotlin-native-*.tar.gz +kotlin-native-*.zip translator/src/test/kotlin/tests/*/linked out tmp diff --git a/DISTRO_README.md b/DISTRO_README.md index a2aec3f29ca..05397fad5d1 100644 --- a/DISTRO_README.md +++ b/DISTRO_README.md @@ -8,32 +8,9 @@ virtual machines are not desirable or possible (such as iOS, embedded targets), or where developer is willing to produce reasonably-sized self-contained program without need to ship an additional execution runtime. - To get started with _Kotlin/Native_ take a look at the attached samples. - - * `androidNativeActivity` - Android Native Activity rendering 3D graphics using OpenGLES - * `calculator` - iOS Swift application, using Kotlin/Native code compiled into the framework - * `csvparser` - simple CSV file parser and analyzer - * `gitchurn` - program interoperating with `libgit2` for GIT repository analysis - * `gtk` - GTK2 interoperability example - * `html5Canvas` - WebAssembly example - * `libcurl` - using of FTP/HTTP/HTTPS client library `libcurl` - * `nonBlockingEchoServer` - multi-client TCP/IP echo server using co-routines - * `objc` - AppKit Objective-C interoperability example for macOS - * `opengl` - OpenGL/GLUT teapot example - * `python_extension` - Python extension written in Kotlin/Native - * `socket` - TCP/IP echo server - * `tensorflow` - simple client for TensorFlow Machine Intelligence library - * `tetris` - Tetris game implementation (using SDL2 for rendering) - * `uikit` - UIKit Objective-C interoperability example for iOS - * `videoplayer` - SDL and FFMPEG-based video and audio player - * `win32` - trivial Win32 GUI application - * `workers` - example of using workers API - - - See `README.md` in each sample directory for more information and build instructions. - _Kotlin/Native_ could be used either as standalone compiler toolchain or as Gradle -plugin. See [`GRADLE_PLUGIN.md`](https://github.com/JetBrains/kotlin-native/blob/master/GRADLE_PLUGIN.md) for more details on how to use this plugin. +plugin. See [documentation](https://kotlinlang.org/docs/reference/native/gradle_plugin.html) +for more details on how to use this plugin. Compile your programs like that: @@ -45,10 +22,12 @@ For an optimized compilation use -opt: kotlinc hello.kt -o hello -opt To generate interoperability stubs create library definition file -(take a look on `samples/tetris/tetris.sdl`) and run `cinterop` tool like this: +(take a look on [Tetris sample](samples/tetris)) +and run `cinterop` tool like this: cinterop -def lib.def - -See [`INTEROP.md`](https://github.com/JetBrains/kotlin-native/blob/master/INTEROP.md) for more information on how to use C libraries from _Kotlin/Native_. + +See [C interop documentation](https://kotlinlang.org/docs/reference/native/c_interop.html) +for more information on how to use C libraries from _Kotlin/Native_. See [`RELEASE_NOTES.md`](https://github.com/JetBrains/kotlin-native/blob/master/RELEASE_NOTES.md) for information on supported platforms and current limitations. diff --git a/GRADLE_PLUGIN.md b/GRADLE_PLUGIN.md index 9ca207cd763..dcd1394015d 100644 --- a/GRADLE_PLUGIN.md +++ b/GRADLE_PLUGIN.md @@ -3,7 +3,7 @@ ### IMPORTANT NOTICE This document describes Kotlin/Native experimental Gradle plugin, which is not the plugin yet supported by IDE -or in multiplatform projects. See MPP Gradle plugin [documentation](https://kotlinlang.org/docs/reference/building-mpp-with-gradle.html +or in multiplatform projects. See MPP Gradle plugin [documentation](https://kotlinlang.org/docs/reference/building-mpp-with-gradle.html) for more information. ### Overview diff --git a/build.gradle b/build.gradle index e221ab837f7..f7c03f33f30 100644 --- a/build.gradle +++ b/build.gradle @@ -17,6 +17,7 @@ import groovy.io.FileType import org.jetbrains.kotlin.konan.target.* import org.jetbrains.kotlin.konan.properties.* import org.jetbrains.kotlin.konan.util.* +import org.jetbrains.kotlin.CopySamples buildscript { apply from: "gradle/kotlinGradlePlugin.gradle" @@ -390,35 +391,9 @@ task bundle(type: (isWindows()) ? Zip : Tar) { } from(project.rootDir) { include 'RELEASE_NOTES.md' - include 'samples/**' - exclude '**/gradle.properties' - exclude '**/settings.gradle' - exclude '**/build' - exclude '**/.gradle' - exclude 'samples/**/*.kt.bc-build' into baseName } - from(project.file("samples")) { - include '**/settings.gradle' - into "$baseName/samples" - filter { it.startsWith("includeBuild") ? null : it } - } - - from(project.file("samples")) { - include '**/gradle.properties' - into "$baseName/samples" - filter { - if (it.startsWith("konan.home=")) { - return it.replace("/dist", "") - } - if (it.startsWith("konan.plugin.version=")) { - return "konan.plugin.version=$gradlePluginVersion" - } - return it - } - } - destinationDir = file('.') if (!isWindows()) { extension = 'tar.gz' @@ -426,6 +401,45 @@ task bundle(type: (isWindows()) ? Zip : Tar) { } } +task samples { + dependsOn 'samplesZip', 'samplesTar' +} + +task samplesZip(type: Zip) +task samplesTar(type: Tar) { + extension = 'tar.gz' + compression = Compression.GZIP +} + +configure([samplesZip, samplesTar]) { + baseName "kotlin-native-samples-$konanVersionFull" + destinationDir = projectDir + into(baseName) + + from(file('samples')) { + // Process properties files separately. + exclude '**/gradle.properties' + } + + from(file('samples')) { + include '**/gradle.properties' + filter { + it.startsWith('org.jetbrains.kotlin.native.home=') || it.startsWith('# Use custom Kotlin/Native home:') ? null : it + } + } + + // Exclude build artifacts. + exclude '**/build' + exclude '**/.gradle' + exclude '**/.idea' + exclude '**/*.kt.bc-build/' +} + +task copy_samples(dependsOn: 'copySamples') +task copySamples(type: CopySamples) { + destinationDir file('build/samples-under-test') +} + task uploadBundle { dependsOn ':bundle' doLast { diff --git a/buildSrc/plugins/src/main/kotlin/org/jetbrains/kotlin/CopySamples.kt b/buildSrc/plugins/src/main/kotlin/org/jetbrains/kotlin/CopySamples.kt new file mode 100644 index 00000000000..796b955e77d --- /dev/null +++ b/buildSrc/plugins/src/main/kotlin/org/jetbrains/kotlin/CopySamples.kt @@ -0,0 +1,55 @@ +package org.jetbrains.kotlin + +import groovy.lang.Closure +import org.gradle.api.Task +import org.gradle.api.tasks.Copy + +/** + * A task that copies samples and replaces direct repository URLs with ones provided by the cache-redirector service. + */ +open class CopySamples: Copy() { + + var samplesDir = project.file("samples") + + init { + configureReplacements() + } + + fun samplesDir(path: Any) { + samplesDir = project.file(path) + } + + private fun configureReplacements() { + from(samplesDir) { + it.exclude("**/*.gradle") + } + from(samplesDir) { + it.include("**/*.gradle") + it.filter { line -> + replacements.forEach { (repo, replacement) -> + if (line.contains(repo)) { + return@filter line.replace(repo, replacement) + } + } + return@filter line + } + } + } + + override fun configure(closure: Closure): Task { + super.configure(closure) + configureReplacements() + return this + } + + companion object { + val replacements = listOf( + "mavenCentral()" to "maven { url 'https://cache-redirector.jetbrains.com/maven-central' }", + "jcenter()" to "maven { url 'https://cache-redirector.jetbrains.com/jcenter' }", + "https://dl.bintray.com/kotlin/kotlin-dev" to "https://cache-redirector.jetbrains.com/dl.bintray.com/kotlin/kotlin-dev", + "https://dl.bintray.com/kotlin/kotlin-eap" to "https://cache-redirector.jetbrains.com/dl.bintray.com/kotlin/kotlin-eap", + "https://dl.bintray.com/kotlin/ktor" to "https://cache-redirector.jetbrains.com/dl.bintray.com/kotlin/ktor", + "https://plugins.gradle.org/m2" to "https://cache-redirector.jetbrains.com/plugins.gradle.org/m2" + ) + } +} diff --git a/samples/README.md b/samples/README.md index cde12e75192..f79d9805879 100644 --- a/samples/README.md +++ b/samples/README.md @@ -1,22 +1,34 @@ # Samples This directory contains a set of samples demonstrating how one can work with Kotlin/Native. The samples can be -built using either command line tools (via `build.sh` script presented in each sample directory) or using a gradle build. -See `README.md` in sample directories to learn more about specific samples and the building process. +built using Gradle build tool. See `README.md` in sample directories to learn more about specific samples and +the building process. -**Note**: If the samples are built from a source tree (not from a distribution archive) the compiler and the gradle -plugin built from the sources are used. So one must build the compiler by running `./gradlew cross_dist` from the -Kotlin/Native root directory before building samples (see + * `androidNativeActivity` - Android Native Activity rendering 3D graphics using OpenGLES + * `calculator` - iOS Swift application, using Kotlin/Native code compiled into the framework + * `csvparser` - simple CSV file parser and analyzer + * `echoServer` - TCP/IP echo server + * `gitchurn` - program interoperating with `libgit2` for GIT repository analysis + * `gtk` - GTK2 interoperability example + * `html5Canvas` - WebAssembly example + * `libcurl` - using of FTP/HTTP/HTTPS client library `libcurl` + * `nonBlockingEchoServer` - multi-client TCP/IP echo server using co-routines + * `objc` - AppKit Objective-C interoperability example for macOS + * `opengl` - OpenGL/GLUT teapot example + * `python_extension` - Python extension written in Kotlin/Native + * `tensorflow` - simple client for TensorFlow Machine Intelligence library + * `tetris` - Tetris game implementation (using SDL2 for rendering) + * `uikit` - UIKit Objective-C interoperability example for iOS + * `videoplayer` - SDL and FFMPEG-based video and audio player + * `win32` - trivial Win32 GUI application + * `workers` - example of using workers API + + +**Note**: If the samples are built from a source tree (not from a distribution archive) the compiler built from +the sources is used. So one must build the compiler and the necessary platform libraries by running +`./gradlew bundle` from the Kotlin/Native root directory before building samples (see [README.md](https://github.com/JetBrains/kotlin-native/blob/master/README.md) for details). -One may also build all the samples with one command. To build them using the command line tools run: +One may also build all the samples with one command. To build them using Gradle run: - ./build.sh - -To build all the samples using the gradle build: - - ./gradlew build - -One also may launch the command line build via a gradle task `buildSh` (equivalent of `./build.sh` executing): - - ./gradlew buildSh + ./gradlew buildAllSamples diff --git a/samples/androidNativeActivity/README.md b/samples/androidNativeActivity/README.md index 42f3a0ca919..b6ab01e619c 100644 --- a/samples/androidNativeActivity/README.md +++ b/samples/androidNativeActivity/README.md @@ -1,15 +1,20 @@ # Android Native Activity - This example shows how to build an Android Native Activity. Also, we provide an example + +This example shows how to build an Android Native Activity. Also, we provide an example bridging mechanism for the Java APIs, callable from Native side. The example will render a textured dodecahedron using OpenGL ES library. It can be rotated with fingers. -Please make sure that Android SDK version 25 is installed, using Android SDK manager in Android Studio. +Please make sure that Android SDK version 28 is installed, using Android SDK manager in Android Studio. See https://developer.android.com/studio/index.html for more details on Android Studio or -`$ANDROID_HOME/tools/bin/sdkmanager "platforms;android-25" "build-tools;25.0.2"` from command line. +`$ANDROID_HOME/tools/bin/sdkmanager "platforms;android-28" "build-tools;28.0.3"` from command line. We use JniBridge to call vibration service on the Java side for short tremble on startup. -To build use `ANDROID_HOME= ../gradlew build`. +To build use `ANDROID_HOME= ../gradlew assemble`. Run `$ANDROID_HOME/platform-tools/adb install -r build/outputs/apk/debug/androidNativeActivity-debug.apk` to deploy the apk on the Android device or emulator (note that only ARM-based devices are currently supported). +Note: If you are importing project to IDEA for the first time, you might need to put `local.properties` file +with the following content: + + sdk.dir= diff --git a/samples/androidNativeActivity/build.gradle b/samples/androidNativeActivity/build.gradle index af7bde516eb..1bacafb1a01 100644 --- a/samples/androidNativeActivity/build.gradle +++ b/samples/androidNativeActivity/build.gradle @@ -1,85 +1,100 @@ buildscript { repositories { + google() jcenter() mavenCentral() - google() - maven { - url "https://dl.bintray.com/jetbrains/kotlin-native-dependencies" - } + maven { url 'https://dl.bintray.com/kotlin/kotlin-dev' } + maven { url 'https://dl.bintray.com/kotlin/kotlin-eap' } } + dependencies { - classpath "org.jetbrains.kotlin:kotlin-native-gradle-plugin:${project.property('konan.plugin.version')}" - classpath 'com.android.tools.build:gradle:3.1.2' + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + classpath 'com.android.tools.build:gradle:3.2.1' } } repositories { - jcenter() google() + jcenter() + mavenCentral() + maven { url 'https://dl.bintray.com/kotlin/kotlin-dev' } + maven { url 'https://dl.bintray.com/kotlin/kotlin-eap' } } -apply plugin: 'konan' +apply plugin: 'org.jetbrains.kotlin.multiplatform' apply plugin: 'com.android.application' -konan.targets = ['android_arm32', 'android_arm64'] - -def outDir = file('Polyhedron') -def libsDir = file("$outDir/libs") -def platforms = [ - "armeabi-v7a": [konanTarget: "android_arm32"], - "arm64-v8a" : [konanTarget: "android_arm64"] +def appDir = file("$buildDir/Polyhedron") +def libsDir = file("$appDir/libs") +Map libsDirMapping = [ + 'arm32' : "$libsDir/armeabi-v7a", + 'arm64' : "$libsDir/arm64-v8a" ] -konanArtifacts { - program('Polyhedron') { - artifactName 'libpoly' - } -} - -task copyLibs(type: Copy) { - dependsOn konanArtifacts.Polyhedron - destinationDir libsDir - - platforms.each { name, platform -> - into(name) { - from konanArtifacts.Polyhedron."${platform.konanTarget}".artifact - } - } -} - -task deleteOut(type: Delete) { - delete outDir -} - -clean.dependsOn deleteOut - -tasks.matching { it.name == 'preBuild' }.all { - it.dependsOn copyLibs -} - android { - compileSdkVersion 25 + compileSdkVersion 28 defaultConfig { applicationId 'com.jetbrains.konan_activity2' minSdkVersion 9 - targetSdkVersion 25 + targetSdkVersion 28 ndk { - abiFilters "armeabi-v7a", "arm64-v8a" + abiFilters 'armeabi-v7a', 'arm64-v8a' } } sourceSets { main { + root 'src/arm32Main' jniLibs.srcDir libsDir } } - } -task buildApk(type: Copy) { - dependsOn "assembleDebug" - destinationDir outDir - from 'build/outputs/apk' +kotlin { + targets { + fromPreset(presets.androidNativeArm32, 'arm32') + fromPreset(presets.androidNativeArm64, 'arm64') + + configure([arm32, arm64]) { + compilations.main.outputKinds 'EXECUTABLE' + compilations.main.entryPoint 'sample.androidnative.main' + compilations.main.cinterops { + bmpformat + } + } + } + + sourceSets { + arm64Main.dependsOn arm32Main + } +} + +// Disable generating Kotlin metadata. +tasks.compileKotlinMetadata.enabled = false + +afterEvaluate { + kotlin.targets { targets -> + [arm32, arm64].collect { target -> + target.compilations.main { mainCompilation -> + String buildType = 'RELEASE' // Change to 'DEBUG' to include debug symbols. + Object linkTask = mainCompilation.getLinkTask('EXECUTABLE', buildType) + + // Rename binary files to 'libpoly.so' and put them to the appropriate location. + File binaryFile = linkTask.outputFile.get() + linkTask.doLast { + copy { + from binaryFile + into libsDirMapping[target.targetName] + rename { + 'libpoly.so' + } + } + } + + tasks.preBuild.dependsOn linkTask + } + } + } } diff --git a/samples/androidNativeActivity/build.sh b/samples/androidNativeActivity/build.sh new file mode 100755 index 00000000000..a26f890f026 --- /dev/null +++ b/samples/androidNativeActivity/build.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash + +DIR=$(cd "$(dirname "${BASH_SOURCE[0]}" )" && pwd ) + +$DIR/../gradlew -p $DIR assemble diff --git a/samples/androidNativeActivity/gradle.properties b/samples/androidNativeActivity/gradle.properties index 1a26c3ce51c..7fc6f1ff272 100644 --- a/samples/androidNativeActivity/gradle.properties +++ b/samples/androidNativeActivity/gradle.properties @@ -1,2 +1 @@ -konan.home=../../dist -konan.plugin.version=+ +kotlin.code.style=official diff --git a/samples/androidNativeActivity/gradle/wrapper/gradle-wrapper.jar b/samples/androidNativeActivity/gradle/wrapper/gradle-wrapper.jar index 29953ea141f..91ca28c8b80 100644 Binary files a/samples/androidNativeActivity/gradle/wrapper/gradle-wrapper.jar and b/samples/androidNativeActivity/gradle/wrapper/gradle-wrapper.jar differ diff --git a/samples/androidNativeActivity/gradle/wrapper/gradle-wrapper.properties b/samples/androidNativeActivity/gradle/wrapper/gradle-wrapper.properties index d76b502e226..e6a30918ef8 100644 --- a/samples/androidNativeActivity/gradle/wrapper/gradle-wrapper.properties +++ b/samples/androidNativeActivity/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.7-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/samples/androidNativeActivity/settings.gradle b/samples/androidNativeActivity/settings.gradle index 5235398bace..43c08c10733 100644 --- a/samples/androidNativeActivity/settings.gradle +++ b/samples/androidNativeActivity/settings.gradle @@ -1,2 +1,20 @@ -includeBuild '../../shared' -includeBuild '../../tools/kotlin-native-gradle-plugin' +// Reuse Kotlin version from the root project. +File rootProjectGradlePropertiesFile = file("${rootProject.projectDir}/../gradle.properties") +if (!rootProjectGradlePropertiesFile.isFile()) { + throw new Exception("File $rootProjectGradlePropertiesFile does not exist or is not a file") +} + +Properties rootProjectProperties = new Properties() +rootProjectGradlePropertiesFile.withInputStream { inputStream -> + rootProjectProperties.load(inputStream) + if (!rootProjectProperties.containsKey('kotlin_version')) { + throw new Exception("No 'kotlin_version' property in $rootProjectGradlePropertiesFile file") + } +} + +gradle.beforeProject { project -> + rootProjectProperties.forEach { String key, value -> + if (!project.hasProperty(key)) + project.ext[key] = value + } +} diff --git a/samples/androidNativeActivity/src/main/AndroidManifest.xml b/samples/androidNativeActivity/src/arm32Main/AndroidManifest.xml similarity index 100% rename from samples/androidNativeActivity/src/main/AndroidManifest.xml rename to samples/androidNativeActivity/src/arm32Main/AndroidManifest.xml diff --git a/samples/androidNativeActivity/src/main/assets/kotlin_logo.bmp b/samples/androidNativeActivity/src/arm32Main/assets/kotlin_logo.bmp similarity index 100% rename from samples/androidNativeActivity/src/main/assets/kotlin_logo.bmp rename to samples/androidNativeActivity/src/arm32Main/assets/kotlin_logo.bmp diff --git a/samples/androidNativeActivity/src/arm32Main/kotlin/BMPHeader.kt b/samples/androidNativeActivity/src/arm32Main/kotlin/BMPHeader.kt new file mode 100644 index 00000000000..34ae36f3e24 --- /dev/null +++ b/samples/androidNativeActivity/src/arm32Main/kotlin/BMPHeader.kt @@ -0,0 +1,7 @@ +package sample.androidnative + +import kotlinx.cinterop.* +import sample.androidnative.bmpformat.BMPHeader + +val BMPHeader.data + get() = (ptr.reinterpret() + sizeOf()) as CArrayPointer diff --git a/samples/androidNativeActivity/src/main/kotlin/Disposable.kt b/samples/androidNativeActivity/src/arm32Main/kotlin/Disposable.kt similarity index 74% rename from samples/androidNativeActivity/src/main/kotlin/Disposable.kt rename to samples/androidNativeActivity/src/arm32Main/kotlin/Disposable.kt index 1e7f912d163..b1076bde043 100644 --- a/samples/androidNativeActivity/src/main/kotlin/Disposable.kt +++ b/samples/androidNativeActivity/src/arm32Main/kotlin/Disposable.kt @@ -1,20 +1,9 @@ /* - * Copyright 2010-2018 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. */ -package NativeApplication +package sample.androidnative import kotlinx.cinterop.* diff --git a/samples/androidNativeActivity/src/main/kotlin/Engine.kt b/samples/androidNativeActivity/src/arm32Main/kotlin/Engine.kt similarity index 93% rename from samples/androidNativeActivity/src/main/kotlin/Engine.kt rename to samples/androidNativeActivity/src/arm32Main/kotlin/Engine.kt index f08c027dae8..e082bb980d7 100644 --- a/samples/androidNativeActivity/src/main/kotlin/Engine.kt +++ b/samples/androidNativeActivity/src/arm32Main/kotlin/Engine.kt @@ -1,19 +1,9 @@ /* - * Copyright 2010-2018 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. */ -package NativeApplication + +package sample.androidnative import kotlinx.cinterop.* import platform.android.* diff --git a/samples/androidNativeActivity/src/main/kotlin/JniBridge.kt b/samples/androidNativeActivity/src/arm32Main/kotlin/JniBridge.kt similarity index 86% rename from samples/androidNativeActivity/src/main/kotlin/JniBridge.kt rename to samples/androidNativeActivity/src/arm32Main/kotlin/JniBridge.kt index 598a3978002..b8cc8d1b243 100644 --- a/samples/androidNativeActivity/src/main/kotlin/JniBridge.kt +++ b/samples/androidNativeActivity/src/arm32Main/kotlin/JniBridge.kt @@ -1,19 +1,9 @@ /* - * Copyright 2010-2018 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. */ -package NativeApplication + +package sample.androidnative import kotlinx.cinterop.* import platform.android.* diff --git a/samples/androidNativeActivity/src/main/kotlin/Polyhedra.kt b/samples/androidNativeActivity/src/arm32Main/kotlin/Polyhedra.kt similarity index 82% rename from samples/androidNativeActivity/src/main/kotlin/Polyhedra.kt rename to samples/androidNativeActivity/src/arm32Main/kotlin/Polyhedra.kt index dfb4beba9f8..1a16c1cea46 100644 --- a/samples/androidNativeActivity/src/main/kotlin/Polyhedra.kt +++ b/samples/androidNativeActivity/src/arm32Main/kotlin/Polyhedra.kt @@ -1,19 +1,9 @@ /* - * Copyright 2010-2018 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. */ -package NativeApplication + +package sample.androidnative const val Zero = 0.0f const val DodeA = 0.93417235896f // (Sqrt(5) + 1) / (2 * Sqrt(3)) diff --git a/samples/androidNativeActivity/src/main/kotlin/Renderer.kt b/samples/androidNativeActivity/src/arm32Main/kotlin/Renderer.kt similarity index 94% rename from samples/androidNativeActivity/src/main/kotlin/Renderer.kt rename to samples/androidNativeActivity/src/arm32Main/kotlin/Renderer.kt index ccae3662ff8..70b0ee73c72 100644 --- a/samples/androidNativeActivity/src/main/kotlin/Renderer.kt +++ b/samples/androidNativeActivity/src/arm32Main/kotlin/Renderer.kt @@ -1,20 +1,9 @@ /* - * Copyright 2010-2018 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. */ -package NativeApplication +package sample.androidnative import kotlinx.cinterop.* import platform.android.* @@ -56,6 +45,7 @@ import platform.gles.glVertexPointer import platform.gles.glTexCoordPointer import platform.gles.glNormalPointer import platform.gles.GL_TEXTURE_ENV_COLOR +import sample.androidnative.bmpformat.BMPHeader class Renderer(val container: DisposableContainer, val nativeActivity: ANativeActivity, @@ -207,8 +197,9 @@ class Renderer(val container: DisposableContainer, if (AAsset_read(asset, buffer, length.convert()) != length.toInt()) { throw Error("Error reading asset") } - with(BMPHeader(buffer.rawValue)) { - if (magic != 0x4d42 || zero != 0 || size != length.toInt() || bits != 24) { + + with(buffer.reinterpret().pointed) { + if (magic != 0x4d42.toUShort() || zero != 0u || size != length.toUInt() || bits != 24.toUShort()) { throw Error("Error parsing texture file") } val numberOfBytes = width * height * 3 diff --git a/samples/androidNativeActivity/src/main/kotlin/Vectors.kt b/samples/androidNativeActivity/src/arm32Main/kotlin/Vectors.kt similarity index 69% rename from samples/androidNativeActivity/src/main/kotlin/Vectors.kt rename to samples/androidNativeActivity/src/arm32Main/kotlin/Vectors.kt index 91f5efc79dd..f86c077362c 100644 --- a/samples/androidNativeActivity/src/main/kotlin/Vectors.kt +++ b/samples/androidNativeActivity/src/arm32Main/kotlin/Vectors.kt @@ -1,19 +1,9 @@ /* - * Copyright 2010-2018 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. */ -package NativeApplication + +package sample.androidnative import kotlinx.cinterop.* import platform.android.* diff --git a/samples/androidNativeActivity/src/arm32Main/kotlin/main.kt b/samples/androidNativeActivity/src/arm32Main/kotlin/main.kt new file mode 100644 index 00000000000..dc558f08937 --- /dev/null +++ b/samples/androidNativeActivity/src/arm32Main/kotlin/main.kt @@ -0,0 +1,24 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package sample.androidnative + +import kotlinx.cinterop.* +import platform.android.* + +fun main() { + logInfo("Entering main().") + memScoped { + val state = alloc() + getNativeActivityState(state.ptr) + val engine = Engine(state) + try { + engine.mainLoop() + } finally { + engine.dispose() + } + } + kotlin.system.exitProcess(0) +} diff --git a/samples/androidNativeActivity/src/main/res/mipmap-hdpi/konan_activity.png b/samples/androidNativeActivity/src/arm32Main/res/mipmap-hdpi/konan_activity.png similarity index 100% rename from samples/androidNativeActivity/src/main/res/mipmap-hdpi/konan_activity.png rename to samples/androidNativeActivity/src/arm32Main/res/mipmap-hdpi/konan_activity.png diff --git a/samples/androidNativeActivity/src/main/res/mipmap-mdpi/konan_activity.png b/samples/androidNativeActivity/src/arm32Main/res/mipmap-mdpi/konan_activity.png similarity index 100% rename from samples/androidNativeActivity/src/main/res/mipmap-mdpi/konan_activity.png rename to samples/androidNativeActivity/src/arm32Main/res/mipmap-mdpi/konan_activity.png diff --git a/samples/androidNativeActivity/src/main/res/mipmap-xhdpi/konan_activity.png b/samples/androidNativeActivity/src/arm32Main/res/mipmap-xhdpi/konan_activity.png similarity index 100% rename from samples/androidNativeActivity/src/main/res/mipmap-xhdpi/konan_activity.png rename to samples/androidNativeActivity/src/arm32Main/res/mipmap-xhdpi/konan_activity.png diff --git a/samples/androidNativeActivity/src/main/res/mipmap-xxhdpi/konan_activity.png b/samples/androidNativeActivity/src/arm32Main/res/mipmap-xxhdpi/konan_activity.png similarity index 100% rename from samples/androidNativeActivity/src/main/res/mipmap-xxhdpi/konan_activity.png rename to samples/androidNativeActivity/src/arm32Main/res/mipmap-xxhdpi/konan_activity.png diff --git a/samples/androidNativeActivity/src/main/res/values/strings.xml b/samples/androidNativeActivity/src/arm32Main/res/values/strings.xml similarity index 100% rename from samples/androidNativeActivity/src/main/res/values/strings.xml rename to samples/androidNativeActivity/src/arm32Main/res/values/strings.xml diff --git a/samples/androidNativeActivity/src/main/kotlin/BMPHeader.kt b/samples/androidNativeActivity/src/main/kotlin/BMPHeader.kt deleted file mode 100644 index 64073e1dc1f..00000000000 --- a/samples/androidNativeActivity/src/main/kotlin/BMPHeader.kt +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2010-2018 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package NativeApplication - -import kotlinx.cinterop.* - -internal class BMPHeader(val rawPtr: NativePtr) { - inline fun memberAt(offset: Long): T { - return interpretPointed(this.rawPtr + offset) - } - - val magic get() = memberAt(0).value.toInt() - val size get() = memberAt(2).value - val zero get() = memberAt(6).value - val width get() = memberAt(18).value - val height get() = memberAt(22).value - val bits get() = memberAt(28).value.toInt() - val data get() = interpretCPointer(rawPtr + 54) as CArrayPointer -} \ No newline at end of file diff --git a/samples/androidNativeActivity/src/main/kotlin/main.kt b/samples/androidNativeActivity/src/main/kotlin/main.kt deleted file mode 100644 index 71a640a46d4..00000000000 --- a/samples/androidNativeActivity/src/main/kotlin/main.kt +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2010-2018 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import kotlinx.cinterop.* -import platform.android.* -import NativeApplication.* - -fun main(args: Array) { - logInfo("Entering main().") - memScoped { - val state = alloc() - getNativeActivityState(state.ptr) - val engine = Engine(state) - try { - engine.mainLoop() - } finally { - engine.dispose() - } - } - kotlin.system.exitProcess(0) -} diff --git a/samples/androidNativeActivity/src/nativeInterop/cinterop/bmpformat.def b/samples/androidNativeActivity/src/nativeInterop/cinterop/bmpformat.def new file mode 100644 index 00000000000..2d661b1bcf4 --- /dev/null +++ b/samples/androidNativeActivity/src/nativeInterop/cinterop/bmpformat.def @@ -0,0 +1,16 @@ +package = sample.androidnative.bmpformat + +--- +#include + +typedef struct __attribute__((packed)) { + uint16_t magic; + uint32_t size; + uint32_t zero; + uint8_t padding1[8]; + int32_t width; + int32_t height; + uint8_t padding2[2]; + uint16_t bits; + uint8_t padding3[24]; +} BMPHeader; diff --git a/samples/build.gradle b/samples/build.gradle index 75330ee4a8a..309bb9312b4 100644 --- a/samples/build.gradle +++ b/samples/build.gradle @@ -1,39 +1,59 @@ -subprojects { - buildscript { - repositories { - maven { - url 'https://cache-redirector.jetbrains.com/maven-central' - } - maven { - url "https://dl.bintray.com/jetbrains/kotlin-native-dependencies" - } - } +buildscript { + repositories { + mavenCentral() + maven { url 'https://dl.bintray.com/kotlin/kotlin-dev' } + maven { url 'https://dl.bintray.com/kotlin/kotlin-eap' } + } - dependencies { - classpath "org.jetbrains.kotlin:kotlin-native-gradle-plugin:${project.property('konan.plugin.version')}" - } + dependencies { + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + } +} + +allprojects { + repositories { + mavenCentral() + maven { url 'https://dl.bintray.com/kotlin/kotlin-dev' } + maven { url 'https://dl.bintray.com/kotlin/kotlin-eap' } } } task buildSh(type: Exec) { - commandLine "${projectDir.canonicalPath}/build.sh" - workingDir projectDir.canonicalPath + errorOutput = System.out + ignoreExitValue = true + workingDir projectDir + enabled = !MPPTools.isWindows() + if (MPPTools.isLinux() || MPPTools.isMacos()) { + commandLine "$projectDir/build.sh" + } } task buildSamplesWithPlatformLibs() { - dependsOn ':csvparser:build' - dependsOn ':nonBlockingEchoServer:build' - dependsOn ':objc:build' - dependsOn ':opengl:build' - dependsOn ':socket:build' - dependsOn ':uikit:build' - dependsOn ':win32:build' - dependsOn ':workers:build' - dependsOn ':globalState:build' + dependsOn ':csvparser:assemble' + dependsOn ':echoServer:assemble' + dependsOn ':globalState:assemble' + dependsOn ':html5Canvas:assemble' + dependsOn ':workers:assemble' + + if (MPPTools.isMacos() || MPPTools.isLinux()) { + dependsOn ':nonBlockingEchoServer:assemble' + dependsOn ':tensorflow:assemble' + } + + if (MPPTools.isMacos()) { + dependsOn ':objc:assemble' + dependsOn ':opengl:assemble' + dependsOn ':uikit:assemble' + } + + if (MPPTools.isWindows()) { + dependsOn ':win32:assemble' + } } task buildAllSamples() { + dependsOn buildSh subprojects.each { - dependsOn("${it.path}:build") + dependsOn("${it.path}:assemble") } } diff --git a/samples/buildSrc/build.gradle b/samples/buildSrc/build.gradle new file mode 100644 index 00000000000..f167e041313 --- /dev/null +++ b/samples/buildSrc/build.gradle @@ -0,0 +1,26 @@ +buildscript { + repositories { + mavenCentral() + maven { url 'https://dl.bintray.com/kotlin/kotlin-dev' } + maven { url 'https://dl.bintray.com/kotlin/kotlin-eap' } + } + + dependencies { + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + } +} + +apply plugin: 'kotlin' + +repositories { + mavenCentral() + maven { url 'https://dl.bintray.com/kotlin/kotlin-dev' } + maven { url 'https://dl.bintray.com/kotlin/kotlin-eap' } + maven { url 'https://plugins.gradle.org/m2/' } +} + +dependencies { + compileOnly gradleApi() + implementation 'org.jetbrains.kotlin:kotlin-gradle-plugin' + implementation 'org.jetbrains.kotlin:kotlin-stdlib' +} diff --git a/samples/buildSrc/settings.gradle b/samples/buildSrc/settings.gradle new file mode 100644 index 00000000000..43c08c10733 --- /dev/null +++ b/samples/buildSrc/settings.gradle @@ -0,0 +1,20 @@ +// Reuse Kotlin version from the root project. +File rootProjectGradlePropertiesFile = file("${rootProject.projectDir}/../gradle.properties") +if (!rootProjectGradlePropertiesFile.isFile()) { + throw new Exception("File $rootProjectGradlePropertiesFile does not exist or is not a file") +} + +Properties rootProjectProperties = new Properties() +rootProjectGradlePropertiesFile.withInputStream { inputStream -> + rootProjectProperties.load(inputStream) + if (!rootProjectProperties.containsKey('kotlin_version')) { + throw new Exception("No 'kotlin_version' property in $rootProjectGradlePropertiesFile file") + } +} + +gradle.beforeProject { project -> + rootProjectProperties.forEach { String key, value -> + if (!project.hasProperty(key)) + project.ext[key] = value + } +} diff --git a/samples/buildSrc/src/main/kotlin/Internals.kt b/samples/buildSrc/src/main/kotlin/Internals.kt new file mode 100644 index 00000000000..d46ce36b47c --- /dev/null +++ b/samples/buildSrc/src/main/kotlin/Internals.kt @@ -0,0 +1,38 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +import org.gradle.api.NamedDomainObjectCollection +import org.gradle.api.NamedDomainObjectContainer +import org.gradle.api.Project +import org.gradle.api.plugins.ExtraPropertiesExtension +import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension +import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation +import org.jetbrains.kotlin.gradle.plugin.KotlinTargetPreset +import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeCompilation + +/* + * This file includes internal short-cuts visible only inside of the 'buildSrc' module. + */ + +internal val hostOs by lazy { System.getProperty("os.name") } +internal val userHome by lazy { System.getProperty("user.home") } + +internal val Project.ext: ExtraPropertiesExtension + get() = extensions.getByName("ext") as ExtraPropertiesExtension + +internal val Project.kotlin: KotlinMultiplatformExtension + get() = extensions.getByName("kotlin") as KotlinMultiplatformExtension + +internal val NamedDomainObjectCollection>.macosX64: KotlinTargetPreset<*> + get() = getByName(::macosX64.name) as KotlinTargetPreset<*> + +internal val NamedDomainObjectCollection>.linuxX64: KotlinTargetPreset<*> + get() = getByName(::linuxX64.name) as KotlinTargetPreset<*> + +internal val NamedDomainObjectCollection>.mingwX64: KotlinTargetPreset<*> + get() = getByName(::mingwX64.name) as KotlinTargetPreset<*> + +internal val NamedDomainObjectContainer.main: KotlinNativeCompilation + get() = getByName(::main.name) as KotlinNativeCompilation diff --git a/samples/buildSrc/src/main/kotlin/MPPTools.kt b/samples/buildSrc/src/main/kotlin/MPPTools.kt new file mode 100644 index 00000000000..d3175f254b7 --- /dev/null +++ b/samples/buildSrc/src/main/kotlin/MPPTools.kt @@ -0,0 +1,76 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +@file:JvmName("MPPTools") + +import groovy.lang.Closure +import org.gradle.api.Project +import org.gradle.api.Task +import org.jetbrains.kotlin.gradle.plugin.KotlinTarget +import org.jetbrains.kotlin.gradle.plugin.KotlinTargetPreset +import java.nio.file.Paths + +/* + * This file includes short-cuts that may potentially be implemented in Kotlin MPP Gradle plugin in the future. + */ + +// Short-cuts for detecting the host OS. +@get:JvmName("isMacos") +val isMacos by lazy { hostOs == "Mac OS X" } + +@get:JvmName("isWindows") +val isWindows by lazy { hostOs.startsWith("Windows") } + +@get:JvmName("isLinux") +val isLinux by lazy { hostOs == "Linux" } + +// Short-cuts for mostly used paths. +@get:JvmName("mingwPath") +val mingwPath by lazy { System.getenv("MINGW64_DIR") ?: "c:/msys64/mingw64" } + +@get:JvmName("kotlinNativeDataPath") +val kotlinNativeDataPath by lazy { + System.getenv("KONAN_DATA_DIR") ?: Paths.get(userHome, ".konan").toString() +} + +// A short-cut for evaluation of the default host Kotlin/Native preset. +@JvmOverloads +fun defaultHostPreset( + subproject: Project, + whitelist: List> = listOf(subproject.kotlin.presets.macosX64, subproject.kotlin.presets.linuxX64, subproject.kotlin.presets.mingwX64) +): KotlinTargetPreset<*> { + + if (whitelist.isEmpty()) + throw Exception("Preset whitelist must not be empty in Kotlin/Native ${subproject.displayName}.") + + val presetCandidate = when { + isMacos -> subproject.kotlin.presets.macosX64 + isLinux -> subproject.kotlin.presets.linuxX64 + isWindows -> subproject.kotlin.presets.mingwX64 + else -> null + } + + val preset = if (presetCandidate != null && presetCandidate in whitelist) + presetCandidate + else + throw Exception("Host OS '$hostOs' is not supported in Kotlin/Native ${subproject.displayName}.") + + subproject.ext.set("hostPreset", preset) + + return preset +} + +// A short-cut to add a Kotlin/Native run task. +@JvmOverloads +fun createRunTask( + subproject: Project, + name: String, + target: KotlinTarget, + configureClosure: Closure? = null +): Task { + val task = subproject.tasks.create(name, RunKotlinNativeTask::class.java, target) + task.configure(configureClosure ?: task.emptyConfigureClosure()) + return task +} diff --git a/samples/buildSrc/src/main/kotlin/RunKotlinNativeTask.kt b/samples/buildSrc/src/main/kotlin/RunKotlinNativeTask.kt new file mode 100644 index 00000000000..2ad0c63849d --- /dev/null +++ b/samples/buildSrc/src/main/kotlin/RunKotlinNativeTask.kt @@ -0,0 +1,51 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +import groovy.lang.Closure +import org.gradle.api.DefaultTask +import org.gradle.api.Task +import org.gradle.api.tasks.TaskAction +import org.jetbrains.kotlin.gradle.plugin.KotlinTarget +import javax.inject.Inject + +open class RunKotlinNativeTask @Inject constructor( + private val myTarget: KotlinTarget +): DefaultTask() { + + var buildType = "RELEASE" + var workingDir: Any = project.projectDir + private var myArgs: List = emptyList() + private val myEnvironment: MutableMap = mutableMapOf() + + fun args(vararg args: Any) { + myArgs = args.map { it.toString() } + } + + fun environment(map: Map) { + myEnvironment += map + } + + override fun configure(configureClosure: Closure): Task { + val task = super.configure(configureClosure) + this.dependsOn += myTarget.compilations.main.linkTaskName("EXECUTABLE", buildType) + return task + } + + @TaskAction + fun run() { + project.exec { + it.executable = myTarget.compilations.main.getBinary("EXECUTABLE", buildType).toString() + it.args = myArgs + it.environment = myEnvironment + it.workingDir(workingDir) + } + } + + internal fun emptyConfigureClosure() = object : Closure(this) { + override fun call(): RunKotlinNativeTask { + return this@RunKotlinNativeTask + } + } +} diff --git a/samples/calculator/.gitignore b/samples/calculator/.gitignore new file mode 100644 index 00000000000..9bce6af399b --- /dev/null +++ b/samples/calculator/.gitignore @@ -0,0 +1 @@ +xcuserdata diff --git a/samples/calculator/README.md b/samples/calculator/README.md index abdb7190a22..6b14b91f4cf 100644 --- a/samples/calculator/README.md +++ b/samples/calculator/README.md @@ -1,10 +1,10 @@ # Calculator sample -This example shows how to use Kotlin common module (located in [common/](common/)) in different environments. +This example shows how to use Kotlin common module (located in [arithmeticParser](arithmeticParser/)) in different environments. Currently for -* Android (see [android](android/)) -* iOS (see [ios/calculator](ios/calculator/)) -* plain JVM (cli) (see [jvm](jvm/)) +* Android (see [androidApp](androidApp/)) +* iOS (see [iosApp](iosApp/)) +* plain JVM (cli) (see [cliApp](cliApp/)) ## Common @@ -13,18 +13,26 @@ Common Kotlin module contains arithmetic expressions parser. ## Android App The common module may be used in an Android application. -To build and run the Android sample do the following: +Please make sure that Android SDK version 28 is installed, using Android SDK manager in Android Studio. +See https://developer.android.com/studio/index.html for more details on Android Studio or +`$ANDROID_HOME/tools/bin/sdkmanager "platforms;android-28" "build-tools;28.0.3"` from command line. -1. Open the project in Android Studio 3.1 -2. Create a new Android App configuration. Choose module `android`. -3. Now build and run the configuration created. +To build use `ANDROID_HOME= ../gradlew assemble`. + +Run `$ANDROID_HOME/platform-tools/adb install -r androidApp/build/outputs/apk/debug/androidApp-debug.apk` +to deploy the apk on the Android device or emulator. + +Note: If you are importing project to IDEA for the first time, you might need to put `local.properties` file +with the following content: + + sdk.dir= ## iOS -The iOS project compiles Kotlin module to a framework (see [ios](ios/)). The framework can be easily included in an existing iOS project (e.g. written in Swift or Objective-C) +The iOS project compiles Kotlin module to a framework (see [iosApp](iosApp/)). The framework can be easily included in an existing iOS project (e.g. written in Swift or Objective-C) To build and run the iOS sample do the following: -1. Open `ios/calculator.xcodeproj` with Xcode. +1. Open `iosApp/calculator.xcodeproj` with Xcode. 2. Open the project's target through project navigator, go to tab 'General'. In 'Identity' section change the bundle ID to the unique string in reverse-DNS format. Then select the team in 'Signing' section. @@ -41,14 +49,7 @@ the Xcode project. ## Plain JVM The common module can also be used in JVM application built by Kotlin/JVM compiler with Gradle. -To build and run it, go to [jvm](jvm/) directory and use +To build and run it, go to [cliApp](cliApp/) directory and use ``` -../gradlew run +../gradlew runProgram ``` - -To build the distribution: -``` -../gradlew distZip -``` -(the result will be available as -`jvm/build/distributions/KotlinCalculator.zip`) diff --git a/samples/calculator/android/build.gradle b/samples/calculator/android/build.gradle deleted file mode 100644 index b97516566b9..00000000000 --- a/samples/calculator/android/build.gradle +++ /dev/null @@ -1,44 +0,0 @@ -buildscript { - ext.kotlin_version = '1.3.0-rc-6' - - repositories { - google() - jcenter() - } - - dependencies { - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - classpath 'com.android.tools.build:gradle:3.1.4' - } -} - -apply plugin: 'com.android.application' -apply plugin: 'kotlin-platform-android' - -android { - compileSdkVersion 27 - defaultConfig { - applicationId "org.konan.calculator" - minSdkVersion 21 - targetSdkVersion 27 - versionCode 1 - versionName "1.0.0" - } - sourceSets { - main.java.srcDirs += 'src/main/kotlin' - main.java.srcDirs += '../common/src/main/kotlin' - } -} - -repositories { - google() - jcenter() - mavenCentral() -} - -dependencies { - implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" - expectedBy project(':common') - - implementation "com.android.support:appcompat-v7:27.0.2" -} diff --git a/samples/calculator/androidApp/build.gradle b/samples/calculator/androidApp/build.gradle new file mode 100644 index 00000000000..04650a84e8c --- /dev/null +++ b/samples/calculator/androidApp/build.gradle @@ -0,0 +1,26 @@ +apply plugin: 'org.jetbrains.kotlin.multiplatform' +apply plugin: 'com.android.application' +apply plugin: 'kotlin-android-extensions' + +android { + compileSdkVersion 28 + + defaultConfig { + applicationId 'org.konan.calculator' + minSdkVersion 21 + targetSdkVersion 28 + } +} + +dependencies { + api 'com.android.support:appcompat-v7:28.0.0' + api 'com.android.support.constraint:constraint-layout:1.1.3' + implementation fileTree(dir: 'libs', include: ['*.jar']) + implementation project(':arithmeticParser') +} + +kotlin { + targets { + fromPreset(presets.android, 'android') + } +} diff --git a/samples/calculator/androidApp/gradle.properties b/samples/calculator/androidApp/gradle.properties new file mode 100644 index 00000000000..790a07d5124 --- /dev/null +++ b/samples/calculator/androidApp/gradle.properties @@ -0,0 +1,2 @@ +kotlin.code.style=official +kotlin.import.noCommonSourceSets=true diff --git a/samples/calculator/android/src/main/AndroidManifest.xml b/samples/calculator/androidApp/src/main/AndroidManifest.xml similarity index 76% rename from samples/calculator/android/src/main/AndroidManifest.xml rename to samples/calculator/androidApp/src/main/AndroidManifest.xml index 4388566755e..a224235bfd7 100644 --- a/samples/calculator/android/src/main/AndroidManifest.xml +++ b/samples/calculator/androidApp/src/main/AndroidManifest.xml @@ -1,5 +1,8 @@ + + package="sample.calculator.android" + android:versionCode="1" + android:versionName="1.0"> diff --git a/samples/calculator/android/src/main/kotlin/org/konan/calculator/MainActivity.kt b/samples/calculator/androidApp/src/main/kotlin/MainActivity.kt similarity index 71% rename from samples/calculator/android/src/main/kotlin/org/konan/calculator/MainActivity.kt rename to samples/calculator/androidApp/src/main/kotlin/MainActivity.kt index 14f1b8f6cfa..b21f0de3060 100644 --- a/samples/calculator/android/src/main/kotlin/org/konan/calculator/MainActivity.kt +++ b/samples/calculator/androidApp/src/main/kotlin/MainActivity.kt @@ -1,10 +1,15 @@ -package org.konan.calculator +/* + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package sample.calculator.android import android.os.Bundle import android.support.v7.app.AppCompatActivity import android.widget.EditText import android.widget.TextView -import org.konan.arithmeticparser.parseAndCompute +import sample.calculator.arithmeticparser.parseAndCompute class MainActivity : AppCompatActivity() { @@ -19,7 +24,7 @@ class MainActivity : AppCompatActivity() { val inputText = input.text.toString() val result = parseAndCompute(inputText).expression with(resultView) { - text = if (result != null) inputText + " = " + result.toString() else "Unable to parse " + inputText + text = if (result != null) inputText + " = " + result.toString() else "Unable to parse $inputText" } true } diff --git a/samples/calculator/android/src/main/res/drawable-v24/ic_launcher_foreground.xml b/samples/calculator/androidApp/src/main/res/drawable-v24/ic_launcher_foreground.xml similarity index 100% rename from samples/calculator/android/src/main/res/drawable-v24/ic_launcher_foreground.xml rename to samples/calculator/androidApp/src/main/res/drawable-v24/ic_launcher_foreground.xml diff --git a/samples/calculator/android/src/main/res/drawable/ic_launcher_background.xml b/samples/calculator/androidApp/src/main/res/drawable/ic_launcher_background.xml similarity index 100% rename from samples/calculator/android/src/main/res/drawable/ic_launcher_background.xml rename to samples/calculator/androidApp/src/main/res/drawable/ic_launcher_background.xml diff --git a/samples/calculator/android/src/main/res/layout/activity_main.xml b/samples/calculator/androidApp/src/main/res/layout/activity_main.xml similarity index 100% rename from samples/calculator/android/src/main/res/layout/activity_main.xml rename to samples/calculator/androidApp/src/main/res/layout/activity_main.xml diff --git a/samples/calculator/android/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/samples/calculator/androidApp/src/main/res/mipmap-anydpi-v26/ic_launcher.xml similarity index 100% rename from samples/calculator/android/src/main/res/mipmap-anydpi-v26/ic_launcher.xml rename to samples/calculator/androidApp/src/main/res/mipmap-anydpi-v26/ic_launcher.xml diff --git a/samples/calculator/android/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/samples/calculator/androidApp/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml similarity index 100% rename from samples/calculator/android/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml rename to samples/calculator/androidApp/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml diff --git a/samples/calculator/android/src/main/res/mipmap-hdpi/ic_launcher.png b/samples/calculator/androidApp/src/main/res/mipmap-hdpi/ic_launcher.png similarity index 100% rename from samples/calculator/android/src/main/res/mipmap-hdpi/ic_launcher.png rename to samples/calculator/androidApp/src/main/res/mipmap-hdpi/ic_launcher.png diff --git a/samples/calculator/android/src/main/res/mipmap-hdpi/ic_launcher_round.png b/samples/calculator/androidApp/src/main/res/mipmap-hdpi/ic_launcher_round.png similarity index 100% rename from samples/calculator/android/src/main/res/mipmap-hdpi/ic_launcher_round.png rename to samples/calculator/androidApp/src/main/res/mipmap-hdpi/ic_launcher_round.png diff --git a/samples/calculator/android/src/main/res/mipmap-mdpi/ic_launcher.png b/samples/calculator/androidApp/src/main/res/mipmap-mdpi/ic_launcher.png similarity index 100% rename from samples/calculator/android/src/main/res/mipmap-mdpi/ic_launcher.png rename to samples/calculator/androidApp/src/main/res/mipmap-mdpi/ic_launcher.png diff --git a/samples/calculator/android/src/main/res/mipmap-mdpi/ic_launcher_round.png b/samples/calculator/androidApp/src/main/res/mipmap-mdpi/ic_launcher_round.png similarity index 100% rename from samples/calculator/android/src/main/res/mipmap-mdpi/ic_launcher_round.png rename to samples/calculator/androidApp/src/main/res/mipmap-mdpi/ic_launcher_round.png diff --git a/samples/calculator/android/src/main/res/mipmap-xhdpi/ic_launcher.png b/samples/calculator/androidApp/src/main/res/mipmap-xhdpi/ic_launcher.png similarity index 100% rename from samples/calculator/android/src/main/res/mipmap-xhdpi/ic_launcher.png rename to samples/calculator/androidApp/src/main/res/mipmap-xhdpi/ic_launcher.png diff --git a/samples/calculator/android/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/samples/calculator/androidApp/src/main/res/mipmap-xhdpi/ic_launcher_round.png similarity index 100% rename from samples/calculator/android/src/main/res/mipmap-xhdpi/ic_launcher_round.png rename to samples/calculator/androidApp/src/main/res/mipmap-xhdpi/ic_launcher_round.png diff --git a/samples/calculator/android/src/main/res/mipmap-xxhdpi/ic_launcher.png b/samples/calculator/androidApp/src/main/res/mipmap-xxhdpi/ic_launcher.png similarity index 100% rename from samples/calculator/android/src/main/res/mipmap-xxhdpi/ic_launcher.png rename to samples/calculator/androidApp/src/main/res/mipmap-xxhdpi/ic_launcher.png diff --git a/samples/calculator/android/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/samples/calculator/androidApp/src/main/res/mipmap-xxhdpi/ic_launcher_round.png similarity index 100% rename from samples/calculator/android/src/main/res/mipmap-xxhdpi/ic_launcher_round.png rename to samples/calculator/androidApp/src/main/res/mipmap-xxhdpi/ic_launcher_round.png diff --git a/samples/calculator/android/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/samples/calculator/androidApp/src/main/res/mipmap-xxxhdpi/ic_launcher.png similarity index 100% rename from samples/calculator/android/src/main/res/mipmap-xxxhdpi/ic_launcher.png rename to samples/calculator/androidApp/src/main/res/mipmap-xxxhdpi/ic_launcher.png diff --git a/samples/calculator/android/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/samples/calculator/androidApp/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png similarity index 100% rename from samples/calculator/android/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png rename to samples/calculator/androidApp/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png diff --git a/samples/calculator/android/src/main/res/values/colors.xml b/samples/calculator/androidApp/src/main/res/values/colors.xml similarity index 100% rename from samples/calculator/android/src/main/res/values/colors.xml rename to samples/calculator/androidApp/src/main/res/values/colors.xml diff --git a/samples/calculator/android/src/main/res/values/strings.xml b/samples/calculator/androidApp/src/main/res/values/strings.xml similarity index 100% rename from samples/calculator/android/src/main/res/values/strings.xml rename to samples/calculator/androidApp/src/main/res/values/strings.xml diff --git a/samples/calculator/android/src/main/res/values/styles.xml b/samples/calculator/androidApp/src/main/res/values/styles.xml similarity index 100% rename from samples/calculator/android/src/main/res/values/styles.xml rename to samples/calculator/androidApp/src/main/res/values/styles.xml diff --git a/samples/calculator/arithmeticParser/build.gradle b/samples/calculator/arithmeticParser/build.gradle new file mode 100644 index 00000000000..d1dd766e449 --- /dev/null +++ b/samples/calculator/arithmeticParser/build.gradle @@ -0,0 +1,80 @@ +apply plugin: 'org.jetbrains.kotlin.multiplatform' + +kotlin { + targets { + fromPreset(determineIosPreset(), 'ios') { + compilations.main.outputKinds 'FRAMEWORK' + } + + fromPreset(presets.jvm, 'jvm') + } + + sourceSets { + commonMain { + dependencies { + api 'org.jetbrains.kotlin:kotlin-stdlib-common' + } + } + jvmMain { + dependencies { + api 'org.jetbrains.kotlin:kotlin-stdlib-jdk8' + } + } + } +} + +// Workaround for https://youtrack.jetbrains.com/issue/KT-27170 +configurations { + compileClasspath +} + +// If custom preset specified in 'calculator.preset.name' property, then use it for building. +// Otherwise build for iPhone simulator (by default). +def determineIosPreset() { + String presetName = project.hasProperty('calculator.preset.name') ? project.properties['calculator.preset.name'] : 'iosX64' + def preset = project.kotlin.presets[presetName] + println("$project has been configured for $presetName platform.") + preset +} + +// Special Gradle task that is called from Xcode. +// Two Gradle properties must be specified for this task: +// - calculator.configuration.name=[Release|Debug] +// - calculator.framework.location +task buildFrameworkForXcode { + doLast { + if (!isCalledFromXcode()) { + throw new Exception("Please run 'buildFrameworkForXcode' task with all necessary properties!") + } + + println("from: ${kotlin.targets.ios.compilations.main.getBinary('FRAMEWORK', getBuildTypeForXcode()).parentFile}") + println("into: ${getXcodeConfigurationBuildDir()}") + + File frameworkDir = kotlin.targets.ios.compilations.main.getBinary('FRAMEWORK', getBuildTypeForXcode()) + + copy { + from frameworkDir.parentFile + into getXcodeConfigurationBuildDir() + include "${frameworkDir.name}/**" + include "${frameworkDir.name}.dSYM/**" + } + } +} + +afterEvaluate { + if (isCalledFromXcode()) { + buildFrameworkForXcode.dependsOn kotlin.targets.ios.compilations.main.linkTaskName('FRAMEWORK', getBuildTypeForXcode()) + } +} + +private boolean isCalledFromXcode() { + project.hasProperty('calculator.configuration.name') && project.hasProperty('calculator.framework.location') +} + +private String getBuildTypeForXcode() { + project.properties['calculator.configuration.name'] as String +} + +private String getXcodeConfigurationBuildDir() { + project.properties['calculator.framework.location'] as String +} diff --git a/samples/calculator/arithmeticParser/gradle.properties b/samples/calculator/arithmeticParser/gradle.properties new file mode 100644 index 00000000000..7fc6f1ff272 --- /dev/null +++ b/samples/calculator/arithmeticParser/gradle.properties @@ -0,0 +1 @@ +kotlin.code.style=official diff --git a/samples/calculator/common/src/main/kotlin/org/konan/arithmeticparser/Parser.kt b/samples/calculator/arithmeticParser/src/commonMain/kotlin/Parser.kt similarity index 88% rename from samples/calculator/common/src/main/kotlin/org/konan/arithmeticparser/Parser.kt rename to samples/calculator/arithmeticParser/src/commonMain/kotlin/Parser.kt index 42b4ddd3d86..b44bb7182c8 100644 --- a/samples/calculator/common/src/main/kotlin/org/konan/arithmeticparser/Parser.kt +++ b/samples/calculator/arithmeticParser/src/commonMain/kotlin/Parser.kt @@ -1,23 +1,12 @@ /* - * Copyright 2010-2017 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. */ -package org.konan.arithmeticparser +package sample.calculator.arithmeticparser fun parseAndCompute(expression: String): PartialParser.Result = - PartialParser(Calculator(), PartialRenderer()).parseWithPartial(expression) + PartialParser(Calculator(), PartialRenderer()).parseWithPartial(expression) class Calculator : ExpressionComposer { override fun number(value: Double) = value @@ -47,7 +36,7 @@ interface ExpressionComposer { fun div(left: E, right: E): E } -open class Parser(protected val composer: ExpressionComposer) { +open class Parser(private val composer: ExpressionComposer) { fun parse(expression: String): E? { val tokenizer = Tokenizer(expression) val prefix = parseAsPrefix(tokenizer) @@ -70,12 +59,10 @@ open class Parser(protected val composer: ExpressionComposer) { private fun ExpressionPrefix.tryExtend(tokenizer: Tokenizer): ExpressionPrefix? = when (this) { is ContinuableWithExpression -> { val number = tokenizer.tryReadNumber() - if (number != null) { - this.with(composer.number(number)) - } else if (tokenizer.tryReadLeftParenthesis()) { - this.withLeftParenthesis() - } else { - null + when { + number != null -> this.with(composer.number(number)) + tokenizer.tryReadLeftParenthesis() -> this.withLeftParenthesis() + else -> null } } @@ -221,7 +208,7 @@ internal data class EndedWithExpression( internal sealed class ContinuableWithExpression : ExpressionPrefix() private fun ContinuableWithExpression.with(expression: E) = - EndedWithExpression(this, expression) + EndedWithExpression(this, expression) private object Empty : ContinuableWithExpression() @@ -230,7 +217,7 @@ private data class EndedWithLeftParenthesis( ) : ContinuableWithExpression() private fun ContinuableWithExpression.withLeftParenthesis() = - EndedWithLeftParenthesis(this) + EndedWithLeftParenthesis(this) private data class EndedWithOperator( val prefix: ContinuableWithExpression, diff --git a/samples/calculator/build.gradle b/samples/calculator/build.gradle index 7faf89c1313..7113c2ebbc8 100644 --- a/samples/calculator/build.gradle +++ b/samples/calculator/build.gradle @@ -1,23 +1,24 @@ -allprojects { - buildscript { - repositories { - maven { url "https://dl.bintray.com/kotlin/kotlin-dev" } - } - } - +buildscript { repositories { - maven { url "https://dl.bintray.com/kotlin/kotlin-dev" } + google() + jcenter() + mavenCentral() + maven { url 'https://dl.bintray.com/kotlin/kotlin-dev' } + maven { url 'https://dl.bintray.com/kotlin/kotlin-eap' } + } + + dependencies { + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + classpath 'com.android.tools.build:gradle:3.2.1' } } -task build { - subprojects.each { - dependsOn("${it.path}:build") - } -} - -task clean { - subprojects.each { - dependsOn("${it.path}:clean") +allprojects { + repositories { + google() + jcenter() + mavenCentral() + maven { url 'https://dl.bintray.com/kotlin/kotlin-dev' } + maven { url 'https://dl.bintray.com/kotlin/kotlin-eap' } } } diff --git a/samples/calculator/build.sh b/samples/calculator/build.sh new file mode 100755 index 00000000000..a26f890f026 --- /dev/null +++ b/samples/calculator/build.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash + +DIR=$(cd "$(dirname "${BASH_SOURCE[0]}" )" && pwd ) + +$DIR/../gradlew -p $DIR assemble diff --git a/samples/calculator/cliApp/build.gradle b/samples/calculator/cliApp/build.gradle new file mode 100644 index 00000000000..2197c99386a --- /dev/null +++ b/samples/calculator/cliApp/build.gradle @@ -0,0 +1,22 @@ +apply plugin: 'org.jetbrains.kotlin.multiplatform' + +kotlin { + targets { + fromPreset(presets.jvm, 'jvm') + } + + sourceSets { + jvmMain { + dependencies { + implementation project(':arithmeticParser') + } + } + } +} + +task runProgram(type: JavaExec) { + dependsOn assemble + main = 'sample.calculator.jvm.JvmCli' + classpath = files(kotlin.targets.jvm.compilations.main.output) + kotlin.targets.jvm.compilations.main.runtimeDependencyFiles + args '2 + 3' +} diff --git a/samples/calculator/cliApp/gradle.properties b/samples/calculator/cliApp/gradle.properties new file mode 100644 index 00000000000..790a07d5124 --- /dev/null +++ b/samples/calculator/cliApp/gradle.properties @@ -0,0 +1,2 @@ +kotlin.code.style=official +kotlin.import.noCommonSourceSets=true diff --git a/samples/calculator/jvm/src/main/kotlin/org/konan/calculator/JvmCli.kt b/samples/calculator/cliApp/src/jvmMain/kotlin/JvmCli.kt similarity index 62% rename from samples/calculator/jvm/src/main/kotlin/org/konan/calculator/JvmCli.kt rename to samples/calculator/cliApp/src/jvmMain/kotlin/JvmCli.kt index 124b0c9378d..f3554b27666 100644 --- a/samples/calculator/jvm/src/main/kotlin/org/konan/calculator/JvmCli.kt +++ b/samples/calculator/cliApp/src/jvmMain/kotlin/JvmCli.kt @@ -1,11 +1,17 @@ -package org.konan.calculator +/* + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ +@file:JvmName("JvmCli") -import org.konan.arithmeticparser.* +package sample.calculator.jvm + +import sample.calculator.arithmeticparser.parseAndCompute fun main(args: Array) { val expression = if (args.isNotEmpty()) { args.first().also { - println(it) + print(it) } } else { println("Enter an expression:") diff --git a/samples/calculator/common/build.gradle b/samples/calculator/common/build.gradle deleted file mode 100644 index 81b0de4d771..00000000000 --- a/samples/calculator/common/build.gradle +++ /dev/null @@ -1,23 +0,0 @@ -buildscript { - ext.kotlin_version = '1.3.0-rc-6' - - repositories { - mavenCentral() - } - - dependencies { - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - } -} - -apply plugin: 'kotlin-platform-common' - -group = 'org.jetbrains.kotlin.konan.samples' - -repositories { - mavenCentral() -} - -dependencies { - compile "org.jetbrains.kotlin:kotlin-stdlib-common:$kotlin_version" -} diff --git a/samples/calculator/gradle.properties b/samples/calculator/gradle.properties index 0737650d23e..23f4b0b5150 100644 --- a/samples/calculator/gradle.properties +++ b/samples/calculator/gradle.properties @@ -1,2 +1,4 @@ -konan.home=../../../dist -konan.plugin.version=+ \ No newline at end of file +kotlin.code.style=official + +# Use custom Kotlin/Native home: +org.jetbrains.kotlin.native.home=../../../dist diff --git a/samples/calculator/gradle/wrapper/gradle-wrapper.jar b/samples/calculator/gradle/wrapper/gradle-wrapper.jar index 29953ea141f..91ca28c8b80 100644 Binary files a/samples/calculator/gradle/wrapper/gradle-wrapper.jar and b/samples/calculator/gradle/wrapper/gradle-wrapper.jar differ diff --git a/samples/calculator/gradle/wrapper/gradle-wrapper.properties b/samples/calculator/gradle/wrapper/gradle-wrapper.properties index d76b502e226..e6a30918ef8 100644 --- a/samples/calculator/gradle/wrapper/gradle-wrapper.properties +++ b/samples/calculator/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.7-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/samples/calculator/ios/build.gradle b/samples/calculator/ios/build.gradle deleted file mode 100644 index c2b151aa897..00000000000 --- a/samples/calculator/ios/build.gradle +++ /dev/null @@ -1,25 +0,0 @@ -buildscript { - repositories { - mavenCentral() - maven { url "https://dl.bintray.com/jetbrains/kotlin-native-dependencies" } - } - - dependencies { - classpath "org.jetbrains.kotlin:kotlin-native-gradle-plugin:${project.property('konan.plugin.version')}" - } -} - -apply plugin: 'konan' - -konan.targets = ['iphone', 'iphone_sim'] - -konanArtifacts { - framework('KotlinArithmeticParser') { - enableMultiplatform true - } -} - -dependencies { - expectedBy project(':common') -} - diff --git a/samples/calculator/ios/calculator.xcodeproj/project.pbxproj b/samples/calculator/iosApp/calculator.xcodeproj/project.pbxproj similarity index 84% rename from samples/calculator/ios/calculator.xcodeproj/project.pbxproj rename to samples/calculator/iosApp/calculator.xcodeproj/project.pbxproj index c2f8fe16638..dd027b1e0c7 100644 --- a/samples/calculator/ios/calculator.xcodeproj/project.pbxproj +++ b/samples/calculator/iosApp/calculator.xcodeproj/project.pbxproj @@ -12,8 +12,8 @@ 2C3F384A1FD1738300151601 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 2C3F38481FD1738300151601 /* Main.storyboard */; }; 2C3F384C1FD1738300151601 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 2C3F384B1FD1738300151601 /* Assets.xcassets */; }; 2C3F384F1FD1738300151601 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 2C3F384D1FD1738300151601 /* LaunchScreen.storyboard */; }; - 7FE128BF205854BA0064CE74 /* KotlinArithmeticParser.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 7FF94AD92058464C00590D0D /* KotlinArithmeticParser.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 7FF94AE32058483900590D0D /* KotlinArithmeticParser.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7FF94AD92058464C00590D0D /* KotlinArithmeticParser.framework */; }; + 7FE128BF205854BA0064CE74 /* arithmeticParser.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 7FF94AD92058464C00590D0D /* arithmeticParser.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 7FF94AE32058483900590D0D /* arithmeticParser.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7FF94AD92058464C00590D0D /* arithmeticParser.framework */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -23,7 +23,7 @@ dstPath = ""; dstSubfolderSpec = 10; files = ( - 7FE128BF205854BA0064CE74 /* KotlinArithmeticParser.framework in Embed Frameworks */, + 7FE128BF205854BA0064CE74 /* arithmeticParser.framework in Embed Frameworks */, ); name = "Embed Frameworks"; runOnlyForDeploymentPostprocessing = 0; @@ -38,7 +38,7 @@ 2C3F384B1FD1738300151601 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 2C3F384E1FD1738300151601 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 2C3F38501FD1738300151601 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 7FF94AD92058464C00590D0D /* KotlinArithmeticParser.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = KotlinArithmeticParser.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 7FF94AD92058464C00590D0D /* arithmeticParser.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = arithmeticParser.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 7FF94AEA2058485300590D0D /* Parser.kt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Parser.kt; sourceTree = ""; }; /* End PBXFileReference section */ @@ -47,7 +47,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 7FF94AE32058483900590D0D /* KotlinArithmeticParser.framework in Frameworks */, + 7FF94AE32058483900590D0D /* arithmeticParser.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -58,7 +58,7 @@ isa = PBXGroup; children = ( 2C3F38431FD1738300151601 /* calculator */, - 7FF94ADA2058464C00590D0D /* KotlinArithmeticParser */, + 7FF94ADA2058464C00590D0D /* arithmeticParser */, 2C3F38421FD1738300151601 /* Products */, 7FF94AE22058483900590D0D /* Frameworks */, ); @@ -68,7 +68,7 @@ isa = PBXGroup; children = ( 2C3F38411FD1738300151601 /* KotlinCalculator.app */, - 7FF94AD92058464C00590D0D /* KotlinArithmeticParser.framework */, + 7FF94AD92058464C00590D0D /* arithmeticParser.framework */, ); name = Products; sourceTree = ""; @@ -86,12 +86,12 @@ path = calculator; sourceTree = ""; }; - 7FF94ADA2058464C00590D0D /* KotlinArithmeticParser */ = { + 7FF94ADA2058464C00590D0D /* arithmeticParser */ = { isa = PBXGroup; children = ( 7FF94AE42058485300590D0D /* src */, ); - name = KotlinArithmeticParser; + name = arithmeticParser; sourceTree = ""; }; 7FF94AE22058483900590D0D /* Frameworks */ = { @@ -104,50 +104,26 @@ 7FF94AE42058485300590D0D /* src */ = { isa = PBXGroup; children = ( - 7FF94AE52058485300590D0D /* main */, + 7FF94AE52058485300590D0D /* commonMain */, ); name = src; - path = ../common/src; + path = ../arithmeticParser/src; sourceTree = SOURCE_ROOT; }; - 7FF94AE52058485300590D0D /* main */ = { + 7FF94AE52058485300590D0D /* commonMain */ = { isa = PBXGroup; children = ( 7FF94AE62058485300590D0D /* kotlin */, ); - path = main; + path = commonMain; sourceTree = ""; }; 7FF94AE62058485300590D0D /* kotlin */ = { - isa = PBXGroup; - children = ( - 7FF94AE72058485300590D0D /* org */, - ); - path = kotlin; - sourceTree = ""; - }; - 7FF94AE72058485300590D0D /* org */ = { - isa = PBXGroup; - children = ( - 7FF94AE82058485300590D0D /* konan */, - ); - path = org; - sourceTree = ""; - }; - 7FF94AE82058485300590D0D /* konan */ = { - isa = PBXGroup; - children = ( - 7FF94AE92058485300590D0D /* arithmeticparser */, - ); - path = konan; - sourceTree = ""; - }; - 7FF94AE92058485300590D0D /* arithmeticparser */ = { isa = PBXGroup; children = ( 7FF94AEA2058485300590D0D /* Parser.kt */, ); - path = arithmeticparser; + path = kotlin; sourceTree = ""; }; /* End PBXGroup section */ @@ -171,9 +147,9 @@ productReference = 2C3F38411FD1738300151601 /* KotlinCalculator.app */; productType = "com.apple.product-type.application"; }; - 7FF94AD82058464C00590D0D /* KotlinArithmeticParser */ = { + 7FF94AD82058464C00590D0D /* arithmeticParser */ = { isa = PBXNativeTarget; - buildConfigurationList = 7FF94ADE2058464C00590D0D /* Build configuration list for PBXNativeTarget "KotlinArithmeticParser" */; + buildConfigurationList = 7FF94ADE2058464C00590D0D /* Build configuration list for PBXNativeTarget "arithmeticParser" */; buildPhases = ( 7FF94AE12058466D00590D0D /* Compile Kotlin/Native */, ); @@ -181,9 +157,9 @@ ); dependencies = ( ); - name = KotlinArithmeticParser; - productName = KotlinArithmeticParser; - productReference = 7FF94AD92058464C00590D0D /* KotlinArithmeticParser.framework */; + name = arithmeticParser; + productName = arithmeticParser; + productReference = 7FF94AD92058464C00590D0D /* arithmeticParser.framework */; productType = "com.apple.product-type.framework"; }; /* End PBXNativeTarget section */ @@ -220,7 +196,7 @@ projectRoot = ""; targets = ( 2C3F38401FD1738300151601 /* KotlinCalculator */, - 7FF94AD82058464C00590D0D /* KotlinArithmeticParser */, + 7FF94AD82058464C00590D0D /* arithmeticParser */, ); }; /* End PBXProject section */ @@ -251,7 +227,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"$SRCROOT/../gradlew\" -p \"$SRCROOT\" \"$KONAN_TASK\" \\\n-Pkonan.configuration.build.dir=\"$CONFIGURATION_BUILD_DIR\" \\\n-Pkonan.debugging.symbols=\"$DEBUGGING_SYMBOLS\" \\\n-Pkonan.optimizations.enable=\"$KONAN_ENABLE_OPTIMIZATIONS\""; + shellScript = "\"$SRCROOT/../gradlew\" -p \"$SRCROOT/..\" buildFrameworkForXcode \\\n-Pcalculator.preset.name=\"$KOTLIN_NATIVE_PRESET\" \\\n-Pcalculator.configuration.name=\"$CONFIGURATION\" \\\n-Pcalculator.framework.location=\"$CONFIGURATION_BUILD_DIR\"\n"; }; /* End PBXShellScriptBuildPhase section */ @@ -445,12 +421,10 @@ DYLIB_INSTALL_NAME_BASE = "@rpath"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 11.2; - KONAN_ENABLE_OPTIMIZATIONS = NO; - KONAN_TASK = ""; - "KONAN_TASK[sdk=iphoneos*]" = compileKonanKotlinArithmeticParserIos_arm64; - "KONAN_TASK[sdk=iphonesimulator*]" = compileKonanKotlinArithmeticParserIos_x64; + "KOTLIN_NATIVE_PRESET[sdk=iphoneos*]" = iosArm64; + "KOTLIN_NATIVE_PRESET[sdk=iphonesimulator*]" = iosX64; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = JetBrains.KotlinArithmeticParser; + PRODUCT_BUNDLE_IDENTIFIER = JetBrains.arithmeticParser; PRODUCT_MODULE_NAME = "_$(PRODUCT_NAME:c99extidentifier)"; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -475,12 +449,10 @@ DYLIB_INSTALL_NAME_BASE = "@rpath"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 11.2; - KONAN_ENABLE_OPTIMIZATIONS = YES; - KONAN_TASK = ""; - "KONAN_TASK[sdk=iphoneos*]" = compileKonanKotlinArithmeticParserIos_arm64; - "KONAN_TASK[sdk=iphonesimulator*]" = compileKonanKotlinArithmeticParserIos_x64; + "KOTLIN_NATIVE_PRESET[sdk=iphoneos*]" = iosArm64; + "KOTLIN_NATIVE_PRESET[sdk=iphonesimulator*]" = iosX64; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = JetBrains.KotlinArithmeticParser; + PRODUCT_BUNDLE_IDENTIFIER = JetBrains.arithmeticParser; PRODUCT_MODULE_NAME = "_$(PRODUCT_NAME:c99extidentifier)"; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -513,7 +485,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 7FF94ADE2058464C00590D0D /* Build configuration list for PBXNativeTarget "KotlinArithmeticParser" */ = { + 7FF94ADE2058464C00590D0D /* Build configuration list for PBXNativeTarget "arithmeticParser" */ = { isa = XCConfigurationList; buildConfigurations = ( 7FF94ADF2058464C00590D0D /* Debug */, diff --git a/samples/calculator/ios/calculator.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/samples/calculator/iosApp/calculator.xcodeproj/project.xcworkspace/contents.xcworkspacedata similarity index 100% rename from samples/calculator/ios/calculator.xcodeproj/project.xcworkspace/contents.xcworkspacedata rename to samples/calculator/iosApp/calculator.xcodeproj/project.xcworkspace/contents.xcworkspacedata diff --git a/samples/calculator/iosApp/calculator.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/samples/calculator/iosApp/calculator.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 00000000000..18d981003d6 --- /dev/null +++ b/samples/calculator/iosApp/calculator.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/samples/calculator/ios/calculator/AppDelegate.swift b/samples/calculator/iosApp/calculator/AppDelegate.swift similarity index 92% rename from samples/calculator/ios/calculator/AppDelegate.swift rename to samples/calculator/iosApp/calculator/AppDelegate.swift index 86c713afed7..b813994f762 100644 --- a/samples/calculator/ios/calculator/AppDelegate.swift +++ b/samples/calculator/iosApp/calculator/AppDelegate.swift @@ -1,9 +1,6 @@ // -// AppDelegate.swift -// calculator -// -// Created by jetbrains on 01/12/2017. -// Copyright Âİ 2017 JetBrains. All rights reserved. +// Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license +// that can be found in the license/LICENSE.txt file. // import UIKit diff --git a/samples/calculator/ios/calculator/Assets.xcassets/AppIcon.appiconset/Contents.json b/samples/calculator/iosApp/calculator/Assets.xcassets/AppIcon.appiconset/Contents.json similarity index 94% rename from samples/calculator/ios/calculator/Assets.xcassets/AppIcon.appiconset/Contents.json rename to samples/calculator/iosApp/calculator/Assets.xcassets/AppIcon.appiconset/Contents.json index 1d060ed2882..d8db8d65fd7 100644 --- a/samples/calculator/ios/calculator/Assets.xcassets/AppIcon.appiconset/Contents.json +++ b/samples/calculator/iosApp/calculator/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -84,6 +84,11 @@ "idiom" : "ipad", "size" : "83.5x83.5", "scale" : "2x" + }, + { + "idiom" : "ios-marketing", + "size" : "1024x1024", + "scale" : "1x" } ], "info" : { diff --git a/samples/calculator/ios/calculator/Base.lproj/LaunchScreen.storyboard b/samples/calculator/iosApp/calculator/Base.lproj/LaunchScreen.storyboard similarity index 100% rename from samples/calculator/ios/calculator/Base.lproj/LaunchScreen.storyboard rename to samples/calculator/iosApp/calculator/Base.lproj/LaunchScreen.storyboard diff --git a/samples/calculator/ios/calculator/Base.lproj/Main.storyboard b/samples/calculator/iosApp/calculator/Base.lproj/Main.storyboard similarity index 100% rename from samples/calculator/ios/calculator/Base.lproj/Main.storyboard rename to samples/calculator/iosApp/calculator/Base.lproj/Main.storyboard diff --git a/samples/calculator/ios/calculator/Info.plist b/samples/calculator/iosApp/calculator/Info.plist similarity index 100% rename from samples/calculator/ios/calculator/Info.plist rename to samples/calculator/iosApp/calculator/Info.plist diff --git a/samples/calculator/ios/calculator/ViewController.swift b/samples/calculator/iosApp/calculator/ViewController.swift similarity index 96% rename from samples/calculator/ios/calculator/ViewController.swift rename to samples/calculator/iosApp/calculator/ViewController.swift index fecc52facbd..7edae128315 100644 --- a/samples/calculator/ios/calculator/ViewController.swift +++ b/samples/calculator/iosApp/calculator/ViewController.swift @@ -1,13 +1,10 @@ // -// ViewController.swift -// calculator -// -// Created by jetbrains on 01/12/2017. -// Copyright Âİ 2017 JetBrains. All rights reserved. +// Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license +// that can be found in the license/LICENSE.txt file. // import UIKit -import KotlinArithmeticParser +import arithmeticParser class ViewController: UIViewController, UITextViewDelegate, UICollectionViewDataSource { diff --git a/samples/calculator/jvm/build.gradle b/samples/calculator/jvm/build.gradle deleted file mode 100644 index 4ea69932403..00000000000 --- a/samples/calculator/jvm/build.gradle +++ /dev/null @@ -1,30 +0,0 @@ -buildscript { - ext.kotlin_version = '1.3.0-rc-6' - - repositories { - mavenCentral() - } - - dependencies { - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - } -} - -apply plugin: 'kotlin-platform-jvm' -apply plugin: 'application' - -repositories { - mavenCentral() -} - -dependencies { - compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" - expectedBy project(":common") -} - -applicationName = "KotlinCalculator" - -mainClassName = 'org.konan.calculator.JvmCliKt' -run { - args "2 + 2" -} diff --git a/samples/calculator/settings.gradle b/samples/calculator/settings.gradle index ad596ac6907..4df713ebf56 100644 --- a/samples/calculator/settings.gradle +++ b/samples/calculator/settings.gradle @@ -1,17 +1,37 @@ -include ':common' -include ':jvm' -include ':ios' - -def localProperties = new Properties() -def localPropertiesFile = file('local.properties') -if (localPropertiesFile.exists()) { - localPropertiesFile.withReader { localProperties.load(it) } +// Reuse Kotlin version from the root project. +File rootProjectGradlePropertiesFile = file("${rootProject.projectDir}/../gradle.properties") +if (!rootProjectGradlePropertiesFile.isFile()) { + throw new Exception("File $rootProjectGradlePropertiesFile does not exist or is not a file") } +Properties rootProjectProperties = new Properties() +rootProjectGradlePropertiesFile.withInputStream { inputStream -> + rootProjectProperties.load(inputStream) + if (!rootProjectProperties.containsKey('kotlin_version')) { + throw new Exception("No 'kotlin_version' property in $rootProjectGradlePropertiesFile file") + } +} + +gradle.beforeProject { project -> + rootProjectProperties.forEach { String key, value -> + if (!project.hasProperty(key)) + project.ext[key] = value + } +} + +include ':arithmeticParser' +include ':cliApp' + +boolean sdkDirPropertySpecified = false +File localPropertiesFile = file("${rootProject.projectDir}/local.properties") +if (localPropertiesFile.isFile()) { + Properties properties = new Properties() + localPropertiesFile.withInputStream { inputStream -> properties.load(inputStream) } + sdkDirPropertySpecified = properties.containsKey('sdk.dir') +} + + // Don't create Android tasks if a user has no Android SDK. -if (localProperties.containsKey("sdk.dir") || System.getenv('ANDROID_HOME') != null) { - include ':android' +if (sdkDirPropertySpecified || System.getenv('ANDROID_HOME') != null) { + include ':androidApp' } - -includeBuild '../../shared' -includeBuild '../../tools/kotlin-native-gradle-plugin' diff --git a/samples/csvparser/European_Mammals_Red_List_Nov_2009.csv b/samples/csvparser/European_Mammals_Red_List_Nov_2009.csv old mode 100755 new mode 100644 diff --git a/samples/csvparser/README.md b/samples/csvparser/README.md index 1987f9e8015..d2deb9efa94 100644 --- a/samples/csvparser/README.md +++ b/samples/csvparser/README.md @@ -1,14 +1,14 @@ # CSV parser - This example shows how one could implement simple comma separated values reader and parser in Kotlin. +This example shows how one could implement simple comma separated values reader and parser in Kotlin. 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 assemble` or `./build.sh`. +To build use `../gradlew assemble`. -Now you can run artifact directly +To run use `../gradlew runProgram` or execute the program directly: - ./build/exe/main/release/csvparser.kexe ./European_Mammals_Red_List_Nov_2009.csv 4 100 + ./build/bin/csvParser/main/release/executable/csvparser.kexe ./European_Mammals_Red_List_Nov_2009.csv 4 100 It will print number of all unique entries in fifth column (Family, zero-based index) in first 100 rows of the CSV file. diff --git a/samples/csvparser/build.bat b/samples/csvparser/build.bat deleted file mode 100644 index 6132c58b110..00000000000 --- a/samples/csvparser/build.bat +++ /dev/null @@ -1,16 +0,0 @@ -@echo off - -setlocal - -set DIR=. - -if defined KONAN_HOME ( - set "PATH=%KONAN_HOME%\bin;%PATH%" -) else ( - set "PATH=..\..\dist\bin;..\..\bin;%PATH%" -) - -if "%TARGET%" == "" set TARGET=mingw - -call konanc -target "%TARGET%" "%DIR%\src\main\kotlin\CsvParser.kt" -o CsvParser -exit /b %ERRORLEVEL% diff --git a/samples/csvparser/build.gradle b/samples/csvparser/build.gradle index dc821bd5983..734da2f66da 100644 --- a/samples/csvparser/build.gradle +++ b/samples/csvparser/build.gradle @@ -1,5 +1,16 @@ -apply plugin: 'org.jetbrains.kotlin.platform.native' +plugins { + id 'kotlin-multiplatform' +} -components.main { - outputKinds = [ EXECUTABLE ] -} \ No newline at end of file +kotlin { + targets { + fromPreset(MPPTools.defaultHostPreset(project), 'csvParser') { + compilations.main.outputKinds 'EXECUTABLE' + compilations.main.entryPoint 'sample.csvparser.main' + } + } +} + +MPPTools.createRunTask(project, 'runProgram', kotlin.targets.csvParser) { + args './European_Mammals_Red_List_Nov_2009.csv', 4, 100 +} diff --git a/samples/csvparser/build.sh b/samples/csvparser/build.sh deleted file mode 100755 index bc48c94b84f..00000000000 --- a/samples/csvparser/build.sh +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env bash - -DIR=$(cd "$(dirname "${BASH_SOURCE[0]}" )" && pwd ) - -source "$DIR/../konan.sh" - -if [ x$TARGET == x ]; then -case "$OSTYPE" in - darwin*) TARGET=macbook ;; - linux*) TARGET=linux ;; - msys*) TARGET=mingw ;; - *) echo "unknown: $OSTYPE" && exit 1;; -esac -fi - -var=CFLAGS_${TARGET} -CFLAGS=${!var} -var=LINKER_ARGS_${TARGET} -LINKER_ARGS=${!var} -var=COMPILER_ARGS_${TARGET} -COMPILER_ARGS=${!var} # add -opt for an optimized build. - -mkdir -p $DIR/build/c_interop/ -mkdir -p $DIR/build/bin/ - -konanc $COMPILER_ARGS -target $TARGET $DIR/src/main/kotlin/CsvParser.kt \ - -o $DIR/build/bin/CsvParser || exit 1 - -echo "Artifact path is $DIR/build/bin/CsvParser.kexe" diff --git a/samples/csvparser/gradle.properties b/samples/csvparser/gradle.properties index 54639beb5fa..790a07d5124 100644 --- a/samples/csvparser/gradle.properties +++ b/samples/csvparser/gradle.properties @@ -1 +1,2 @@ -runArgs=./European_Mammals_Red_List_Nov_2009.csv 4 100 \ No newline at end of file +kotlin.code.style=official +kotlin.import.noCommonSourceSets=true diff --git a/samples/csvparser/src/main/kotlin/CsvParser.kt b/samples/csvparser/src/csvParserMain/kotlin/CsvParser.kt similarity index 71% rename from samples/csvparser/src/main/kotlin/CsvParser.kt rename to samples/csvparser/src/csvParserMain/kotlin/CsvParser.kt index 1d931da2d58..a565d74de60 100644 --- a/samples/csvparser/src/main/kotlin/CsvParser.kt +++ b/samples/csvparser/src/csvParserMain/kotlin/CsvParser.kt @@ -1,19 +1,10 @@ /* - * Copyright 2010-2017 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. */ +package sample.csvparser + import kotlinx.cinterop.* import platform.posix.* @@ -40,7 +31,7 @@ fun parseLine(line: String, separator: Char) : List { fun main(args: Array) { if (args.size != 3) { - println("usage: csvparser.kexe file.csv column count") + println("Usage: csvparser.kexe ") return } val fileName = args[0] diff --git a/samples/curl/README.md b/samples/curl/README.md index 632e68216a0..c0567cdcfcc 100644 --- a/samples/curl/README.md +++ b/samples/curl/README.md @@ -3,11 +3,11 @@ This example shows how to communicate with libcurl, HTTP/HTTPS/FTP/etc client library and how to 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 assemble`. -Now you can run the client directly +To run use `../gradlew runProgram` or execute the program directly: - ./build/exe/main/release//curl.kexe https://www.jetbrains.com + ./build/bin/curl/main/release/executable/curl.kexe 'https://www.jetbrains.com/' It will perform HTTP get and print out the data obtained. diff --git a/samples/curl/build.gradle b/samples/curl/build.gradle index 27f5b43a3aa..96a57748fba 100644 --- a/samples/curl/build.gradle +++ b/samples/curl/build.gradle @@ -1,33 +1,58 @@ -buildscript { - repositories { - maven { - url 'https://cache-redirector.jetbrains.com/maven-central' - } - maven { - url "https://dl.bintray.com/jetbrains/kotlin-native-dependencies" - } - } +import java.nio.file.Paths - dependencies { - classpath "org.jetbrains.kotlin:kotlin-native-gradle-plugin:${project.property('konan.plugin.version')}" - } +plugins { + id 'kotlin-multiplatform' } -apply plugin: 'org.jetbrains.kotlin.platform.native' - -def localMavenRepo="file://${new File(System.properties['user.home'] as String)}/.m2-kotlin-native" +def localRepo = rootProject.file('build/.m2-repo') repositories { - maven { - url = localMavenRepo + maven { url = "file://$localRepo" } +} + +kotlin { + presets { + // Determine host preset. + MPPTools.defaultHostPreset(project, [macosX64, linuxX64]) + } + + targets { + fromPreset(hostPreset, 'curl') { + compilations.main.outputKinds 'EXECUTABLE' + compilations.main.entryPoint 'sample.curl.main' + } + } + + sourceSets { + curlMain { + dependencies { + implementation 'org.jetbrains.kotlin.sample.native:libcurl:1.0' + } + } } } -components.main { - targets = ['macos_x64', 'linux_x64'] - outputKinds = [ EXECUTABLE ] +MPPTools.createRunTask(project, 'runProgram', kotlin.targets.curl) { + args 'https://www.jetbrains.com/' +} - dependencies { - implementation 'org.jetbrains.kotlin.native:libcurl:1.0' +// The code snippet below is needed to make all compile tasks depend on publication of +// "libcurl" library. So that to the time of compilation the library will already be +// in Maven repo and will be successfully resolved as a dependency of this project. +tasks.withType(AbstractCompile) { + dependsOn ':libcurl:publish' +} + +// The following snippet is needed to give instructions for IDEA user who just imported project +// and sees "Could not resolve..." message in IDEA console. +gradle.buildFinished { + String configurationName = kotlin.targets.curl.compilations.main.compileDependencyConfigurationName + Configuration configuration = project.configurations.getByName(configurationName) + if (configuration.canBeResolved && configuration.state == Configuration.State.RESOLVED_WITH_FAILURES) { + println( + "\nIMPORTANT:\n" + + "\tThe message about unresolved \"libcurl\" dependency likely means that \"libcurl\" has not been built and published to local Maven repo yet.\n" + + "\tPlease run \"publish\" task for \"libcurl\" sub-project and re-import Kotlin/Native samples in IDEA.\n" + ) } } diff --git a/samples/curl/gradle.properties b/samples/curl/gradle.properties index cdb70994cf8..790a07d5124 100644 --- a/samples/curl/gradle.properties +++ b/samples/curl/gradle.properties @@ -1,2 +1,2 @@ -konan.home=../../dist -konan.plugin.version=+ \ No newline at end of file +kotlin.code.style=official +kotlin.import.noCommonSourceSets=true diff --git a/samples/curl/gradle/wrapper/gradle-wrapper.jar b/samples/curl/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index 29953ea141f..00000000000 Binary files a/samples/curl/gradle/wrapper/gradle-wrapper.jar and /dev/null differ diff --git a/samples/curl/gradle/wrapper/gradle-wrapper.properties b/samples/curl/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index d76b502e226..00000000000 --- a/samples/curl/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,5 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists diff --git a/samples/curl/gradlew b/samples/curl/gradlew deleted file mode 100755 index cccdd3d517f..00000000000 --- a/samples/curl/gradlew +++ /dev/null @@ -1,172 +0,0 @@ -#!/usr/bin/env sh - -############################################################################## -## -## Gradle start up script for UN*X -## -############################################################################## - -# Attempt to set APP_HOME -# Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null - -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" - -warn () { - echo "$*" -} - -die () { - echo - echo "$*" - echo - exit 1 -} - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; - NONSTOP* ) - nonstop=true - ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi -fi - -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi - -# For Cygwin, switch paths to Windows format before running java -if $cygwin ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi - # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" - fi - i=$((i+1)) - done - case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac -fi - -# Escape application args -save () { - for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done - echo " " -} -APP_ARGS=$(save "$@") - -# Collect all arguments for the java command, following the shell quoting and substitution rules -eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" - -# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong -if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then - cd "$(dirname "$0")" -fi - -exec "$JAVACMD" "$@" diff --git a/samples/curl/gradlew.bat b/samples/curl/gradlew.bat deleted file mode 100644 index e95643d6a2c..00000000000 --- a/samples/curl/gradlew.bat +++ /dev/null @@ -1,84 +0,0 @@ -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto init - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:init -@rem Get command-line arguments, handling Windows variants - -if not "%OS%" == "Windows_NT" goto win9xME_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/samples/curl/libcurl.iml b/samples/curl/libcurl.iml deleted file mode 100755 index f7bc7ef6e74..00000000000 --- a/samples/curl/libcurl.iml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - \ No newline at end of file diff --git a/samples/curl/settings.gradle b/samples/curl/settings.gradle deleted file mode 100644 index d0193c301cd..00000000000 --- a/samples/curl/settings.gradle +++ /dev/null @@ -1,4 +0,0 @@ -enableFeaturePreview('GRADLE_METADATA') - -includeBuild '../../shared' -includeBuild '../../tools/kotlin-native-gradle-plugin' diff --git a/samples/curl/src/main/kotlin/main.kt b/samples/curl/src/curlMain/kotlin/main.kt similarity index 56% rename from samples/curl/src/main/kotlin/main.kt rename to samples/curl/src/curlMain/kotlin/main.kt index 12bfa7089b6..08fee5cc267 100644 --- a/samples/curl/src/main/kotlin/main.kt +++ b/samples/curl/src/curlMain/kotlin/main.kt @@ -1,7 +1,14 @@ -import org.konan.libcurl.* +/* + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package sample.curl + +import sample.libcurl.* fun main(args: Array) { - if (args.size == 0) + if (args.isEmpty()) return help() val curl = CUrl(args[0]) diff --git a/samples/echoServer/README.md b/samples/echoServer/README.md new file mode 100644 index 00000000000..95486f2f17b --- /dev/null +++ b/samples/echoServer/README.md @@ -0,0 +1,15 @@ +# Sockets demo + +To build use `../gradlew assemble`. + +To run use `../gradlew runProgram` or execute the program directly: + + ./build/bin/echoServer/main/release/executable/echoServer.kexe 3000 & + +Test the server by connecting to it, for example with telnet: + + telnet localhost 3000 + +Write something to console and watch server echoing it back. + +~~Quit telnet by pressing ctrl+] ctrl+D~~ diff --git a/samples/echoServer/build.gradle b/samples/echoServer/build.gradle new file mode 100644 index 00000000000..b77542d36e8 --- /dev/null +++ b/samples/echoServer/build.gradle @@ -0,0 +1,16 @@ +plugins { + id 'kotlin-multiplatform' +} + +kotlin { + targets { + fromPreset(MPPTools.defaultHostPreset(project), 'echoServer') { + compilations.main.outputKinds 'EXECUTABLE' + compilations.main.entryPoint 'sample.echoserver.main' + } + } +} + +MPPTools.createRunTask(project, 'runProgram', kotlin.targets.echoServer) { + args 3000 +} diff --git a/samples/echoServer/gradle.properties b/samples/echoServer/gradle.properties new file mode 100644 index 00000000000..790a07d5124 --- /dev/null +++ b/samples/echoServer/gradle.properties @@ -0,0 +1,2 @@ +kotlin.code.style=official +kotlin.import.noCommonSourceSets=true diff --git a/samples/socket/src/main/kotlin/EchoServer.kt b/samples/echoServer/src/echoServerMain/kotlin/EchoServer.kt similarity index 78% rename from samples/socket/src/main/kotlin/EchoServer.kt rename to samples/echoServer/src/echoServerMain/kotlin/EchoServer.kt index 0dd13f44841..a532ba6327f 100644 --- a/samples/socket/src/main/kotlin/EchoServer.kt +++ b/samples/echoServer/src/echoServerMain/kotlin/EchoServer.kt @@ -1,25 +1,16 @@ /* - * Copyright 2010-2017 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. */ +package sample.echoserver + import kotlinx.cinterop.* import platform.posix.* fun main(args: Array) { - if (args.size < 1) { - println("Usage: ./echo_server ") + if (args.isEmpty()) { + println("Usage: echoserver.kexe ") return } diff --git a/samples/gitchurn/README.md b/samples/gitchurn/README.md index 941e02cecd9..d3f920b54db 100644 --- a/samples/gitchurn/README.md +++ b/samples/gitchurn/README.md @@ -3,10 +3,10 @@ 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 assemble` or `./build.sh`. +To build use `../gradlew assemble`. -Now you can run the program directly +To run use `../gradlew runProgram` or execute the program directly: - ./build/exe/main/release//gitchurn.kexe ../../ + ./build/bin/gitChurn/main/release/executable/gitchurn.kexe ../../ It will print most frequently modified (by number of commits) files in repository. diff --git a/samples/gitchurn/build.gradle b/samples/gitchurn/build.gradle index 8c641fc2810..f497a8cdac2 100644 --- a/samples/gitchurn/build.gradle +++ b/samples/gitchurn/build.gradle @@ -1,19 +1,33 @@ -apply plugin: 'org.jetbrains.kotlin.platform.native' +plugins { + id 'kotlin-multiplatform' +} -components.main { - targets = ['macos_x64', 'linux_x64'] - outputKinds = [EXECUTABLE] +kotlin { + presets { + // Determine host preset. + MPPTools.defaultHostPreset(project, [macosX64, linuxX64]) + } - dependencies { - cinterop('libgit2') { - target('linux') { - includeDirs.headerFilterOnly '/usr/include' - } - - target('macbook') { - includeDirs.headerFilterOnly '/opt/local/include', '/usr/local/include' + targets { + fromPreset(hostPreset, 'gitChurn') { + compilations.main.outputKinds 'EXECUTABLE' + compilations.main.entryPoint 'sample.gitchurn.main' + compilations.main.cinterops { + libgit2 { + switch (hostPreset) { + case presets.macosX64: + includeDirs.headerFilterOnly '/opt/local/include', '/usr/local/include' + break + case presets.linuxX64: + includeDirs.headerFilterOnly '/usr/include' + break + } + } } } } } +MPPTools.createRunTask(project, 'runProgram', kotlin.targets.gitChurn) { + args project.getRootProject().getRootDir().toString() + '/..' +} diff --git a/samples/gitchurn/build.sh b/samples/gitchurn/build.sh deleted file mode 100755 index 20d81bea982..00000000000 --- a/samples/gitchurn/build.sh +++ /dev/null @@ -1,32 +0,0 @@ -#!/usr/bin/env bash - -DIR=$(cd "$(dirname "${BASH_SOURCE[0]}" )" && pwd ) - -source "$DIR/../konan.sh" - -INTEROP_ARGS_macbook="-headerFilterAdditionalSearchPrefix /usr/local/include \ - -headerFilterAdditionalSearchPrefix /opt/local/include" -INTEROP_ARGS_linux="-headerFilterAdditionalSearchPrefix /usr/include" - -if [ x$TARGET == x ]; then -case "$OSTYPE" in - darwin*) TARGET=macbook ;; - linux*) TARGET=linux ;; - *) echo "unknown: $OSTYPE" && exit 1;; -esac -fi - -var=INTEROP_ARGS_${TARGET} -INTEROP_ARGS=${!var} -COMPILER_ARGS= # add -opt for an optimized build. - -mkdir -p $DIR/build/c_interop/ -mkdir -p $DIR/build/bin/ - -cinterop $INTEROP_ARGS -def $DIR/src/main/c_interop/libgit2.def -target $TARGET \ - -o $DIR/build/c_interop/libgit2 || exit 1 - -konanc $COMPILER_ARGS -target $TARGET $DIR/src/main/kotlin -library $DIR/build/c_interop/libgit2 \ - -o $DIR/build/bin/GitChurn || exit 1 - -echo "Artifact path is $DIR/build/bin/GitChurn.kexe" diff --git a/samples/gitchurn/gradle.properties b/samples/gitchurn/gradle.properties new file mode 100644 index 00000000000..790a07d5124 --- /dev/null +++ b/samples/gitchurn/gradle.properties @@ -0,0 +1,2 @@ +kotlin.code.style=official +kotlin.import.noCommonSourceSets=true diff --git a/samples/gitchurn/src/main/kotlin/org/konan/libgit/GitChurn.kt b/samples/gitchurn/src/gitChurnMain/kotlin/GitChurn.kt similarity index 62% rename from samples/gitchurn/src/main/kotlin/org/konan/libgit/GitChurn.kt rename to samples/gitchurn/src/gitChurnMain/kotlin/GitChurn.kt index 9c2a67e8cb5..60410ba4148 100644 --- a/samples/gitchurn/src/main/kotlin/org/konan/libgit/GitChurn.kt +++ b/samples/gitchurn/src/gitChurnMain/kotlin/GitChurn.kt @@ -1,41 +1,44 @@ /* - * Copyright 2010-2017 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. */ -package org.konan.libgit +package sample.gitchurn import kotlinx.cinterop.* -import platform.posix.* -import libgit2.* +import libgit2.git_time_t +import platform.posix.ctime +import platform.posix.time_tVar fun main(args: Array) { - if (args.size == 0) + if (args.isEmpty()) return help() val workDir = args[0] - val limit = if (args.size > 1) { - args[1].toInt() - } else - null + val limit = if (args.size > 1) { + val limitRaw = args[1].toIntOrNull() + if (limitRaw == null || limitRaw <= 0) { + return help("Not a positive integer: $limitRaw") + } + limitRaw + } else + Int.MAX_VALUE + + try { + calculateChurn(workDir, limit) + } catch (e: GitException) { + help(e.message) + } +} + +private fun calculateChurn(workDir: String, limit: Int) { println("Openingâ€Ĥ") val repository = git.repository(workDir) val map = mutableMapOf() var count = 0 val commits = repository.commits() - val limited = limit?.let { commits.take(it) } ?: commits + val limited = commits.take(limit) println("Calculatingâ€Ĥ") limited.forEach { commit -> if (count % 100 == 0) @@ -65,7 +68,7 @@ fun main(args: Array) { git.close() } -fun git_time_t.format() = memScoped { +private fun git_time_t.format() = memScoped { val commitTime = alloc() commitTime.value = this@format ctime(commitTime.ptr)!!.toKString().trim() @@ -81,6 +84,9 @@ private fun printTree(commit: GitCommit) { } } -fun help() { - println("Working directory should be provided") +private fun help(errorMessage: String? = null) { + errorMessage?.let { + println("ERROR: $it") + } + println("./gitchurn.kexe []") } diff --git a/samples/gitchurn/src/main/kotlin/org/konan/libgit/GitCommit.kt b/samples/gitchurn/src/gitChurnMain/kotlin/GitCommit.kt similarity index 60% rename from samples/gitchurn/src/main/kotlin/org/konan/libgit/GitCommit.kt rename to samples/gitchurn/src/gitChurnMain/kotlin/GitCommit.kt index fec70d4883f..7b12183345f 100644 --- a/samples/gitchurn/src/main/kotlin/org/konan/libgit/GitCommit.kt +++ b/samples/gitchurn/src/gitChurnMain/kotlin/GitCommit.kt @@ -1,20 +1,9 @@ /* - * Copyright 2010-2017 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. */ -package org.konan.libgit +package sample.gitchurn import kotlinx.cinterop.* import libgit2.* diff --git a/samples/gitchurn/src/main/kotlin/org/konan/libgit/GitDiff.kt b/samples/gitchurn/src/gitChurnMain/kotlin/GitDiff.kt similarity index 64% rename from samples/gitchurn/src/main/kotlin/org/konan/libgit/GitDiff.kt rename to samples/gitchurn/src/gitChurnMain/kotlin/GitDiff.kt index c8918bfbc7b..b5d73643422 100644 --- a/samples/gitchurn/src/main/kotlin/org/konan/libgit/GitDiff.kt +++ b/samples/gitchurn/src/gitChurnMain/kotlin/GitDiff.kt @@ -1,20 +1,9 @@ /* - * Copyright 2010-2017 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. */ -package org.konan.libgit +package sample.gitchurn import kotlinx.cinterop.* import libgit2.* diff --git a/samples/gitchurn/src/gitChurnMain/kotlin/GitRemote.kt b/samples/gitchurn/src/gitChurnMain/kotlin/GitRemote.kt new file mode 100644 index 00000000000..18a65ee8772 --- /dev/null +++ b/samples/gitchurn/src/gitChurnMain/kotlin/GitRemote.kt @@ -0,0 +1,16 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package sample.gitchurn + +import kotlinx.cinterop.* +import libgit2.* + +class GitRemote(val repository: GitRepository, val handle: CPointer) { + fun close() = git_remote_free(handle) + + val url: String get() = git_remote_url(handle)!!.toKString() + val name: String = git_remote_name(handle)!!.toKString() +} \ No newline at end of file diff --git a/samples/gitchurn/src/main/kotlin/org/konan/libgit/GitRepository.kt b/samples/gitchurn/src/gitChurnMain/kotlin/GitRepository.kt similarity index 76% rename from samples/gitchurn/src/main/kotlin/org/konan/libgit/GitRepository.kt rename to samples/gitchurn/src/gitChurnMain/kotlin/GitRepository.kt index d17c08b1b84..b10f23d37f6 100644 --- a/samples/gitchurn/src/main/kotlin/org/konan/libgit/GitRepository.kt +++ b/samples/gitchurn/src/gitChurnMain/kotlin/GitRepository.kt @@ -1,20 +1,9 @@ /* - * Copyright 2010-2017 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. */ -package org.konan.libgit +package sample.gitchurn import kotlinx.cinterop.* import libgit2.* diff --git a/samples/gitchurn/src/main/kotlin/org/konan/libgit/GitTree.kt b/samples/gitchurn/src/gitChurnMain/kotlin/GitTree.kt similarity index 74% rename from samples/gitchurn/src/main/kotlin/org/konan/libgit/GitTree.kt rename to samples/gitchurn/src/gitChurnMain/kotlin/GitTree.kt index 3bd4707f5dd..03d78325939 100644 --- a/samples/gitchurn/src/main/kotlin/org/konan/libgit/GitTree.kt +++ b/samples/gitchurn/src/gitChurnMain/kotlin/GitTree.kt @@ -1,20 +1,9 @@ /* - * Copyright 2010-2017 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. */ -package org.konan.libgit +package sample.gitchurn import kotlinx.cinterop.* import libgit2.* diff --git a/samples/gitchurn/src/gitChurnMain/kotlin/git.kt b/samples/gitchurn/src/gitChurnMain/kotlin/git.kt new file mode 100644 index 00000000000..5ecb1d6413c --- /dev/null +++ b/samples/gitchurn/src/gitChurnMain/kotlin/git.kt @@ -0,0 +1,33 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package sample.gitchurn + +import kotlinx.cinterop.* +import libgit2.* + +object git { + init { + git_libgit2_init() + } + + fun close() { + git_libgit2_shutdown() + } + + fun repository(location: String): GitRepository { + return GitRepository(location) + } +} + +fun Int.errorCheck() { + if (this == 0) return + throw GitException() +} + +class GitException : Exception(run { + val err = giterr_last() + err!!.pointed.message!!.toKString() +}) \ No newline at end of file diff --git a/samples/gitchurn/src/main/kotlin/main.kt b/samples/gitchurn/src/main/kotlin/main.kt deleted file mode 100644 index 0f3e32e9568..00000000000 --- a/samples/gitchurn/src/main/kotlin/main.kt +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright 2010-2017 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -fun main(args: Array) { - org.konan.libgit.main(args) -} \ No newline at end of file diff --git a/samples/gitchurn/src/main/kotlin/org/konan/libgit/GitRemote.kt b/samples/gitchurn/src/main/kotlin/org/konan/libgit/GitRemote.kt deleted file mode 100644 index 6f14a028e1b..00000000000 --- a/samples/gitchurn/src/main/kotlin/org/konan/libgit/GitRemote.kt +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2010-2017 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.konan.libgit - -import kotlinx.cinterop.* -import libgit2.* - -class GitRemote(val repository: GitRepository, val handle: CPointer) { - fun close() = git_remote_free(handle) - - val url: String get() = git_remote_url(handle)!!.toKString() - val name: String = git_remote_name(handle)!!.toKString() -} \ No newline at end of file diff --git a/samples/gitchurn/src/main/kotlin/org/konan/libgit/git.kt b/samples/gitchurn/src/main/kotlin/org/konan/libgit/git.kt deleted file mode 100644 index a969e90d835..00000000000 --- a/samples/gitchurn/src/main/kotlin/org/konan/libgit/git.kt +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2010-2017 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.konan.libgit - -import kotlinx.cinterop.* -import libgit2.* - -object git { - init { - git_libgit2_init() - } - - fun close() { - git_libgit2_shutdown() - } - - fun repository(location: String): GitRepository { - return GitRepository(location) - } -} - -fun Int.errorCheck() { - if (this == 0) return - throw GitException() -} - -class GitException : Exception(run { - val err = giterr_last() - err!!.pointed.message!!.toKString() -}) \ No newline at end of file diff --git a/samples/gitchurn/src/main/c_interop/libgit2.def b/samples/gitchurn/src/nativeInterop/cinterop/libgit2.def similarity index 100% rename from samples/gitchurn/src/main/c_interop/libgit2.def rename to samples/gitchurn/src/nativeInterop/cinterop/libgit2.def diff --git a/samples/globalState/README.md b/samples/globalState/README.md index fd8614482e7..96fb6050dff 100644 --- a/samples/globalState/README.md +++ b/samples/globalState/README.md @@ -1,9 +1,9 @@ # Shared global state - This example shows how one could implement global shared state using interop mechanisms. +This example shows how one could implement global shared state using interop mechanisms. To build use `../gradlew assemble`. -To run use `./build/exe/main/release//globalState.kexe`. - +To run use `../gradlew runProgram` or execute the program directly: + ./build/bin/globalState/main/release/executable/globalState.kexe diff --git a/samples/globalState/build.gradle b/samples/globalState/build.gradle index b2294ed5064..1bedca23aab 100644 --- a/samples/globalState/build.gradle +++ b/samples/globalState/build.gradle @@ -1,10 +1,17 @@ -apply plugin: 'org.jetbrains.kotlin.platform.native' +plugins { + id 'kotlin-multiplatform' +} -components.main { - targets = ['macos_x64', 'linux_x64', 'mingw_x64'] - outputKinds = [EXECUTABLE] - - dependencies { - cinterop('global') +kotlin { + targets { + fromPreset(MPPTools.defaultHostPreset(project), 'globalState') { + compilations.main.outputKinds 'EXECUTABLE' + compilations.main.entryPoint 'sample.globalstate.main' + compilations.main.cinterops { + global + } + } } -} \ No newline at end of file +} + +MPPTools.createRunTask(project, 'runProgram', kotlin.targets.globalState) diff --git a/samples/globalState/gradle.properties b/samples/globalState/gradle.properties new file mode 100644 index 00000000000..790a07d5124 --- /dev/null +++ b/samples/globalState/gradle.properties @@ -0,0 +1,2 @@ +kotlin.code.style=official +kotlin.import.noCommonSourceSets=true diff --git a/samples/globalState/src/main/kotlin/Global.kt b/samples/globalState/src/globalStateMain/kotlin/Global.kt similarity index 76% rename from samples/globalState/src/main/kotlin/Global.kt rename to samples/globalState/src/globalStateMain/kotlin/Global.kt index 345455c0447..4fa60b882c2 100644 --- a/samples/globalState/src/main/kotlin/Global.kt +++ b/samples/globalState/src/globalStateMain/kotlin/Global.kt @@ -1,20 +1,9 @@ /* - * Copyright 2010-2018 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. */ -import global.* +package sample.globalstate import kotlin.native.concurrent.* import kotlinx.cinterop.* @@ -35,13 +24,13 @@ data class SharedData(val string: String, val int: Int, val member: SharedDataMe val globalObject: SharedData? get() = sharedData.frozenKotlinObject?.asStableRef()?.get() -fun dumpShared(prefix: String): Unit { +fun dumpShared(prefix: String) { println(""" $prefix: ${pthread_self()} x=${sharedData.x} f=${sharedData.f} s=${sharedData.string!!.toKString()} """.trimIndent()) } -fun main(args: Array) { +fun main() { // Arena owning all native allocs. val arena = Arena() @@ -49,10 +38,12 @@ fun main(args: Array) { sharedData.x = 239 sharedData.f = 0.5f sharedData.string = "Hello Kotlin!".cstr.getPointer(arena) + // Here we create detached mutable object, which could be later reattached by another thread. sharedData.kotlinObject = DetachedObjectGraph { SharedData("A string", 42, SharedDataMember(2.39)) }.asCPointer() + // Here we create shared frozen object reference, val stableRef = StableRef.create(SharedData("Shared", 239, SharedDataMember(2.71)).freeze()) sharedData.frozenKotlinObject = stableRef.asCPointer() @@ -63,8 +54,7 @@ fun main(args: Array) { // memScoped is needed to pass thread's local address to pthread_create(). memScoped { val thread = alloc() - pthread_create(thread.ptr, null, staticCFunction { - argC -> + pthread_create(thread.ptr, null, staticCFunction { argC -> initRuntimeIfNeeded() dumpShared("thread2") val kotlinObject = DetachedObjectGraph(sharedData.kotlinObject).attach() diff --git a/samples/globalState/src/main/c_interop/global.def b/samples/globalState/src/nativeInterop/cinterop/global.def similarity index 58% rename from samples/globalState/src/main/c_interop/global.def rename to samples/globalState/src/nativeInterop/cinterop/global.def index 022a999c0de..f4391051aa9 100644 --- a/samples/globalState/src/main/c_interop/global.def +++ b/samples/globalState/src/nativeInterop/cinterop/global.def @@ -1,4 +1,4 @@ -package = global +package = sample.globalstate --- typedef struct { @@ -7,6 +7,6 @@ typedef struct { char* string; void* kotlinObject; void* frozenKotlinObject; -} SharedData; +} SharedDataStruct; -SharedData sharedData; +SharedDataStruct sharedData; diff --git a/samples/gradle.properties b/samples/gradle.properties index cdb70994cf8..d406f3c36fb 100644 --- a/samples/gradle.properties +++ b/samples/gradle.properties @@ -1,2 +1,8 @@ -konan.home=../../dist -konan.plugin.version=+ \ No newline at end of file +# Run parallel builds in Gradle: +org.gradle.parallel=true + +# Pin Kotlin version: +kotlin_version=1.3.0-rc-202 + +# Use custom Kotlin/Native home: +org.jetbrains.kotlin.native.home=../../dist diff --git a/samples/gradle/wrapper/gradle-wrapper.jar b/samples/gradle/wrapper/gradle-wrapper.jar index 29953ea141f..91ca28c8b80 100644 Binary files a/samples/gradle/wrapper/gradle-wrapper.jar and b/samples/gradle/wrapper/gradle-wrapper.jar differ diff --git a/samples/gradle/wrapper/gradle-wrapper.properties b/samples/gradle/wrapper/gradle-wrapper.properties index d76b502e226..e6a30918ef8 100644 --- a/samples/gradle/wrapper/gradle-wrapper.properties +++ b/samples/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.7-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/samples/gtk/README.md b/samples/gtk/README.md index f7dc2947f3a..4395f4ada52 100644 --- a/samples/gtk/README.md +++ b/samples/gtk/README.md @@ -1,16 +1,15 @@ # GTK application - This example shows how one may use _Kotlin/Native_ to build GUI - applications with the GTK toolkit. +This example shows how one may use _Kotlin/Native_ to build GUI +applications with the GTK toolkit. -To build use `../gradlew assemble` or `./build.sh [-I=/include/path]`. +To build use `../gradlew assemble`. Do not forget to install GTK3. See bellow. -On Mac use `port install gtk3`, on Debian flavours of Linux - `apt-get install libgtk-3-dev`. -To run on Mac also install XQuartz X server (https://www.xquartz.org/), and then +To run on Mac also install XQuartz X server (https://www.xquartz.org/), and then `../gradlew runProgram` or execute the program directly: - ./build/exe/main/release//gtk.kexe + ./build/bin/gtk/main/release/executable/gtk.kexe Dialog box with the button will be shown, and application will print message and terminate on button click. diff --git a/samples/gtk/build.gradle b/samples/gtk/build.gradle index 301d26268cd..b50de36c5e4 100644 --- a/samples/gtk/build.gradle +++ b/samples/gtk/build.gradle @@ -1,17 +1,27 @@ -apply plugin: 'org.jetbrains.kotlin.platform.native' +plugins { + id 'kotlin-multiplatform' +} -def includePrefixes = [ '/opt/local/include', '/usr/include', '/usr/local/include' ] +kotlin { + presets { + // Determine host preset. + MPPTools.defaultHostPreset(project, [macosX64, linuxX64]) + } -components.main { - targets = ['macos_x64', 'linux_x64'] - outputKinds = [EXECUTABLE] - - dependencies { - cinterop('gtk3') { - includePrefixes.each { - includeDirs "$it/atk-1.0", "$it/gdk-pixbuf-2.0", "$it/cairo", "$it/pango-1.0", "$it/gtk-3.0", "$it/glib-2.0" + targets { + fromPreset(hostPreset, 'gtk') { + compilations.main.outputKinds 'EXECUTABLE' + compilations.main.entryPoint 'sample.gtk.main' + compilations.main.cinterops { + gtk3 { + ['/opt/local/include', '/usr/include', '/usr/local/include'].each { + includeDirs "$it/atk-1.0", "$it/gdk-pixbuf-2.0", "$it/cairo", "$it/pango-1.0", "$it/gtk-3.0", "$it/glib-2.0" + } + includeDirs '/opt/local/lib/glib-2.0/include', '/usr/lib/x86_64-linux-gnu/glib-2.0/include', '/usr/local/lib/glib-2.0/include' + } } - includeDirs '/opt/local/lib/glib-2.0/include', '/usr/lib/x86_64-linux-gnu/glib-2.0/include', '/usr/local/lib/glib-2.0/include' } } } + +MPPTools.createRunTask(project, 'runProgram', kotlin.targets.gtk) diff --git a/samples/gtk/build.sh b/samples/gtk/build.sh deleted file mode 100755 index 2372df10573..00000000000 --- a/samples/gtk/build.sh +++ /dev/null @@ -1,32 +0,0 @@ -#!/usr/bin/env bash - -DIR=$(cd "$(dirname "${BASH_SOURCE[0]}" )" && pwd ) - -source "$DIR/../konan.sh" - -IPREFIX_macbook=-I/opt/local/include -IPREFIX_linux=-I/usr/include - -if [ x$TARGET == x ]; then -case "$OSTYPE" in - darwin*) TARGET=macbook ;; - linux*) TARGET=linux ;; - *) echo "unknown: $OSTYPE" && exit 1;; -esac -fi - -var=IPREFIX_${TARGET} -IPREFIX="${!var}" - -mkdir -p $DIR/build/c_interop/ -mkdir -p $DIR/build/bin/ - -echo "Generating GTK stubs, may take few mins depending on the hardware..." -cinterop -J-Xmx8g -compilerOpts "$IPREFIX/atk-1.0 $IPREFIX/gdk-pixbuf-2.0 $IPREFIX/cairo $IPREFIX/pango-1.0 \ - -I/opt/local/lib/glib-2.0/include $IPREFIX/gtk-3.0 $IPREFIX/glib-2.0" \ - -def $DIR/src/main/c_interop/gtk3.def -target $TARGET -o $DIR/build/c_interop/gtk3 || exit 1 - -konanc -target $TARGET $DIR/src/main/kotlin -library $DIR/build/c_interop/gtk3 \ - -o $DIR/build/bin/Gtk3Demo || exit 1 - -echo "Artifact path is $DIR/build/bin/Gtk3Demo.kexe" diff --git a/samples/gtk/gradle.properties b/samples/gtk/gradle.properties index f1b71e7cdd7..d46ff933fd4 100644 --- a/samples/gtk/gradle.properties +++ b/samples/gtk/gradle.properties @@ -1 +1,3 @@ -konan.jvmArgs=-Xmx8g \ No newline at end of file +org.jetbrains.kotlin.native.jvmArgs=-Xmx8g +kotlin.code.style=official +kotlin.import.noCommonSourceSets=true diff --git a/samples/gtk/src/main/kotlin/Main.kt b/samples/gtk/src/gtkMain/kotlin/Main.kt similarity index 75% rename from samples/gtk/src/main/kotlin/Main.kt rename to samples/gtk/src/gtkMain/kotlin/Main.kt index b93b53b501d..c09de4f268a 100644 --- a/samples/gtk/src/main/kotlin/Main.kt +++ b/samples/gtk/src/gtkMain/kotlin/Main.kt @@ -1,19 +1,10 @@ /* - * Copyright 2010-2017 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. */ +package sample.gtk + import kotlinx.cinterop.* import gtk3.* diff --git a/samples/gtk/src/main/c_interop/gtk3.def b/samples/gtk/src/nativeInterop/cinterop/gtk3.def similarity index 100% rename from samples/gtk/src/main/c_interop/gtk3.def rename to samples/gtk/src/nativeInterop/cinterop/gtk3.def diff --git a/samples/html5Canvas/README.md b/samples/html5Canvas/README.md new file mode 100644 index 00000000000..723a04f9f17 --- /dev/null +++ b/samples/html5Canvas/README.md @@ -0,0 +1,15 @@ +# HTML5 Canvas + +This sample shows how to use Kotlin/Native to build a WebAssembly application and how to call JavaScript functions +from a Kotlin/Native code. + +> __Note__: If you build this sample not from the Kotlin/Native repository, you need to specify a path to a +Kotlin/Native distribution. Add the following snippet in `gradle.properties`: +>``` +>org.jetbrains.kotlin.native.home= +>``` +> The default distribution path is `$HOME/.konan/kotlin-native--`. + +To build use `../gradlew assemble`. + +To run use `../gradlew runProgram`. \ No newline at end of file diff --git a/samples/html5Canvas/build.bat b/samples/html5Canvas/build.bat deleted file mode 100644 index 056ade9b40a..00000000000 --- a/samples/html5Canvas/build.bat +++ /dev/null @@ -1,27 +0,0 @@ -@echo off -setlocal enableextensions - -set DIR=%~dp0 - -if defined KONAN_HOME ( - set "PATH=%KONAN_HOME%\bin;%PATH%" -) else ( - set "PATH=..\..\dist\bin;..\..\bin;%PATH%" -) - -if not exist build\bin\ (mkdir build\bin) -if not exist build\klib\ (mkdir build\klib) - -::: TODO: use the proper path and names -call jsinterop -pkg kotlinx.interop.wasm.dom ^ - -o %DIR%\build\klib\dom -target wasm32 || exit /b - -call konanc %DIR%\src\main\kotlin ^ - -r %DIR%\build\klib -l dom ^ - -o %DIR%\build\bin\html5Canvas -target wasm32 || exit 1 - -echo "Artifact path is %DIR%\build\bin\html5Canvas.wasm" -echo "Artifact path is %DIR%\build\bin\html5Canvas.wasm.js" -echo "Check out %DIR%\index.html" -echo "Serve %DIR%\ by an http server for the demo" -::: For example run: py -m http.server 8080 diff --git a/samples/html5Canvas/build.gradle b/samples/html5Canvas/build.gradle new file mode 100644 index 00000000000..5afdc4bb8ac --- /dev/null +++ b/samples/html5Canvas/build.gradle @@ -0,0 +1,75 @@ +import org.jetbrains.kotlin.gradle.dsl.KotlinJvmCompile +import org.jetbrains.kotlin.gradle.tasks.KotlinNativeCompile + +import java.nio.file.Paths + +plugins { + id 'kotlin-multiplatform' +} + +repositories { + jcenter() + maven { url "https://dl.bintray.com/kotlin/ktor" } +} + +String packageName = 'kotlinx.interop.wasm.dom' +String jsinteropKlibFileName = Paths.get(buildDir.toString(), 'klib', "$packageName-jsinterop.klib").toString() + +kotlin { + targets { + fromPreset(presets.wasm32, 'html5Canvas') { + compilations.main.outputKinds 'EXECUTABLE' + compilations.main.entryPoint 'sample.html5canvas.main' + } + fromPreset(presets.jvm, 'httpServer') + } + sourceSets { + html5CanvasMain { + dependencies { + implementation files(jsinteropKlibFileName) + } + } + httpServerMain { + dependencies { + implementation "io.ktor:ktor-server-netty:1.0.0-beta-1" + } + } + } +} + +task jsinterop(type: Exec) { + workingDir projectDir + def ext = MPPTools.isWindows() ? '.bat' : '' + def distributionPath = project.properties['org.jetbrains.kotlin.native.home'] + if (distributionPath != null) { + commandLine Paths.get(distributionPath as String, 'bin', "jsinterop$ext").toString(), + '-pkg', packageName, + '-o', jsinteropKlibFileName, + '-target', 'wasm32' + } else { + doFirst { + // Abort build execution if the distribution path isn't specified. + throw new GradleException("""\ + |Kotlin/Native distribution path must be specified to build the JavaScript interop. + |Use 'org.jetbrains.kotlin.native.home' project property to specify it. + """.stripMargin()) + } + } +} + +tasks.withType(KotlinNativeCompile).all { + dependsOn jsinterop +} + +// This is to run embedded HTTP server with Ktor: +task runProgram(type: JavaExec) { + dependsOn assemble + main = 'sample.html5canvas.httpserver.HttpServer' + classpath = files(kotlin.targets.httpServer.compilations.main.output) + kotlin.targets.httpServer.compilations.main.runtimeDependencyFiles + args projectDir +} + +tasks.withType(KotlinJvmCompile).all { + runProgram.dependsOn it + kotlinOptions.jvmTarget = '1.8' +} diff --git a/samples/html5Canvas/build.sh b/samples/html5Canvas/build.sh deleted file mode 100755 index 2145aed3077..00000000000 --- a/samples/html5Canvas/build.sh +++ /dev/null @@ -1,34 +0,0 @@ -#!/usr/bin/env bash - -DIR=$(cd "$(dirname "${BASH_SOURCE[0]}" )" && pwd ) - -source "$DIR/../konan.sh" - -if [ x$TARGET == x ]; then -case "$OSTYPE" in - darwin*) TARGET=macbook ;; - linux*) TARGET=linux ;; - *) echo "unknown: $OSTYPE" && exit 1;; -esac -fi - -var=CFLAGS_${TARGET} -CFLAGS=${!var} -var=COMPILER_ARGS_${TARGET} -COMPILER_ARGS=${!var} # add -opt for an optimized build. - -mkdir -p $DIR/build/bin -mkdir -p $DIR/build/klib - -jsinterop -pkg kotlinx.interop.wasm.dom \ - -o $DIR/build/klib/dom -target wasm32 || exit 1 - -konanc $DIR/src/main/kotlin \ - -r $DIR/build/klib -l dom \ - -o $DIR/build/bin/html5Canvas -target wasm32 || exit 1 - -echo "Artifact path is $DIR/build/bin/html5Canvas.wasm" -echo "Artifact path is $DIR/build/bin/html5Canvas.wasm.js" -echo "Check out $DIR/index.html" -echo "Serve $DIR/ by an http server for the demo" -# For example run: python -m SimpleHTTPServer 8080 diff --git a/samples/html5Canvas/gradle.properties b/samples/html5Canvas/gradle.properties new file mode 100644 index 00000000000..790a07d5124 --- /dev/null +++ b/samples/html5Canvas/gradle.properties @@ -0,0 +1,2 @@ +kotlin.code.style=official +kotlin.import.noCommonSourceSets=true diff --git a/samples/html5Canvas/index.html b/samples/html5Canvas/index.html index 3b06c6280c0..89aaaf3895d 100644 --- a/samples/html5Canvas/index.html +++ b/samples/html5Canvas/index.html @@ -2,7 +2,7 @@ - + diff --git a/samples/html5Canvas/src/main/kotlin/main.kt b/samples/html5Canvas/src/html5CanvasMain/kotlin/main.kt similarity index 84% rename from samples/html5Canvas/src/main/kotlin/main.kt rename to samples/html5Canvas/src/html5CanvasMain/kotlin/main.kt index a4ee388f826..4104fb998ca 100644 --- a/samples/html5Canvas/src/main/kotlin/main.kt +++ b/samples/html5Canvas/src/html5CanvasMain/kotlin/main.kt @@ -1,7 +1,14 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package sample.html5canvas + import kotlinx.interop.wasm.dom.* import kotlinx.wasm.jsinterop.* -fun main(args: Array) { +fun main() { val canvas = document.getElementById("myCanvas").asCanvas val ctx = canvas.getContext("2d") diff --git a/samples/html5Canvas/src/httpServerMain/kotlin/HttpServer.kt b/samples/html5Canvas/src/httpServerMain/kotlin/HttpServer.kt new file mode 100644 index 00000000000..5653e3f61db --- /dev/null +++ b/samples/html5Canvas/src/httpServerMain/kotlin/HttpServer.kt @@ -0,0 +1,44 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +@file:JvmName("HttpServer") + +package sample.html5canvas.httpserver + +import io.ktor.http.content.default +import io.ktor.http.content.files +import io.ktor.http.content.static +import io.ktor.routing.routing +import io.ktor.server.engine.embeddedServer +import io.ktor.server.netty.Netty +import java.io.File + +fun main(args: Array) { + + check(args.size == 1) { "Invalid number of arguments: $args.\nExpected one argument with content root." } + + val contentRoot = File(args[0]) + check(contentRoot.isDirectory) { "Invalid content root: $contentRoot." } + + println( + """ + + IMPORTANT: Please open http://localhost:8080/ in your browser! + + To stop embedded HTTP server use Ctrl+C (Cmd+C for Mac OS X). + + """.trimIndent() + ) + + val server = embeddedServer(Netty, 8080) { + routing { + static("/") { + files(contentRoot) + default("index.html") + } + } + } + server.start(wait = true) +} diff --git a/samples/libcurl/README.md b/samples/libcurl/README.md index 103dd69391b..95c7fd6c2a3 100644 --- a/samples/libcurl/README.md +++ b/samples/libcurl/README.md @@ -1,10 +1,9 @@ # Curl interop library This example shows how to build and publish an interop library to communicate with the libcurl, -HTTP/HTTPS/FTP/etc client library. Debian-like distros may need to -`apt-get install libcurl4-openssl-dev`. +HTTP/HTTPS/FTP/etc client library. Debian-like distros may need to `apt-get install libcurl4-openssl-dev`. -To build use `../gradlew assemble` +To build use `../gradlew assemble`. -To publish the library into a local repo use `../gradlew publish` +To publish the library into a local repo use `../gradlew publish`. diff --git a/samples/libcurl/build.gradle b/samples/libcurl/build.gradle index 21c890bf94d..8e581ce9e40 100644 --- a/samples/libcurl/build.gradle +++ b/samples/libcurl/build.gradle @@ -1,46 +1,55 @@ -apply plugin: 'org.jetbrains.kotlin.platform.native' -apply plugin: 'maven-publish' +import java.nio.file.Paths -group 'org.jetbrains.kotlin.native' +plugins { + id 'kotlin-multiplatform' + id 'maven-publish' +} + +group 'org.jetbrains.kotlin.sample.native' version '1.0' -// Native component -components.main { - targets = ['macos_x64', 'linux_x64'] - - dependencies { - cinterop('libcurl-interop') { - defFile 'src/main/c_interop/libcurl.def' - - target('linux_x64') { - includeDirs.headerFilterOnly '/usr/include', '/usr/include/x86_64-linux-gnu' - } - target('macos_x64') { - includeDirs.headerFilterOnly '/opt/local/include', '/usr/local/include' - } - } - } - - pom { - withXml { - def root = asNode() - root.appendNode('name', 'libcurl interop library') - root.appendNode('description', 'A library providing interoperability with host libcurl') - } - } -} - -// Publishing -def localMavenRepo="file://${new File(System.properties['user.home'] as String)}/.m2-kotlin-native" - -task cleanLocalRepo(type: Delete) { - delete localMavenRepo -} +def localRepo = rootProject.file('build/.m2-repo') publishing { repositories { - maven { - url = localMavenRepo + maven { url = "file://$localRepo" } + } +} + +task cleanLocalRepo(type: Delete) { + delete localRepo +} + +kotlin { + presets { + // Determine host preset. + MPPTools.defaultHostPreset(project, [macosX64, linuxX64]) + } + + targets { + fromPreset(hostPreset, 'libcurl') { + compilations.main.cinterops { + libcurl { + switch (hostPreset) { + case presets.macosX64: + includeDirs.headerFilterOnly '/opt/local/include', '/usr/local/include' + break + case presets.linuxX64: + includeDirs.headerFilterOnly '/usr/include', '/usr/include/x86_64-linux-gnu' + break + } + } + } + + mavenPublication { + pom { + withXml { + def root = asNode() + root.appendNode('name', 'libcurl interop library') + root.appendNode('description', 'A library providing interoperability with host libcurl') + } + } + } } } } diff --git a/samples/libcurl/gradle.properties b/samples/libcurl/gradle.properties new file mode 100644 index 00000000000..790a07d5124 --- /dev/null +++ b/samples/libcurl/gradle.properties @@ -0,0 +1,2 @@ +kotlin.code.style=official +kotlin.import.noCommonSourceSets=true diff --git a/samples/libcurl/src/main/kotlin/org/konan/libcurl/CUrl.kt b/samples/libcurl/src/libcurlMain/kotlin/CUrl.kt similarity index 79% rename from samples/libcurl/src/main/kotlin/org/konan/libcurl/CUrl.kt rename to samples/libcurl/src/libcurlMain/kotlin/CUrl.kt index d30140a41fe..0ec4ea139e8 100644 --- a/samples/libcurl/src/main/kotlin/org/konan/libcurl/CUrl.kt +++ b/samples/libcurl/src/libcurlMain/kotlin/CUrl.kt @@ -1,22 +1,26 @@ -package org.konan.libcurl +/* + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package sample.libcurl import kotlinx.cinterop.* -import platform.posix.* import platform.posix.size_t import libcurl.* -class CUrl(val url: String) { - val stableRef = StableRef.create(this) +class CUrl(url: String) { + private val stableRef = StableRef.create(this) - val curl = curl_easy_init(); + private val curl = curl_easy_init() init { curl_easy_setopt(curl, CURLOPT_URL, url) val header = staticCFunction(::header_callback) curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, header) curl_easy_setopt(curl, CURLOPT_HEADERDATA, stableRef.asCPointer()) - val write_data = staticCFunction(::write_callback) - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data) + val writeData = staticCFunction(::write_callback) + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeData) curl_easy_setopt(curl, CURLOPT_WRITEDATA, stableRef.asCPointer()) } diff --git a/samples/libcurl/src/main/kotlin/org/konan/libcurl/Event.kt b/samples/libcurl/src/libcurlMain/kotlin/Event.kt similarity index 79% rename from samples/libcurl/src/main/kotlin/org/konan/libcurl/Event.kt rename to samples/libcurl/src/libcurlMain/kotlin/Event.kt index 388a6e2c619..4eddfe809af 100644 --- a/samples/libcurl/src/main/kotlin/org/konan/libcurl/Event.kt +++ b/samples/libcurl/src/libcurlMain/kotlin/Event.kt @@ -1,4 +1,9 @@ -package org.konan.libcurl +/* + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package sample.libcurl typealias EventHandler = (T) -> Unit class Event { diff --git a/samples/libcurl/src/main/c_interop/libcurl.def b/samples/libcurl/src/nativeInterop/cinterop/libcurl.def similarity index 100% rename from samples/libcurl/src/main/c_interop/libcurl.def rename to samples/libcurl/src/nativeInterop/cinterop/libcurl.def diff --git a/samples/nonBlockingEchoServer/README.md b/samples/nonBlockingEchoServer/README.md index bdcdbfb678b..c61491b8ad3 100644 --- a/samples/nonBlockingEchoServer/README.md +++ b/samples/nonBlockingEchoServer/README.md @@ -7,11 +7,11 @@ 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 assemble` or `./build.sh`. +To build use `../gradlew assemble`. -Now you can run the server +To run use `../gradlew runProgram` or execute the program directly: - ./build/exe/main/release//EchoServer.kexe 3000 & + ./build/bin/nonBlockingEchoServer/main/release/executable/nonBlockingEchoServer.kexe 3000 & Test the server by connecting to it, for example with telnet: @@ -21,6 +21,5 @@ Write something to console and watch server echoing it back. Concurrently connect from another terminal. Note that each connection gets its own connection id prefixed to echo response. - ~~Quit telnet by pressing ctrl+] ctrl+D~~ diff --git a/samples/nonBlockingEchoServer/build.gradle b/samples/nonBlockingEchoServer/build.gradle index ef9cd1bea8a..659e1e8f911 100644 --- a/samples/nonBlockingEchoServer/build.gradle +++ b/samples/nonBlockingEchoServer/build.gradle @@ -1,7 +1,21 @@ -apply plugin: 'org.jetbrains.kotlin.platform.native' +plugins { + id 'kotlin-multiplatform' +} -components.main { - targets = ['macos_x64', 'linux_x64'] - outputKinds = [EXECUTABLE] - baseName = 'EchoServer' -} \ No newline at end of file +kotlin { + presets { + // Determine host preset. + MPPTools.defaultHostPreset(project, [macosX64, linuxX64]) + } + + targets { + fromPreset(hostPreset, 'nonBlockingEchoServer') { + compilations.main.outputKinds 'EXECUTABLE' + compilations.main.entryPoint 'sample.nbechoserver.main' + } + } +} + +MPPTools.createRunTask(project, 'runProgram', kotlin.targets.nonBlockingEchoServer) { + args 3000 +} diff --git a/samples/nonBlockingEchoServer/build.sh b/samples/nonBlockingEchoServer/build.sh deleted file mode 100755 index 45781bc553d..00000000000 --- a/samples/nonBlockingEchoServer/build.sh +++ /dev/null @@ -1,28 +0,0 @@ -#!/usr/bin/env bash - -DIR=$(cd "$(dirname "${BASH_SOURCE[0]}" )" && pwd ) - -source "$DIR/../konan.sh" - -if [ x$TARGET == x ]; then -case "$OSTYPE" in - darwin*) TARGET=macbook ;; - linux*) TARGET=linux ;; - *) echo "unknown: $OSTYPE" && exit 1;; -esac -fi - -var=CFLAGS_${TARGET} -CFLAGS=${!var} -var=LINKER_ARGS_${TARGET} -LINKER_ARGS=${!var} -var=COMPILER_ARGS_${TARGET} -COMPILER_ARGS=${!var} # add -opt for an optimized build. - -mkdir -p $DIR/build/c_interop/ -mkdir -p $DIR/build/bin/ - -konanc $COMPILER_ARGS -target $TARGET $DIR/src/main/kotlin/EchoServer.kt \ - -o $DIR/build/bin/EchoServer || exit 1 - -echo "Artifact path is $DIR/build/bin/EchoServer.kexe" diff --git a/samples/nonBlockingEchoServer/gradle.properties b/samples/nonBlockingEchoServer/gradle.properties index f0f9e55f899..790a07d5124 100644 --- a/samples/nonBlockingEchoServer/gradle.properties +++ b/samples/nonBlockingEchoServer/gradle.properties @@ -1 +1,2 @@ -runArgs=3000 \ No newline at end of file +kotlin.code.style=official +kotlin.import.noCommonSourceSets=true diff --git a/samples/nonBlockingEchoServer/src/main/kotlin/EchoServer.kt b/samples/nonBlockingEchoServer/src/nonBlockingEchoServerMain/kotlin/EchoServer.kt similarity index 92% rename from samples/nonBlockingEchoServer/src/main/kotlin/EchoServer.kt rename to samples/nonBlockingEchoServer/src/nonBlockingEchoServerMain/kotlin/EchoServer.kt index 03a71fd6c7c..ae31d0b31ad 100644 --- a/samples/nonBlockingEchoServer/src/main/kotlin/EchoServer.kt +++ b/samples/nonBlockingEchoServer/src/nonBlockingEchoServerMain/kotlin/EchoServer.kt @@ -1,27 +1,18 @@ /* - * Copyright 2010-2017 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. */ +package sample.nbechoserver + import kotlinx.cinterop.* import platform.posix.* import kotlin.coroutines.* import kotlin.coroutines.intrinsics.* fun main(args: Array) { - if (args.size < 1) { - println("Usage: ./echo_server ") + if (args.isEmpty()) { + println("Usage: nonBlockingEchoServer.kexe ") return } diff --git a/samples/objc/build.gradle b/samples/objc/build.gradle index 494053c23e0..11e2730d7db 100644 --- a/samples/objc/build.gradle +++ b/samples/objc/build.gradle @@ -1,7 +1,14 @@ -apply plugin: 'org.jetbrains.kotlin.platform.native' - -components.main { - targets = ['macos_x64'] - outputKinds = [EXECUTABLE] - baseName = 'Window' +plugins { + id 'kotlin-multiplatform' } + +kotlin { + targets { + fromPreset(MPPTools.defaultHostPreset(project, [presets.macosX64]), 'objc') { + compilations.main.outputKinds 'EXECUTABLE' + compilations.main.entryPoint 'sample.objc.main' + } + } +} + +MPPTools.createRunTask(project, 'runProgram', kotlin.targets.objc) diff --git a/samples/objc/build.sh b/samples/objc/build.sh deleted file mode 100755 index a22d2b518cb..00000000000 --- a/samples/objc/build.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env bash - -DIR=$(cd "$(dirname "${BASH_SOURCE[0]}" )" && pwd ) - -source "$DIR/../konan.sh" - -mkdir -p $DIR/build/bin/ - -konanc -target macbook $DIR/src/main/kotlin/Window.kt \ - -o $DIR/build/bin/window || exit 1 - -echo "Artifact path is $DIR/build/bin/window.kexe" diff --git a/samples/objc/gradle.properties b/samples/objc/gradle.properties new file mode 100644 index 00000000000..790a07d5124 --- /dev/null +++ b/samples/objc/gradle.properties @@ -0,0 +1,2 @@ +kotlin.code.style=official +kotlin.import.noCommonSourceSets=true diff --git a/samples/objc/src/main/kotlin/Window.kt b/samples/objc/src/objcMain/kotlin/Window.kt similarity index 99% rename from samples/objc/src/main/kotlin/Window.kt rename to samples/objc/src/objcMain/kotlin/Window.kt index 8be465e9b37..df48e915572 100644 --- a/samples/objc/src/main/kotlin/Window.kt +++ b/samples/objc/src/objcMain/kotlin/Window.kt @@ -3,6 +3,8 @@ * that can be found in the LICENSE file. */ +package sample.objc + import kotlinx.cinterop.* import platform.AppKit.* import platform.Foundation.* @@ -23,7 +25,7 @@ inline fun executeAsync(queue: NSOperationQueue, crossinline produce data class QueryResult(val json: Map?, val error: String?) -fun main(args: Array) { +fun main() { autoreleasepool { runApp() } @@ -121,7 +123,6 @@ class MyAppDelegate() : NSObject(), NSApplicationDelegateProtocol { size.width * 0.5, size.height * 0.5 ) - } val windowStyle = NSWindowStyleMaskTitled or NSWindowStyleMaskMiniaturizable or diff --git a/samples/opengl/README.md b/samples/opengl/README.md index 3e9bac9d8d5..9df29f71a91 100644 --- a/samples/opengl/README.md +++ b/samples/opengl/README.md @@ -3,11 +3,11 @@ 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 assemble` or `./build.sh`. +To build use `../gradlew assemble`. -Now you can run the application - - ./build/exe/main/release/OpenGlTeapot.kexe +To run use `../gradlew runProgram` or execute the program directly: + + ./build/bin/opengl/main/release/executable/opengl.kexe It will render 3D model of teapot. Feel free to experiment with it, the whole power of OpenGL is at your hands. diff --git a/samples/opengl/build.gradle b/samples/opengl/build.gradle index 0847a1fce70..0d290fbd88f 100644 --- a/samples/opengl/build.gradle +++ b/samples/opengl/build.gradle @@ -1,8 +1,14 @@ -apply plugin: 'org.jetbrains.kotlin.platform.native' - -components.main { - targets = ['macos_x64'] - outputKinds = [EXECUTABLE] - baseName = 'OpenGlTeapot' +plugins { + id 'kotlin-multiplatform' } +kotlin { + targets { + fromPreset(MPPTools.defaultHostPreset(project, [presets.macosX64]), 'opengl') { + compilations.main.outputKinds 'EXECUTABLE' + compilations.main.entryPoint 'sample.opengl.main' + } + } +} + +MPPTools.createRunTask(project, 'runProgram', kotlin.targets.opengl) diff --git a/samples/opengl/build.sh b/samples/opengl/build.sh deleted file mode 100755 index ce6fb7f069e..00000000000 --- a/samples/opengl/build.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/usr/bin/env bash - -DIR=$(cd "$(dirname "${BASH_SOURCE[0]}" )" && pwd ) - -source "$DIR/../konan.sh" - -if [ x$TARGET == x ]; then -case "$OSTYPE" in - darwin*) TARGET=macbook ;; - *) echo "unknown: $OSTYPE" && exit 1;; -esac -fi - -mkdir -p $DIR/build/bin/ - -konanc -target $TARGET $DIR/src/main/kotlin/OpenGlTeapot.kt \ - -o $DIR/build/bin/OpenGlTeapot || exit 1 - -echo "Artifact path is $DIR/build/bin/OpenGlTeapot.kexe" diff --git a/samples/opengl/gradle.properties b/samples/opengl/gradle.properties new file mode 100644 index 00000000000..790a07d5124 --- /dev/null +++ b/samples/opengl/gradle.properties @@ -0,0 +1,2 @@ +kotlin.code.style=official +kotlin.import.noCommonSourceSets=true diff --git a/samples/opengl/src/main/kotlin/OpenGlTeapot.kt b/samples/opengl/src/openglMain/kotlin/OpenGlTeapot.kt similarity index 82% rename from samples/opengl/src/main/kotlin/OpenGlTeapot.kt rename to samples/opengl/src/openglMain/kotlin/OpenGlTeapot.kt index 0e1ddeb21e3..c94f9cf14cb 100644 --- a/samples/opengl/src/main/kotlin/OpenGlTeapot.kt +++ b/samples/opengl/src/openglMain/kotlin/OpenGlTeapot.kt @@ -1,19 +1,10 @@ /* - * Copyright 2010-2017 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. */ +package sample.opengl + import kotlinx.cinterop.* import platform.GLUT.* import platform.OpenGL.* @@ -98,7 +89,7 @@ fun initialize() { glClearColor(0.0f, 0.0f, 0.0f, 1.0f) } -fun main(args: Array) { +fun main() { // initialize and run program memScoped { val argc = alloc().apply { value = 0 } diff --git a/samples/python_extension/build.bat b/samples/python_extension/build.bat index a58a4a5cf40..2fcff0aa32c 100644 --- a/samples/python_extension/build.bat +++ b/samples/python_extension/build.bat @@ -6,11 +6,10 @@ if defined KONAN_HOME ( ) else ( set "PATH=..\..\dist\bin;..\..\bin;%PATH%" ) -konanc -p dynamic src/main/kotlin/Server.kt -o server +kotlinc-native -p dynamic src/main/kotlin/Server.kt -o server rem Prepare MSVC build environment, and .lib file for linking with our .dll. SET VS90COMNTOOLS=%VS140COMNTOOLS% \Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\lib.exe" /def:server.def /out:server.lib /machine:X64 python src/main/python/setup.py install - \ No newline at end of file diff --git a/samples/python_extension/build.sh b/samples/python_extension/build.sh index a52657159ad..483a1970853 100755 --- a/samples/python_extension/build.sh +++ b/samples/python_extension/build.sh @@ -2,9 +2,21 @@ DIR=$(cd "$(dirname "${BASH_SOURCE[0]}" )" && pwd ) -source "$DIR/../konan.sh" +if [ -z "$KONAN_HOME" ]; then + PATH="$DIR/../../dist/bin:$DIR/../../bin:$PATH" +else + PATH="$KONAN_HOME/bin:$PATH" +fi + +KONAN_USER_DIR=${KONAN_DATA_DIR:-"$HOME/.konan"} +KONAN_DEPS="$KONAN_USER_DIR/dependencies" PYTHON=python -konanc -p dynamic ${DIR}/src/main/kotlin/Server.kt -o server -sudo $PYTHON ${DIR}/src/main/python/setup.py install +mkdir -p $DIR/build +cd $DIR/build + +kotlinc-native -p dynamic $DIR/src/main/kotlin/Server.kt -o server + +cd $DIR +sudo -S $PYTHON ${DIR}/src/main/python/setup.py install diff --git a/samples/python_extension/src/main/c/kotlin_bridge.c b/samples/python_extension/src/main/c/kotlin_bridge.c index ed8583a63da..239e5134896 100644 --- a/samples/python_extension/src/main/c/kotlin_bridge.c +++ b/samples/python_extension/src/main/c/kotlin_bridge.c @@ -1,17 +1,6 @@ /* - * Copyright 2010-2017 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. */ #include diff --git a/samples/python_extension/src/main/kotlin/Server.kt b/samples/python_extension/src/main/kotlin/Server.kt index 9ed9d2e1889..ee137f8f94b 100644 --- a/samples/python_extension/src/main/kotlin/Server.kt +++ b/samples/python_extension/src/main/kotlin/Server.kt @@ -1,17 +1,6 @@ /* - * Copyright 2010-2017 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. */ package demo diff --git a/samples/python_extension/src/main/python/main.py b/samples/python_extension/src/main/python/main.py index 4bcfcd81d6e..021f032ad34 100644 --- a/samples/python_extension/src/main/python/main.py +++ b/samples/python_extension/src/main/python/main.py @@ -1,19 +1,9 @@ #!/usr/bin/python # -# Copyright 2010-2017 JetBrains s.r.o. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. +# Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license +# that can be found in the license/LICENSE.txt file. # + import kotlin_bridge session = kotlin_bridge.open_session(239, 'konan') diff --git a/samples/python_extension/src/main/python/setup.py b/samples/python_extension/src/main/python/setup.py index 7026f03d78b..e8030fd991b 100644 --- a/samples/python_extension/src/main/python/setup.py +++ b/samples/python_extension/src/main/python/setup.py @@ -1,19 +1,9 @@ #!/usr/bin/python # -# Copyright 2010-2017 JetBrains s.r.o. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. +# Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license +# that can be found in the license/LICENSE.txt file. # + from distutils.core import setup, Extension setup(name='kotlin_bridge', @@ -29,9 +19,9 @@ setup(name='kotlin_bridge', ext_modules=[ Extension('kotlin_bridge', - include_dirs = ['.'], + include_dirs = ['./build'], libraries = ['server'], - library_dirs = ['.'], + library_dirs = ['./build'], depends = ['server_api.h'], sources = ['src/main/c/kotlin_bridge.c'] ) diff --git a/samples/settings.gradle b/samples/settings.gradle index 585fd56cf19..99a0dc8563c 100644 --- a/samples/settings.gradle +++ b/samples/settings.gradle @@ -1,27 +1,50 @@ -// NOTE: If a new sample uses only platform libs, -// please add it into the 'buildSamplesWithPlatfromLibs' task in build.gradle. -enableFeaturePreview('GRADLE_METADATA') -include ':csvparser' -include ':gitchurn' -include ':globalState' -include ':gtk' -include ':libcurl' -include ':nonBlockingEchoServer' -include ':opengl' -include ':socket' -include ':tetris' -// ML samples have non-trivial deps, disable from here. -// include ':tensorflow' -// include ':torch' -// Android native activity build requires Android SDK. -// So temporary switching off for now, as it breaks the build -// of other samples if SDK is not present. -// include ':androidNativeActivity' -include ':objc' -include ':uikit' -include ':win32' -include ':videoplayer' -include ':workers' +pluginManagement { + resolutionStrategy { + eachPlugin { + if (requested.id.id == "kotlin-multiplatform") { + useModule("org.jetbrains.kotlin:kotlin-gradle-plugin:${requested.version}") + } + } + } -includeBuild '../shared' -includeBuild '../tools/kotlin-native-gradle-plugin' + repositories { + mavenCentral() + maven { url 'https://dl.bintray.com/kotlin/kotlin-dev' } + maven { url 'https://dl.bintray.com/kotlin/kotlin-eap' } + } +} + +enableFeaturePreview('GRADLE_METADATA') + +/* + * The following projects are only available for certain platforms: + */ +if (MPPTools.isMacos() || MPPTools.isLinux() || MPPTools.isWindows()) { + include ':csvparser' + include ':echoServer' + include ':globalState' + include ':html5Canvas' + include ':tetris' + include ':videoplayer' + include ':workers' +} + +if (MPPTools.isMacos() || MPPTools.isLinux()) { + include ':curl' + include ':gitchurn' + include ':gtk' + include ':libcurl' + include ':nonBlockingEchoServer' + include ':tensorflow' + include ':torch' +} + +if (MPPTools.isMacos()) { + include ':objc' + include ':opengl' + include ':uikit' +} + +if (MPPTools.isWindows()) { + include ':win32' +} diff --git a/samples/socket/README.md b/samples/socket/README.md deleted file mode 100644 index 147122c5cb8..00000000000 --- a/samples/socket/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# Sockets demo - -To build use `../gradlew build` or `./build.sh`. - -Now you can run the server - - ./build/exe/main/release/EchoServer.kexe 3000 & - -Test the server by conecting to it, for example with telnet: - - telnet localhost 3000 - -Write something to console and watch server echoing it back. - -~~Quit telnet by pressing ctrl+] ctrl+D~~ - diff --git a/samples/socket/build.gradle b/samples/socket/build.gradle deleted file mode 100644 index 4765e0bab26..00000000000 --- a/samples/socket/build.gradle +++ /dev/null @@ -1,6 +0,0 @@ -apply plugin: 'org.jetbrains.kotlin.platform.native' - -components.main { - outputKinds = [EXECUTABLE] - baseName = 'EchoServer' -} diff --git a/samples/socket/build.sh b/samples/socket/build.sh deleted file mode 100755 index a346cf92c21..00000000000 --- a/samples/socket/build.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env bash - -DIR=$(cd "$(dirname "${BASH_SOURCE[0]}" )" && pwd ) - -source "$DIR/../konan.sh" - -mkdir -p $DIR/build/bin/ - -konanc $COMPILER_ARGS $DIR/src/main/kotlin/EchoServer.kt \ - -o $DIR/build/bin/EchoServer || exit 1 - -echo "Artifact path is $DIR/build/bin/EchoServer.kexe" diff --git a/samples/tensorflow/README.md b/samples/tensorflow/README.md index c3dc868f874..bf853eaade6 100644 --- a/samples/tensorflow/README.md +++ b/samples/tensorflow/README.md @@ -1,11 +1,11 @@ # TensorFlow demo -Small Hello World calculation on the [TensorFlow](https://www.tensorflow.org/) backend, +Small Hello World calculation on the [TensorFlow](https://www.tensorflow.org/) backend, arranging simple operations into a graph and running it on a session. -Like other [TensorFlow clients](https://www.tensorflow.org/extend/language_bindings) -(e. g. for [Python](https://github.com/tensorflow/tensorflow/tree/master/tensorflow/python/client)), -this example is built on top of the -[TensorFlow C API](https://github.com/tensorflow/tensorflow/blob/r1.1/tensorflow/c/c_api.h), +Like other [TensorFlow clients](https://www.tensorflow.org/extend/language_bindings) +(e. g. for [Python](https://github.com/tensorflow/tensorflow/tree/master/tensorflow/python/client)), +this example is built on top of the +[TensorFlow C API](https://github.com/tensorflow/tensorflow/blob/r1.1/tensorflow/c/c_api.h), showing how a TensorFlow client in Kotlin/Native could look like. ## Installation @@ -16,15 +16,15 @@ will install [TensorFlow for C](https://www.tensorflow.org/versions/r1.1/install `$HOME/.konan/third-party/tensorflow` (if not yet done). One may override the location of `third-party/tensorflow` by setting the `KONAN_DATA_DIR` environment variable. -To build use `../gradlew build` or `./build.sh`. - -Then run +To build use `../gradlew assemble`. - ../gradlew run - -Alternatively you can run artifact directly +Then run - ./build/konan/bin/Tensorflow/Tensorflow.kexe + ../gradlew runProgram + +Alternatively you can run the artifact directly through + + ./build/bin/tensorflow/main/release/executable/tensorflow.kexe You may need to specify `LD_LIBRARY_PATH` or `DYLD_LIBRARY_PATH` to `$HOME/.konan/third-party/tensorflow/lib` -if the TensorFlow dynamic library cannot be found. \ No newline at end of file +if the TensorFlow dynamic library cannot be found. diff --git a/samples/tensorflow/build.gradle b/samples/tensorflow/build.gradle index a5049af80e9..39e83485ca9 100644 --- a/samples/tensorflow/build.gradle +++ b/samples/tensorflow/build.gradle @@ -1,50 +1,32 @@ -buildscript { - repositories { - maven { - url 'https://cache-redirector.jetbrains.com/maven-central' - } - maven { - url "https://dl.bintray.com/jetbrains/kotlin-native-dependencies" - } - } - - dependencies { - classpath "org.jetbrains.kotlin:kotlin-native-gradle-plugin:${project.property('konan.plugin.version')}" - } +plugins { + id 'kotlin-multiplatform' } -apply plugin: 'konan' +def tensorflowHome = "${MPPTools.kotlinNativeDataPath()}/third-party/tensorflow" -konan.targets = ['macbook', 'linux'] - -def konanUserDir = System.getenv("KONAN_DATA_DIR") ?: "${System.getProperty("user.home")}/.konan" -def tensorflowHome = "$konanUserDir/third-party/tensorflow" +kotlin { + targets { + fromPreset(MPPTools.defaultHostPreset(project, [presets.macosX64, presets.linuxX64]), 'tensorflow') { + compilations.main.outputKinds 'EXECUTABLE' + compilations.main.entryPoint 'sample.tensorflow.main' + compilations.main.linkerOpts "-L$tensorflowHome/lib", '-ltensorflow' + compilations.main.cinterops { + tensorflow { + includeDirs "$tensorflowHome/include" + } + } + } + } +} task downloadTensorflow(type: Exec) { - workingDir getProjectDir() + workingDir projectDir commandLine './downloadTensorflow.sh' } +tasks[kotlin.targets.tensorflow.compilations.main.cinterops.tensorflow.interopProcessingTaskName].dependsOn downloadTensorflow -konanArtifacts { - interop('TensorflowInterop') { - defFile "src/main/c_interop/tensorflow.def" - includeDirs "${tensorflowHome}/include" - dependsOn 'downloadTensorflow' - } - program('Tensorflow') { - libraries { - artifact 'TensorflowInterop' - } - linkerOpts "-L${tensorflowHome}/lib -ltensorflow" - } -} - -tasks.findByName("runTensorflow")?.dependsOn 'warning' - -task warning { - doLast { - println "Note: You may need to specify LD_LIBRARY_PATH or DYLD_LIBRARY_PATH env variables to $tensorflowHome/lib if the TensorFlow dynamic library cannot be found." - - } +MPPTools.createRunTask(project, 'runProgram', kotlin.targets.tensorflow) { + environment 'LD_LIBRARY_PATH': "$tensorflowHome/lib" + environment 'DYLD_LIBRARY_PATH': "$tensorflowHome/lib" } diff --git a/samples/tensorflow/build.sh b/samples/tensorflow/build.sh deleted file mode 100755 index a6b7f27259f..00000000000 --- a/samples/tensorflow/build.sh +++ /dev/null @@ -1,44 +0,0 @@ -#!/usr/bin/env bash - -DIR=$(cd "$(dirname "${BASH_SOURCE[0]}" )" && pwd ) - -source "$DIR/../konan.sh" - -$DIR/downloadTensorflow.sh - -# KONAN_USER_DIR is set by konan.sh -TF_TARGET_DIRECTORY="$KONAN_USER_DIR/third-party/tensorflow" -TF_TYPE="cpu" # Change to "gpu" for GPU support - -if [ x$TARGET == x ]; then -case "$OSTYPE" in - darwin*) TARGET=macbook; TF_TARGET=darwin ;; - linux*) TARGET=linux; TF_TARGET=linux ;; - *) echo "unknown: $OSTYPE" && exit 1;; -esac -fi - -CFLAGS_macbook="-I${TF_TARGET_DIRECTORY}/include" -CFLAGS_linux="-I${TF_TARGET_DIRECTORY}/include" - -var=CFLAGS_${TARGET} -CFLAGS=${!var} -var=LINKER_ARGS_${TARGET} -LINKER_ARGS=${!var} -var=COMPILER_ARGS_${TARGET} -COMPILER_ARGS=${!var} # add -opt for an optimized build. - -mkdir -p $DIR/build/c_interop/ -mkdir -p $DIR/build/bin/ - -cinterop -def $DIR/src/main/c_interop/tensorflow.def -compilerOpts "$CFLAGS" -target $TARGET \ - -o $DIR/build/c_interop/tensorflow || exit 1 - -konanc $COMPILER_ARGS -target $TARGET $DIR/src/main/kotlin/HelloTensorflow.kt \ - -library $DIR/build/c_interop/tensorflow \ - -o $DIR/build/bin/HelloTensorflow \ - -linkerOpts "-L$TF_TARGET_DIRECTORY/lib -ltensorflow" || exit 1 - -echo "Note: You may need to specify LD_LIBRARY_PATH or DYLD_LIBRARY_PATH env variables to $TF_TARGET_DIRECTORY/lib if the TensorFlow dynamic library cannot be found." - -echo "Artifact path is $DIR/build/bin/HelloTensorflow.kexe" diff --git a/samples/tensorflow/downloadTensorflow.sh b/samples/tensorflow/downloadTensorflow.sh index 051d71d6a38..5cbda81759b 100755 --- a/samples/tensorflow/downloadTensorflow.sh +++ b/samples/tensorflow/downloadTensorflow.sh @@ -13,9 +13,7 @@ esac fi if [ ! -d $TF_TARGET_DIRECTORY/include/tensorflow ]; then - echo "Installing TensorFlow into $TF_TARGET_DIRECTORY ..." - mkdir -p $TF_TARGET_DIRECTORY - curl -s -L \ - "https://storage.googleapis.com/tensorflow/libtensorflow/libtensorflow-${TF_TYPE}-${TF_TARGET}-x86_64-1.1.0.tar.gz" | - tar -C $TF_TARGET_DIRECTORY -xz + echo "Installing TensorFlow into $TF_TARGET_DIRECTORY ..." + mkdir -p $TF_TARGET_DIRECTORY + curl -s -L "https://storage.googleapis.com/tensorflow/libtensorflow/libtensorflow-${TF_TYPE}-${TF_TARGET}-x86_64-1.1.0.tar.gz" | tar -C $TF_TARGET_DIRECTORY -xz fi diff --git a/samples/tensorflow/gradle.properties b/samples/tensorflow/gradle.properties index cdb70994cf8..790a07d5124 100644 --- a/samples/tensorflow/gradle.properties +++ b/samples/tensorflow/gradle.properties @@ -1,2 +1,2 @@ -konan.home=../../dist -konan.plugin.version=+ \ No newline at end of file +kotlin.code.style=official +kotlin.import.noCommonSourceSets=true diff --git a/samples/tensorflow/settings.gradle b/samples/tensorflow/settings.gradle deleted file mode 100644 index d0193c301cd..00000000000 --- a/samples/tensorflow/settings.gradle +++ /dev/null @@ -1,4 +0,0 @@ -enableFeaturePreview('GRADLE_METADATA') - -includeBuild '../../shared' -includeBuild '../../tools/kotlin-native-gradle-plugin' diff --git a/samples/tensorflow/src/main/c_interop/tensorflow.def b/samples/tensorflow/src/nativeInterop/cinterop/tensorflow.def similarity index 100% rename from samples/tensorflow/src/main/c_interop/tensorflow.def rename to samples/tensorflow/src/nativeInterop/cinterop/tensorflow.def diff --git a/samples/tensorflow/src/main/kotlin/HelloTensorflow.kt b/samples/tensorflow/src/tensorflowMain/kotlin/HelloTensorflow.kt similarity index 97% rename from samples/tensorflow/src/main/kotlin/HelloTensorflow.kt rename to samples/tensorflow/src/tensorflowMain/kotlin/HelloTensorflow.kt index 1938494f8e0..04adda9bc89 100644 --- a/samples/tensorflow/src/main/kotlin/HelloTensorflow.kt +++ b/samples/tensorflow/src/tensorflowMain/kotlin/HelloTensorflow.kt @@ -1,3 +1,10 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package sample.tensorflow + import kotlinx.cinterop.* import platform.posix.size_t import tensorflow.* @@ -216,7 +223,7 @@ class Session(val graph: Graph) { } } -fun main(args: Array) { +fun main() { println("Hello, TensorFlow ${TF_Version()!!.toKString()}!") val result = Graph().run { diff --git a/samples/tetris/README.md b/samples/tetris/README.md index 38237d4a7b2..fd843698ffb 100644 --- a/samples/tetris/README.md +++ b/samples/tetris/README.md @@ -4,27 +4,20 @@ This example shows implementation of simple Tetris game using SDL (Simple DirectMedia Layer) library for rendering. SDL allows easy development of cross-platform game and multimedia applications. -Start with building compiler by using `dist` and `cross_dist` for cross-targets (unless -using binary distribution). - Install SDL2 development files (see https://www.libsdl.org/download-2.0.php). For Mac - copy `SDL2.framework` to `$HOME/Library/Frameworks`. For Debian-like Linux - 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 assemble`. - -Aleternatively for Mac and Linux `./build.sh`. +To build Tetris application for your host platform use `../gradlew assemble`. -For Windows use `build.bat`. - Note that SDL2 must be installed on the host. -Now you can run the game +Now you can run the game using `../gradlew runProgram` or directly with + + ./build/bin/tetris/main/release/executable/tetris.kexe - ./build/exe/main/release//tetris.[kexe|exe] - During build process compilation script creates interoperability bindings to SDL2, using SDL C headers, and then compiles an application with the produced bindings. @@ -35,3 +28,5 @@ Also GLES2 renderer is recommended (use `SDL_RENDER_DRIVER=opengles2 ./Tetris.ke For Windows `set SDL_RENDER_DRIVER=software` may be needed on some machines. +Note: There is a known issue with SDL2 library on Mac OS X 10.14 Mojave. Window may render black until +it is dragged. See https://bugzilla.libsdl.org/show_bug.cgi?id=4272 diff --git a/samples/tetris/build.bat b/samples/tetris/build.bat deleted file mode 100644 index d235e7b2f32..00000000000 --- a/samples/tetris/build.bat +++ /dev/null @@ -1,19 +0,0 @@ -@echo off -setlocal -set DIR=. -if "%KONAN_DATA_DIR%"=="" (set "KONAN_DATA_DIR=%userprofile%\.konan") -set "PATH=..\..\dist\bin;..\..\bin;%KONAN_DATA_DIR%\dependencies\msys2-mingw-w64-x86_64-gcc-7.3.0-clang-llvm-lld-6.0.1\bin;%PATH%" -if "%TARGET%" == "" set TARGET=mingw -rem Requires default mingw64 install path yet. -set MINGW=\msys64\mingw64 - -set "CFLAGS=-I%MINGW%\include\SDL2" -rem Add -Wl,--subsystem,windows for making GUI subsystem application. -set "LFLAGS=%DIR%\Tetris.res -L%MINGW%\lib -Wl,-Bstatic -lstdc++ -static -lSDL2 -limm32 -lole32 -loleaut32 -lversion -lwinmm -mwindows" - -call cinterop -def "%DIR%\src\main\c_interop\sdl.def" -compilerOpts "%CFLAGS%" -target "%TARGET%" -o sdl || exit /b -rem Windows build requires Windows Resource Compiler in paths. -call windres "%DIR%\Tetris.rc" -O coff -o "%DIR%\Tetris.res" || exit /b -call konanc -target "%TARGET%" "%DIR%\src\main\kotlin" -library sdl -linkerOpts "%LFLAGS%" -opt -o Tetris || exit /b - -copy src\main\resources\tetris_all.bmp tetris_all.bmp diff --git a/samples/tetris/build.gradle b/samples/tetris/build.gradle index 367d25f64f5..a15772dab9c 100644 --- a/samples/tetris/build.gradle +++ b/samples/tetris/build.gradle @@ -1,85 +1,114 @@ -apply plugin: 'org.jetbrains.kotlin.platform.native' +plugins { + id 'kotlin-multiplatform' +} -def konanUserDir = System.getenv("KONAN_DATA_DIR") ?: "${System.getProperty("user.home")}/.konan" -def resFile = file("$buildDir/konan/res/Tetris.res") +File winCompiledResourceFile = file("$buildDir/compiledWindowsResources/Tetris.res") +project.ext.hostPreset = determinePreset() -components.main { - targets = ['macos_x64', 'linux_x64', 'raspberrypi', 'mingw_x64'] - outputKinds = [EXECUTABLE] - baseName = 'tetris' +kotlin { + targets { + fromPreset(hostPreset, 'tetris') { + compilations.main.outputKinds 'EXECUTABLE' + compilations.main.entryPoint 'sample.tetris.main' - target 'macbook', { - linkerOpts "-F ${System.getProperty("user.home")}/Library/Frameworks -F /Library/Frameworks -framework SDL2" - // Use this line instead of the previous one if you've got a 'No SDL-framework' error. - //linkerOpts "-L/opt/local/lib -L/usr/local/lib -lSDL2" - } - - target 'linux', { - linkerOpts '-L/usr/lib64 -L/usr/lib/x86_64-linux-gnu -lSDL2' - } - - target 'raspberrypi', { - linkerOpts '-lSDL2' - } - - target 'mingw', { - linkerOpts "$resFile -L${System.getenv("MINGW64_DIR")?:"c:/msys64/mingw64"}/lib -Wl,-Bstatic -lstdc++ -static -lSDL2 -limm32 -lole32 -loleaut32 -lversion -lwinmm -mwindows" - } - - dependencies { - cinterop('sdl') { - packageName 'sdl' - target 'macos_x64', { - includeDirs '/Library/Frameworks/SDL2.framework/Headers', - "${System.getProperty("user.home")}/Library/Frameworks/SDL2.framework/Headers", - '/opt/local/include/SDL2', - '/usr/local/include/SDL2' + switch (hostPreset) { + case presets.macosX64: + compilations.main.linkerOpts '-L/opt/local/lib', '-L/usr/local/lib', '-lSDL2' + break + case presets.linuxX64: + compilations.main.linkerOpts '-L/usr/lib64', '-L/usr/lib/x86_64-linux-gnu', '-lSDL2' + break + case presets.mingwX64: + compilations.main.linkerOpts winCompiledResourceFile.path, + "-L${MPPTools.mingwPath()}/lib", + '-Wl,-Bstatic', + '-lstdc++', + '-static', + '-lSDL2', + '-limm32', + '-lole32', + '-loleaut32', + '-lversion', + '-lwinmm', + '-mwindows' + break + case presets.linuxArm32Hfp: + compilations.main.linkerOpts '-lSDL2' + break } - target 'linux_x64', { - includeDirs '/usr/include/SDL2' - } - - target 'raspberrypi', { - includeDirs "$konanUserDir/dependencies/target-sysroot-1-raspberrypi/usr/include/SDL2" - } - - target 'mingw_x64', { - includeDirs "${System.getenv("MINGW64_DIR") ?: "c:/msys64/mingw64"}/include/SDL2" + compilations.main.cinterops { + sdl { + switch (hostPreset) { + case presets.macosX64: + includeDirs '/opt/local/include/SDL2', '/usr/local/include/SDL2' + break + case presets.linuxX64: + includeDirs '/usr/include/SDL2' + break + case presets.mingwX64: + includeDirs "${MPPTools.mingwPath()}/include/SDL2" + break + case presets.linuxArm32Hfp: + includeDirs "${MPPTools.kotlinNativeDataPath()}/dependencies/target-sysroot-1-raspberrypi/usr/include/SDL2" + break + } + } } } } } -assemble { - doLast { - components.main.binaries.get().each { binary -> - copy { - from 'src/main/resources' - into binary.runtimeFile.asFile.get().parentFile +if (hostPreset == kotlin.presets.mingwX64) { + tasks.create('compileWindowsResources', Exec) { + def winResourceFile = kotlin.sourceSets.tetrisMain.resources.files.find { it.name == 'Tetris.rc' } + def windresDir = "${MPPTools.kotlinNativeDataPath()}/dependencies/msys2-mingw-w64-x86_64-gcc-7.3.0-clang-llvm-lld-6.0.1/bin" + def path = System.getenv('PATH') + + commandLine "$windresDir/windres", winResourceFile, '-O', 'coff', '-o', winCompiledResourceFile + environment 'PATH', "$windresDir;$path" + + inputs.file winResourceFile + outputs.file winCompiledResourceFile + } +} + +MPPTools.createRunTask(project, 'runProgram', kotlin.targets.tetris) { + workingDir = project.provider { + kotlin.targets.tetris.compilations.main.getBinary('EXECUTABLE', buildType).parentFile + } +} + +afterEvaluate { + kotlin.targets.tetris.compilations.main { mainCompilation -> + def linkTasks = ['RELEASE', 'DEBUG'] + .collect { mainCompilation.findLinkTask('EXECUTABLE', it) } + .findAll { it != null } + + def compileWindowsResourcesTask = tasks.findByName('compileWindowsResources') + + linkTasks.each { task -> + if (compileWindowsResourcesTask != null) + task.dependsOn compileWindowsResourcesTask + + task.doLast { + copy { + from kotlin.sourceSets.tetrisMain.resources + into task.outputFile.get().parentFile + exclude '*.rc' + } } } } } -task windowsResources (type: Exec) { - def rcFile = file('Tetris.rc') - def path = System.getenv("PATH") - - def windresDir = "$konanUserDir/dependencies/msys2-mingw-w64-x86_64-gcc-7.3.0-clang-llvm-lld-6.0.1/bin" - - commandLine "$windresDir/windres", rcFile, '-O', 'coff', '-o', resFile - environment 'PATH', "$windresDir;$path" - - inputs.file rcFile - outputs.file resFile -} - -project.tasks.matching { - it.name == 'compileDebugMingw_x64KotlinNative' || - it.name == 'compileReleaseMingw_x64KotlinNative' -}.all { - it.dependsOn 'windowsResources' - it.inputs.file resFile +private def determinePreset() { + def preset = isRaspberryPiBuild() ? kotlin.presets.linuxArm32Hfp /* aka RaspberryPi */ : MPPTools.defaultHostPreset(project) + println("$project has been configured for ${preset.name} platform.") + preset } +// If host platform is Linux and RaspberryPi target is activated. +private boolean isRaspberryPiBuild() { + MPPTools.isLinux() && Boolean.parseBoolean(project.findProperty('tetris.raspberrypi.build') as String) +} \ No newline at end of file diff --git a/samples/tetris/build.sh b/samples/tetris/build.sh deleted file mode 100755 index 889a93ff2c2..00000000000 --- a/samples/tetris/build.sh +++ /dev/null @@ -1,53 +0,0 @@ -#!/usr/bin/env bash - -DIR=$(cd "$(dirname "${BASH_SOURCE[0]}" )" && pwd ) - -source "$DIR/../konan.sh" - -# KONAN_DEPS is set in konan.sh -DEPS="$KONAN_DEPS" - -CFLAGS_macbook=-I$HOME/Library/Frameworks/SDL2.framework/Headers -LINKER_ARGS_macbook="-F $HOME/Library/Frameworks -framework SDL2" -COMPILER_ARGS_macbook= -# Uncomment this if your path to SDL differs from the one above. -#CFLAGS_macbook=-I/opt/local/include/SDL2 -#LINKER_ARGS_macbook="-L/opt/local/lib -lSDL2" -#CFLAGS_macbook=-I/usr/local/include/SDL2 -#LINKER_ARGS_macbook="-L/usr/local/lib -lSDL2" - -CFLAGS_linux=-I/usr/include/SDL2 -LINKER_ARGS_linux="-L/usr/lib/x86_64-linux-gnu -lSDL2" -COMPILER_ARGS_linux= - -CFLAGS_raspberrypi=-I$DEPS/target-sysroot-1-raspberrypi/usr/include/SDL2 -LINKER_ARGS_raspberrypi="-lSDL2" -COMPILER_ARGS_raspberrypi= - -if [ x$TARGET == x ]; then -case "$OSTYPE" in - darwin*) TARGET=macbook ;; - linux*) TARGET=linux ;; - *) echo "unknown: $OSTYPE" && exit 1;; -esac -fi - -var=CFLAGS_${TARGET} -CFLAGS=${!var} -var=LINKER_ARGS_${TARGET} -LINKER_ARGS=${!var} -var=COMPILER_ARGS_${TARGET} -COMPILER_ARGS=${!var} # add -opt for an optimized build. - -mkdir -p $DIR/build/c_interop/ -mkdir -p $DIR/build/bin/ - -cinterop -def $DIR/src/main/c_interop/sdl.def -compilerOpts "$CFLAGS" -target $TARGET -o $DIR/build/c_interop/sdl || exit 1 - -konanc $COMPILER_ARGS -target $TARGET $DIR/src/main/kotlin \ - -library $DIR/build/c_interop/sdl -linkerOpts "$LINKER_ARGS" \ - -o $DIR/build/bin/Tetris || exit 1 - -cp -R $DIR/src/main/resources/ $DIR/build/bin/ - -echo "Artifact path is $DIR/build/bin/Tetris.kexe" diff --git a/samples/tetris/gradle.properties b/samples/tetris/gradle.properties new file mode 100644 index 00000000000..0c7c2c2a6d4 --- /dev/null +++ b/samples/tetris/gradle.properties @@ -0,0 +1,5 @@ +kotlin.code.style=official +kotlin.import.noCommonSourceSets=true + +# Uncomment if you would like to build for RaspberryPi: +#tetris.raspberrypi.build=true diff --git a/samples/tetris/src/main/kotlin/main.kt b/samples/tetris/src/main/kotlin/main.kt deleted file mode 100644 index 1093cd51e88..00000000000 --- a/samples/tetris/src/main/kotlin/main.kt +++ /dev/null @@ -1,39 +0,0 @@ -/** - * Copyright 2010-2018 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import tetris.* - -fun main(args: Array) { - var startLevel = Config.startLevel - var width = Config.width - var height = Config.height - when (args.size) { - 1 -> startLevel = args[0].toInt() - 2 -> { - width = args[0].toInt() - height = args[1].toInt() - } - 3 -> { - width = args[0].toInt() - height = args[1].toInt() - startLevel = args[2].toInt() - } - } - val visualizer = SDL_Visualizer(width, height) - val game = Game(width, height, visualizer, visualizer) - game.startNewGame(startLevel) - - return -} \ No newline at end of file diff --git a/samples/tetris/src/main/c_interop/sdl.def b/samples/tetris/src/nativeInterop/cinterop/sdl.def similarity index 100% rename from samples/tetris/src/main/c_interop/sdl.def rename to samples/tetris/src/nativeInterop/cinterop/sdl.def diff --git a/samples/tetris/src/main/kotlin/Config.kt b/samples/tetris/src/tetrisMain/kotlin/Config.kt similarity index 64% rename from samples/tetris/src/main/kotlin/Config.kt rename to samples/tetris/src/tetrisMain/kotlin/Config.kt index a25e47cc828..6e4f9f59ff4 100644 --- a/samples/tetris/src/main/kotlin/Config.kt +++ b/samples/tetris/src/tetrisMain/kotlin/Config.kt @@ -1,19 +1,9 @@ -/** - * Copyright 2010-2018 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. +/* + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. */ -package tetris + +package sample.tetris import platform.posix.* import kotlinx.cinterop.* diff --git a/samples/tetris/src/main/kotlin/SDL_Visualizer.kt b/samples/tetris/src/tetrisMain/kotlin/SDL_Visualizer.kt similarity index 96% rename from samples/tetris/src/main/kotlin/SDL_Visualizer.kt rename to samples/tetris/src/tetrisMain/kotlin/SDL_Visualizer.kt index d33fd7b1c81..e3a1458fd22 100644 --- a/samples/tetris/src/main/kotlin/SDL_Visualizer.kt +++ b/samples/tetris/src/tetrisMain/kotlin/SDL_Visualizer.kt @@ -1,20 +1,9 @@ -/** - * Copyright 2010-2018 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. +/* + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. */ -package tetris +package sample.tetris import kotlinx.cinterop.* import platform.posix.* diff --git a/samples/tetris/src/main/kotlin/Tetris.kt b/samples/tetris/src/tetrisMain/kotlin/Tetris.kt similarity index 96% rename from samples/tetris/src/main/kotlin/Tetris.kt rename to samples/tetris/src/tetrisMain/kotlin/Tetris.kt index 2c4c2dcb47a..0e26af76f4b 100644 --- a/samples/tetris/src/main/kotlin/Tetris.kt +++ b/samples/tetris/src/tetrisMain/kotlin/Tetris.kt @@ -1,20 +1,9 @@ -/** - * Copyright 2010-2018 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. +/* + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. */ -package tetris +package sample.tetris import kotlinx.cinterop.* import platform.posix.* diff --git a/samples/tetris/src/tetrisMain/kotlin/main.kt b/samples/tetris/src/tetrisMain/kotlin/main.kt new file mode 100644 index 00000000000..e81bdb4fa8b --- /dev/null +++ b/samples/tetris/src/tetrisMain/kotlin/main.kt @@ -0,0 +1,29 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package sample.tetris + +fun main(args: Array) { + var startLevel = Config.startLevel + var width = Config.width + var height = Config.height + when (args.size) { + 1 -> startLevel = args[0].toInt() + 2 -> { + width = args[0].toInt() + height = args[1].toInt() + } + 3 -> { + width = args[0].toInt() + height = args[1].toInt() + startLevel = args[2].toInt() + } + } + val visualizer = SDL_Visualizer(width, height) + val game = Game(width, height, visualizer, visualizer) + game.startNewGame(startLevel) + + return +} \ No newline at end of file diff --git a/samples/tetris/src/main/resources/Info.plist b/samples/tetris/src/tetrisMain/resources/Info.plist similarity index 100% rename from samples/tetris/src/main/resources/Info.plist rename to samples/tetris/src/tetrisMain/resources/Info.plist diff --git a/samples/tetris/Tetris.rc b/samples/tetris/src/tetrisMain/resources/Tetris.rc similarity index 100% rename from samples/tetris/Tetris.rc rename to samples/tetris/src/tetrisMain/resources/Tetris.rc diff --git a/samples/tetris/src/main/resources/config.txt b/samples/tetris/src/tetrisMain/resources/config.txt similarity index 100% rename from samples/tetris/src/main/resources/config.txt rename to samples/tetris/src/tetrisMain/resources/config.txt diff --git a/samples/tetris/src/main/resources/tetris_all.bmp b/samples/tetris/src/tetrisMain/resources/tetris_all.bmp similarity index 100% rename from samples/tetris/src/main/resources/tetris_all.bmp rename to samples/tetris/src/tetrisMain/resources/tetris_all.bmp diff --git a/samples/torch/README.md b/samples/torch/README.md index 1897ff2baf2..760c8f970ec 100644 --- a/samples/torch/README.md +++ b/samples/torch/README.md @@ -15,10 +15,10 @@ make sure you have Python 2.X and pyyaml installed: sudo easy_install pip # Linux: if you don't have pip apt-get -y install python-pip - + # if you don't have pyyaml or typing sudo pip install pyyaml typing - + Now ./downloadTorch.sh @@ -26,23 +26,23 @@ Now will install it into `$HOME/.konan/third-party/torch` (if not yet done). One may override the location of `third-party/torch` by setting the `KONAN_DATA_DIR` environment variable. -To build use `../gradlew build` or `./build.sh`. +To build use `../gradlew assemble`. ./downloadMNIST.sh -will download and unzip the [MNIST dataset](https://en.wikipedia.org/wiki/MNIST_database) of -[70000 labeled handwritten digits](http://yann.lecun.com/exdb/mnist/) for training and testing a classifier. +will download and unzip the [MNIST dataset](https://en.wikipedia.org/wiki/MNIST_database) of +[70000 labeled handwritten digits](http://yann.lecun.com/exdb/mnist/) for training and testing a classifier (if not yet done). -Then run +Then run + + ../gradlew runProgram - ../gradlew run - Alternatively you can run the artifact directly through - ./build/konan/bin/macbook/HelloTorch.kexe - -You may need to specify `LD_LIBRARY_PATH` or `DYLD_LIBRARY_PATH` to `$HOME/.konan/third-party/torch/lib` -if the ATen dynamic library cannot be found. + ./build/bin/torch/main/release/executable/torch.kexe -Even on a CPU, training should only take some minutes, +You may need to specify `LD_LIBRARY_PATH` or `DYLD_LIBRARY_PATH` environment variables +to point to `$HOME/.konan/third-party/torch/lib` if the ATen dynamic library cannot be found. + +Even on a CPU, training should only take some minutes, and you should observe a classification accuracy of about 95% on the test dataset. diff --git a/samples/torch/build.gradle b/samples/torch/build.gradle index 222dfc174a0..c7716ac4c05 100644 --- a/samples/torch/build.gradle +++ b/samples/torch/build.gradle @@ -1,50 +1,37 @@ -buildscript { - repositories { - maven { - url 'https://cache-redirector.jetbrains.com/maven-central' - } - maven { - url "https://dl.bintray.com/jetbrains/kotlin-native-dependencies" - } - } - - dependencies { - classpath "org.jetbrains.kotlin:kotlin-native-gradle-plugin:${project.property('konan.plugin.version')}" - } +plugins { + id 'kotlin-multiplatform' } -apply plugin: 'konan' +def torchHome = "${MPPTools.kotlinNativeDataPath()}/third-party/torch" -konan.targets = ['macbook', 'linux'] - -def konanUserDir = System.getenv("KONAN_DATA_DIR") ?: "${System.getProperty("user.home")}/.konan" -def torchHome = "$konanUserDir/third-party/torch" +kotlin { + targets { + fromPreset(MPPTools.defaultHostPreset(project, [presets.macosX64, presets.linuxX64]), 'torch') { + compilations.main.outputKinds 'EXECUTABLE' + compilations.main.entryPoint 'sample.torch.main' + compilations.main.linkerOpts "-L$torchHome/lib", '-lATen' + compilations.main.cinterops { + torch { + includeDirs "$torchHome/include", "$torchHome/include/TH" + } + } + } + } +} task downloadTorch(type: Exec) { - workingDir getProjectDir() + workingDir projectDir commandLine './downloadTorch.sh' } +tasks[kotlin.targets.torch.compilations.main.cinterops.torch.interopProcessingTaskName].dependsOn downloadTorch -konanArtifacts { - interop('TorchInterop') { - defFile "src/main/c_interop/torch.def" - includeDirs "${torchHome}/include", "${torchHome}/include/TH" - dependsOn 'downloadTorch' - } - - program('Torch') { - libraries { - artifact 'TorchInterop' - } - linkerOpts "-L${torchHome}/lib -lATen" - } +task downloadMNIST(type: Exec) { + workingDir projectDir + commandLine './downloadMNIST.sh' } -tasks.findByName("runTorch")?.dependsOn 'warning' - -task warning { - doLast { - println "Note: You may need to specify LD_LIBRARY_PATH or DYLD_LIBRARY_PATH env variables to $torchHome/lib if the ATen dynamic library cannot be found." - - } +MPPTools.createRunTask(project, 'runProgram', kotlin.targets.torch) { + dependsOn downloadMNIST + environment 'LD_LIBRARY_PATH': "$torchHome/lib" + environment 'DYLD_LIBRARY_PATH': "$torchHome/lib" } diff --git a/samples/torch/build.sh b/samples/torch/build.sh deleted file mode 100755 index 7ddc42ce4c2..00000000000 --- a/samples/torch/build.sh +++ /dev/null @@ -1,45 +0,0 @@ -#!/usr/bin/env bash - -DIR=$(cd "$(dirname "${BASH_SOURCE[0]}" )" && pwd ) - -source "$DIR/../konan.sh" - -$DIR/downloadTorch.sh - -TH_TARGET_DIRECTORY="$KONAN_USER_DIR/third-party/torch" - -if [ x$TARGET == x ]; then -case "$OSTYPE" in - darwin*) TARGET=macbook; TF_TARGET=darwin ;; - linux*) TARGET=linux; TF_TARGET=linux ;; - *) echo "unknown: $OSTYPE" && exit 1;; -esac -fi - -CFLAGS_macbook="-I${TH_TARGET_DIRECTORY}/include" -CFLAGS_linux="-I${TH_TARGET_DIRECTORY}/include" - -var=CFLAGS_${TARGET} -CFLAGS=${!var} -var=LINKER_ARGS_${TARGET} -LINKER_ARGS=${!var} -var=COMPILER_ARGS_${TARGET} -COMPILER_ARGS=${!var} # add -opt for an optimized build. - -mkdir -p $DIR/build/c_interop/ -mkdir -p $DIR/build/bin/ - -cinterop -def $DIR/src/main/c_interop/torch.def -compilerOpts "$CFLAGS" -labels $TARGET \ - -copt -I$TH_TARGET_DIRECTORY/include/TH -o $DIR/build/c_interop/torch || exit 1 - -SOURCE_DIR=$DIR/src/main/kotlin - -konanc $COMPILER_ARGS -target $TARGET $SOURCE_DIR/ClassifierDemo.kt $SOURCE_DIR/Disposable.kt \ - $SOURCE_DIR/Tensors.kt $SOURCE_DIR/Modules.kt $SOURCE_DIR/Dataset.kt $SOURCE_DIR/SmallDemos.kt \ - -library $DIR/build/c_interop/torch \ - -o $DIR/build/bin/HelloTorch \ - -linkerOpts "-L$TH_TARGET_DIRECTORY/lib -lATen" || exit 1 - -echo "Note: You may need to specify LD_LIBRARY_PATH or DYLD_LIBRARY_PATH env variables to $TH_TARGET_DIRECTORY/lib if the ATen dynamic library cannot be found." - -echo "Artifact path is $DIR/build/bin/HelloTorch.kexe" diff --git a/samples/torch/downloadMNIST.sh b/samples/torch/downloadMNIST.sh index 5519d38510c..ea348c32340 100755 --- a/samples/torch/downloadMNIST.sh +++ b/samples/torch/downloadMNIST.sh @@ -2,12 +2,16 @@ # See http://yann.lecun.com/exdb/mnist/ -wget http://yann.lecun.com/exdb/mnist/train-images-idx3-ubyte.gz -wget http://yann.lecun.com/exdb/mnist/train-labels-idx1-ubyte.gz -wget http://yann.lecun.com/exdb/mnist/t10k-images-idx3-ubyte.gz -wget http://yann.lecun.com/exdb/mnist/t10k-labels-idx1-ubyte.gz +MNIST_TARGET_DIRECTORY="`pwd`/build/3rd-party/MNIST" -gzip -d train-images-idx3-ubyte.gz -gzip -d train-labels-idx1-ubyte.gz -gzip -d t10k-images-idx3-ubyte.gz -gzip -d t10k-labels-idx1-ubyte.gz \ No newline at end of file +echo "Downloading MNIST databases into $MNIST_TARGET_DIRECTORY ..." + +mkdir -p $MNIST_TARGET_DIRECTORY +cd $MNIST_TARGET_DIRECTORY + +wget -nv -N http://yann.lecun.com/exdb/mnist/train-images-idx3-ubyte.gz +wget -nv -N http://yann.lecun.com/exdb/mnist/train-labels-idx1-ubyte.gz +wget -nv -N http://yann.lecun.com/exdb/mnist/t10k-images-idx3-ubyte.gz +wget -nv -N http://yann.lecun.com/exdb/mnist/t10k-labels-idx1-ubyte.gz + +gunzip -fk *.gz diff --git a/samples/torch/downloadTorch.sh b/samples/torch/downloadTorch.sh index a83c906ceeb..4fa7c03c84a 100755 --- a/samples/torch/downloadTorch.sh +++ b/samples/torch/downloadTorch.sh @@ -5,6 +5,11 @@ TH_TARGET_DIRECTORY="$KONAN_USER_DIR/third-party/torch" NO_CUDA=true # set to false for GPU support if [ ! -d $TH_TARGET_DIRECTORY/include/THNN ]; then + echo "Installing Torch into $TH_TARGET_DIRECTORY ..." + + mkdir -p build/3rd-party + cd build/3rd-party + git clone https://github.com/pytorch/pytorch.git # Current pytorch master fails the build so we need to checkout a correct revision. cd pytorch && git checkout 310c3735b9eb97f30cee743b773e5bb054989edc^ && cd ../ @@ -24,4 +29,4 @@ if [ ! -d $TH_TARGET_DIRECTORY/include/THNN ]; then # hack to solve "fatal error: 'generic/THNN.h' file not found" when linking, -I$/include/THNN did not work cp include/THNN/generic/THNN.h include/TH/generic/THNN.h -fi \ No newline at end of file +fi diff --git a/samples/torch/gradle.properties b/samples/torch/gradle.properties index cdb70994cf8..790a07d5124 100644 --- a/samples/torch/gradle.properties +++ b/samples/torch/gradle.properties @@ -1,2 +1,2 @@ -konan.home=../../dist -konan.plugin.version=+ \ No newline at end of file +kotlin.code.style=official +kotlin.import.noCommonSourceSets=true diff --git a/samples/torch/settings.gradle b/samples/torch/settings.gradle deleted file mode 100644 index d0193c301cd..00000000000 --- a/samples/torch/settings.gradle +++ /dev/null @@ -1,4 +0,0 @@ -enableFeaturePreview('GRADLE_METADATA') - -includeBuild '../../shared' -includeBuild '../../tools/kotlin-native-gradle-plugin' diff --git a/samples/torch/src/main/c_interop/torch.def b/samples/torch/src/nativeInterop/cinterop/torch.def similarity index 100% rename from samples/torch/src/main/c_interop/torch.def rename to samples/torch/src/nativeInterop/cinterop/torch.def diff --git a/samples/torch/src/main/kotlin/ClassifierDemo.kt b/samples/torch/src/torchMain/kotlin/ClassifierDemo.kt similarity index 94% rename from samples/torch/src/main/kotlin/ClassifierDemo.kt rename to samples/torch/src/torchMain/kotlin/ClassifierDemo.kt index eb63f283a0a..719deac00b5 100644 --- a/samples/torch/src/main/kotlin/ClassifierDemo.kt +++ b/samples/torch/src/torchMain/kotlin/ClassifierDemo.kt @@ -1,3 +1,10 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package sample.torch + fun Float.toRoundedString(digits: Int = 0): String { var factor = 1 @@ -63,7 +70,7 @@ fun twoLayerClassifier(dataset: Dataset, hiddenSize: Int = 64) = linear(dataset.inputs[0].size, hiddenSize) before Relu before linear(hiddenSize, dataset.labels[0].size) before Softmax -fun main(args: Array) { +fun main() { val trainingDataset = MNIST.labeledTrainingImages() val predictionNetwork = twoLayerClassifier(trainingDataset) predictionNetwork.trainClassifier(trainingDataset, lossByLabels = { CrossEntropyLoss(labels = it) }) @@ -71,4 +78,4 @@ fun main(args: Array) { val testDataset = MNIST.labeledTestImages() val averageAccuracy = predictionNetwork.testClassifier(testDataset) println("Accuracy on the test set: ${averageAccuracy.toPercentageString()}") -} \ No newline at end of file +} diff --git a/samples/torch/src/main/kotlin/Dataset.kt b/samples/torch/src/torchMain/kotlin/Dataset.kt similarity index 87% rename from samples/torch/src/main/kotlin/Dataset.kt rename to samples/torch/src/torchMain/kotlin/Dataset.kt index 1ad8da8ac8d..8db12819f85 100644 --- a/samples/torch/src/main/kotlin/Dataset.kt +++ b/samples/torch/src/torchMain/kotlin/Dataset.kt @@ -1,3 +1,10 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package sample.torch + import kotlinx.cinterop.* import platform.posix.* @@ -19,7 +26,8 @@ data class Dataset(val inputs: List, val labels: List) { * Provides the MNIST labeled handwritten digit dataset, described at http://yann.lecun.com/exdb/mnist/ */ object MNIST { - private fun readFileData(path: String) = memScoped { + private fun readFileData(fileName: String) = memScoped { + val path = "build/3rd-party/MNIST/$fileName" fun fail(): Nothing = throw Error("Cannot read input file $path") val size = alloc().also { if (stat(path, it.ptr) != 0) fail() }.st_size.toInt() @@ -51,8 +59,8 @@ object MNIST { private fun oneHot(size: Int, index: Int) = FloatArray(size) { if (it == index) 1f else 0f } - private fun readLabels(filePath: String, totalLabels: Int = 10): List { - val data = readFileData(filePath) + private fun readLabels(fileName: String, totalLabels: Int = 10): List { + val data = readFileData(fileName) val check = data.getIntAt(0) val expectedCheck = 2049 if (check != 2049) throw Error("File should start with int $expectedCheck, but was $check.") @@ -66,8 +74,8 @@ object MNIST { return (0 until count).map { oneHot(totalLabels, index = data[offset + it].reinterpretAsUnsigned()) } } - private fun readImages(filePath: String): List { - val data = readFileData(filePath) + private fun readImages(fileName: String): List { + val data = readFileData(fileName) val check = data.getIntAt(0) val expectedCheck = 2051 if (check != expectedCheck) throw Error("File should start with int $expectedCheck, but was $check.") diff --git a/samples/torch/src/main/kotlin/Disposable.kt b/samples/torch/src/torchMain/kotlin/Disposable.kt similarity index 77% rename from samples/torch/src/main/kotlin/Disposable.kt rename to samples/torch/src/torchMain/kotlin/Disposable.kt index e29e66b1238..2d275137d26 100644 --- a/samples/torch/src/main/kotlin/Disposable.kt +++ b/samples/torch/src/torchMain/kotlin/Disposable.kt @@ -1,3 +1,10 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package sample.torch + interface Disposable { fun dispose() } diff --git a/samples/torch/src/main/kotlin/Modules.kt b/samples/torch/src/torchMain/kotlin/Modules.kt similarity index 98% rename from samples/torch/src/main/kotlin/Modules.kt rename to samples/torch/src/torchMain/kotlin/Modules.kt index 949e8d2a66b..bc07fa2a47b 100644 --- a/samples/torch/src/main/kotlin/Modules.kt +++ b/samples/torch/src/torchMain/kotlin/Modules.kt @@ -1,3 +1,10 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package sample.torch + import kotlinx.cinterop.* import torch.* diff --git a/samples/torch/src/main/kotlin/SmallDemos.kt b/samples/torch/src/torchMain/kotlin/SmallDemos.kt similarity index 92% rename from samples/torch/src/main/kotlin/SmallDemos.kt rename to samples/torch/src/torchMain/kotlin/SmallDemos.kt index 9240c71e7e8..58ddb7a0610 100644 --- a/samples/torch/src/main/kotlin/SmallDemos.kt +++ b/samples/torch/src/torchMain/kotlin/SmallDemos.kt @@ -1,3 +1,10 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package sample.torch + // If you are curious you can also try one of these private fun demonstrateTensors() { diff --git a/samples/torch/src/main/kotlin/Tensors.kt b/samples/torch/src/torchMain/kotlin/Tensors.kt similarity index 97% rename from samples/torch/src/main/kotlin/Tensors.kt rename to samples/torch/src/torchMain/kotlin/Tensors.kt index 6b8d2084c3f..c739f95ef5e 100644 --- a/samples/torch/src/main/kotlin/Tensors.kt +++ b/samples/torch/src/torchMain/kotlin/Tensors.kt @@ -1,3 +1,10 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package sample.torch + import kotlinx.cinterop.* import torch.* diff --git a/samples/uikit/README.md b/samples/uikit/README.md index 9f0a2947ec8..647055855e7 100644 --- a/samples/uikit/README.md +++ b/samples/uikit/README.md @@ -10,7 +10,7 @@ To build and run the sample do the following: 2. Open the project's target through project navigator, go to tab 'General'. In 'Identity' section change the bundle ID to the unique string in reverse-DNS format. Then select the team in 'Signing' section. - + See the [Xcode documentation](https://developer.apple.com/library/content/documentation/IDEs/Conceptual/AppDistributionGuide/ConfiguringYourApp/ConfiguringYourApp.html#//apple_ref/doc/uid/TP40012582-CH28-SW2) for more info. diff --git a/samples/uikit/build.gradle b/samples/uikit/build.gradle index 9e25a1085f2..47400c9a0a8 100644 --- a/samples/uikit/build.gradle +++ b/samples/uikit/build.gradle @@ -1,7 +1,59 @@ -apply plugin: 'konan' - -konan.targets = ['iphone', 'iphone_sim'] - -konanArtifacts { - program('app') +plugins { + id 'kotlin-multiplatform' +} + +kotlin { + targets { + fromPreset(determinePreset(), 'ios') { + compilations.main.outputKinds 'EXECUTABLE' + compilations.main.entryPoint 'sample.uikit.main' + } + } +} + +// Special Gradle task that is called from Xcode. +// Two Gradle properties must be specified for this task: +// - uikit.configuration.name=[Release|Debug] +// - uikit.binary.location +task buildAppForXcode { + doLast { + if (!isCalledFromXcode()) { + throw new Exception("Please run 'buildAppForXcode' task with all necessary properties!") + } + + copy { + from file(kotlin.targets.ios.compilations.main.getBinary('EXECUTABLE', getBuildTypeForXcode())) + into file(getBinaryLocationForXcode().parentFile) + rename { + getBinaryLocationForXcode().name + } + } + } +} + +afterEvaluate { + if (isCalledFromXcode()) { + buildAppForXcode.dependsOn kotlin.targets.ios.compilations.main.linkTaskName('EXECUTABLE', getBuildTypeForXcode()) + } +} + +// If custom preset specified in 'uikit.preset.name' property, then use it for building. +// Otherwise build for iPhone simulator (by default). +private def determinePreset() { + String presetName = project.hasProperty('uikit.preset.name') ? project.properties['uikit.preset.name'] : 'iosX64' + def preset = project.kotlin.presets[presetName] + println("$project has been configured for $presetName platform.") + preset +} + +private boolean isCalledFromXcode() { + project.hasProperty('uikit.configuration.name') && project.hasProperty('uikit.binary.location') +} + +private String getBuildTypeForXcode() { + project.properties['uikit.configuration.name'] as String +} + +private File getBinaryLocationForXcode() { + file(project.properties['uikit.binary.location']) } diff --git a/samples/uikit/build.sh b/samples/uikit/build.sh deleted file mode 100755 index 9218dab8a46..00000000000 --- a/samples/uikit/build.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env bash - -DIR=$(cd "$(dirname "${BASH_SOURCE[0]}" )" && pwd ) - -source "$DIR/../konan.sh" - -mkdir -p $DIR/build/bin/ - -konanc -target iphone $DIR/src/main/kotlin/main.kt \ - -o $DIR/build/bin/uikit || exit 1 - -echo "Artifact path is $DIR/build/bin/uikit.kexe" diff --git a/samples/uikit/gradle.properties b/samples/uikit/gradle.properties new file mode 100644 index 00000000000..790a07d5124 --- /dev/null +++ b/samples/uikit/gradle.properties @@ -0,0 +1,2 @@ +kotlin.code.style=official +kotlin.import.noCommonSourceSets=true diff --git a/samples/uikit/konan.xcodeproj/project.pbxproj b/samples/uikit/konan.xcodeproj/project.pbxproj index 065ee2c1229..0e127dbb418 100644 --- a/samples/uikit/konan.xcodeproj/project.pbxproj +++ b/samples/uikit/konan.xcodeproj/project.pbxproj @@ -103,7 +103,6 @@ 2CB540351F56C2C4006EE521 /* Sources */, 2CB540361F56C2C4006EE521 /* Frameworks */, 2C901F991F59928A004412FA /* Build Binary From Kotlin Sources */, - 2C901F911F597BFC004412FA /* Replace Binary */, 2CB540371F56C2C4006EE521 /* Resources */, ); buildRules = ( @@ -162,20 +161,6 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ - 2C901F911F597BFC004412FA /* Replace Binary */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "Replace Binary"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "cp \"$TARGET_BUILD_DIR/app.kexe\" \"$TARGET_BUILD_DIR/$EXECUTABLE_PATH\""; - }; 2C901F991F59928A004412FA /* Build Binary From Kotlin Sources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -188,7 +173,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"$SRCROOT/../gradlew\" -p \"$SRCROOT\" \"$KONAN_TASK\" \\\n-Pkonan.configuration.build.dir=\"$CONFIGURATION_BUILD_DIR\" \\\n-Pkonan.debugging.symbols=\"$DEBUGGING_SYMBOLS\" \\\n-Pkonan.optimizations.enable=\"$KONAN_ENABLE_OPTIMIZATIONS\""; + shellScript = "\"$SRCROOT/../gradlew\" -p \"$SRCROOT\" buildAppForXcode \\\n-Puikit.preset.name=\"$KOTLIN_NATIVE_PRESET\" \\\n-Puikit.configuration.name=\"$CONFIGURATION\" \\\n-Puikit.binary.location=\"$TARGET_BUILD_DIR/$EXECUTABLE_PATH\"\n"; }; 2C901F9C1F5D7074004412FA /* Remove Original Binary */ = { isa = PBXShellScriptBuildPhase; @@ -202,7 +187,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "rm -f \"$TARGET_BUILD_DIR/$EXECUTABLE_PATH\""; + shellScript = "rm -f \"$TARGET_BUILD_DIR/$EXECUTABLE_PATH\"\n"; }; /* End PBXShellScriptBuildPhase section */ @@ -333,9 +318,8 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; INFOPLIST_FILE = konan/Info.plist; - KONAN_ENABLE_OPTIMIZATIONS = NO; - "KONAN_TASK[sdk=iphoneos*]" = compileKonanappIos_arm64; - "KONAN_TASK[sdk=iphonesimulator*]" = compileKonanappIos_x64; + "KOTLIN_NATIVE_PRESET[sdk=iphoneos*]" = iosArm64; + "KOTLIN_NATIVE_PRESET[sdk=iphonesimulator*]" = iosX64; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = org.jetbrains.konan; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -347,9 +331,8 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; INFOPLIST_FILE = konan/Info.plist; - KONAN_ENABLE_OPTIMIZATIONS = YES; - "KONAN_TASK[sdk=iphoneos*]" = compileKonanappIos_arm64; - "KONAN_TASK[sdk=iphonesimulator*]" = compileKonanappIos_x64; + "KOTLIN_NATIVE_PRESET[sdk=iphoneos*]" = iosArm64; + "KOTLIN_NATIVE_PRESET[sdk=iphonesimulator*]" = iosX64; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = org.jetbrains.konan; PRODUCT_NAME = "$(TARGET_NAME)"; diff --git a/samples/uikit/konan.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/samples/uikit/konan.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 00000000000..18d981003d6 --- /dev/null +++ b/samples/uikit/konan.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/samples/uikit/konan/Assets.xcassets/AppIcon.appiconset/Contents.json b/samples/uikit/konan/Assets.xcassets/AppIcon.appiconset/Contents.json index b8236c65348..19882d568af 100644 --- a/samples/uikit/konan/Assets.xcassets/AppIcon.appiconset/Contents.json +++ b/samples/uikit/konan/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -39,6 +39,11 @@ "idiom" : "iphone", "size" : "60x60", "scale" : "3x" + }, + { + "idiom" : "ios-marketing", + "size" : "1024x1024", + "scale" : "1x" } ], "info" : { diff --git a/samples/uikit/src/main/kotlin/main.kt b/samples/uikit/src/iosMain/kotlin/main.kt similarity index 85% rename from samples/uikit/src/main/kotlin/main.kt rename to samples/uikit/src/iosMain/kotlin/main.kt index 0710fda23f6..f60a3a5c623 100644 --- a/samples/uikit/src/main/kotlin/main.kt +++ b/samples/uikit/src/iosMain/kotlin/main.kt @@ -1,3 +1,10 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package sample.uikit + import kotlinx.cinterop.* import platform.Foundation.* import platform.UIKit.* diff --git a/samples/videoplayer/README.md b/samples/videoplayer/README.md index 6e4c771fd71..a63ac45f0c0 100644 --- a/samples/videoplayer/README.md +++ b/samples/videoplayer/README.md @@ -1,18 +1,15 @@ # Simple video player - This example shows how one could implement a video player in Kotlin. +This example shows how one could implement a video player in Kotlin. Almost any video file supported by ffmpeg could be played with it. ffmpeg and SDL2 is needed for that to work, i.e. port install ffmpeg-devel brew install ffmpeg sdl2 - apt install libavcodec-dev libavformat-dev libavutil-dev libswscale-dev \ - libswresample-dev + apt install libavcodec-dev libavformat-dev libavutil-dev libswscale-dev libswresample-dev apt install libsdl2-dev pacman -S mingw-w64-x86_64-SDL2 mingw-w64-x86_64-ffmpeg To build use `../gradlew assemble`. -To run use `./build/exe/main/release//Player.kexe file.mp4`. - - +To run use `./build/bin/videoPlayer/main/release/executable/videoplayer.kexe .mp4`. diff --git a/samples/videoplayer/build.gradle b/samples/videoplayer/build.gradle index 128b9ed601f..f5abf938e98 100644 --- a/samples/videoplayer/build.gradle +++ b/samples/videoplayer/build.gradle @@ -1,54 +1,58 @@ -apply plugin: 'org.jetbrains.kotlin.platform.native' - -components.main { - targets = ['macos_x64', 'linux_x64', 'mingw_x64'] - outputKinds = [EXECUTABLE] - baseName = 'Player' - - dependencies { - cinterop('ffmpeg') { - target 'macos_x64', { - includeDirs.headerFilterOnly '/opt/local/include', '/usr/local/include' - } - - target 'linux_x64', { - includeDirs.headerFilterOnly '/usr/include', '/usr/include/x86_64-linux-gnu', '/usr/include/ffmpeg' - } - - target 'mingw_x64', { - includeDirs 'C:/msys64/mingw64/include' - } - } - - cinterop ('sdl') { - target 'macos_x64', { - includeDirs '/Library/Frameworks/SDL2.framework/Headers', - "${System.getProperty("user.home")}/Library/Frameworks/SDL2.framework/Headers", - '/opt/local/include/SDL2', - '/usr/local/include/SDL2' - } - - target 'linux_x64', { - includeDirs '/usr/include/SDL2' - } - - target 'mingw_x64', { - includeDirs 'C:/msys64/mingw64/include/SDL2' - } - } - } - - target 'macos_x64', { - linkerOpts "-F ${System.getProperty("user.home")}/Library/Frameworks", "-F /Library/Frameworks", - "-L/opt/local/lib", "-L/usr/local/lib" - } - - target 'linux_x64', { - linkerOpts '-L/usr/lib/x86_64-linux-gnu', '-L/usr/lib64' - } - - target 'mingw_x64', { - linkerOpts '-LC:/msys64/mingw64/lib' - } +plugins { + id 'kotlin-multiplatform' } +kotlin { + presets { + // Determine host preset. + MPPTools.defaultHostPreset(project, [macosX64, linuxX64, mingwX64]) + } + + targets { + fromPreset(hostPreset, 'videoPlayer') { + compilations.main.outputKinds 'EXECUTABLE' + compilations.main.entryPoint 'sample.videoplayer.main' + + switch (hostPreset) { + case presets.macosX64: + compilations.main.linkerOpts '-L/opt/local/lib', '-L/usr/local/lib' + break + case presets.linuxX64: + compilations.main.linkerOpts '-L/usr/lib/x86_64-linux-gnu', '-L/usr/lib64' + break + case presets.mingwX64: + compilations.main.linkerOpts "-L${MPPTools.mingwPath()}/lib" + break + } + + compilations.main.cinterops { + ffmpeg { + switch (hostPreset) { + case presets.macosX64: + includeDirs.headerFilterOnly '/opt/local/include', '/usr/local/include' + break + case presets.linuxX64: + includeDirs.headerFilterOnly '/usr/include', '/usr/include/x86_64-linux-gnu', '/usr/include/ffmpeg' + break + case presets.mingwX64: + includeDirs "${MPPTools.mingwPath()}/include" + break + } + } + sdl { + switch (hostPreset) { + case presets.macosX64: + includeDirs '/opt/local/include/SDL2', '/usr/local/include/SDL2' + break + case presets.linuxX64: + includeDirs '/usr/include/SDL2' + break + case presets.mingwX64: + includeDirs "${MPPTools.mingwPath()}/include/SDL2" + break + } + } + } + } + } +} diff --git a/samples/videoplayer/gradle.properties b/samples/videoplayer/gradle.properties new file mode 100644 index 00000000000..790a07d5124 --- /dev/null +++ b/samples/videoplayer/gradle.properties @@ -0,0 +1,2 @@ +kotlin.code.style=official +kotlin.import.noCommonSourceSets=true diff --git a/samples/videoplayer/src/main/kotlin/Dimensions.kt b/samples/videoplayer/src/main/kotlin/Dimensions.kt deleted file mode 100644 index 2c8dbdefc78..00000000000 --- a/samples/videoplayer/src/main/kotlin/Dimensions.kt +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2010-2017 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -data class Dimensions(val w: Int, val h: Int) { - operator fun minus(other: Dimensions) = Dimensions(w - other.w, h - other.h) - operator fun div(b: Int) = Dimensions(w / b, h / b) -} diff --git a/samples/videoplayer/src/main/kotlin/SDLErrors.kt b/samples/videoplayer/src/main/kotlin/SDLErrors.kt deleted file mode 100644 index 18a02f33335..00000000000 --- a/samples/videoplayer/src/main/kotlin/SDLErrors.kt +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright 2010-2017 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import sdl.SDL_GetError -import kotlinx.cinterop.* - -fun throwSDLError(name: String): Nothing = - throw Error("SDL_$name Error: ${SDL_GetError()!!.toKString()}") - -fun checkSDLError(name: String, result: Int) { - if (result != 0) throwSDLError(name) -} diff --git a/samples/videoplayer/src/main/c_interop/ffmpeg.def b/samples/videoplayer/src/nativeInterop/cinterop/ffmpeg.def similarity index 100% rename from samples/videoplayer/src/main/c_interop/ffmpeg.def rename to samples/videoplayer/src/nativeInterop/cinterop/ffmpeg.def diff --git a/samples/videoplayer/src/main/c_interop/sdl.def b/samples/videoplayer/src/nativeInterop/cinterop/sdl.def similarity index 100% rename from samples/videoplayer/src/main/c_interop/sdl.def rename to samples/videoplayer/src/nativeInterop/cinterop/sdl.def diff --git a/samples/videoplayer/src/main/kotlin/DecoderWorker.kt b/samples/videoplayer/src/videoPlayerMain/kotlin/DecoderWorker.kt similarity index 96% rename from samples/videoplayer/src/main/kotlin/DecoderWorker.kt rename to samples/videoplayer/src/videoPlayerMain/kotlin/DecoderWorker.kt index bb314ccaeb4..3f5fc9a2773 100644 --- a/samples/videoplayer/src/main/kotlin/DecoderWorker.kt +++ b/samples/videoplayer/src/videoPlayerMain/kotlin/DecoderWorker.kt @@ -1,19 +1,10 @@ /* - * Copyright 2010-2017 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. */ +package sample.videoplayer + import ffmpeg.* import kotlin.native.concurrent.* import kotlinx.cinterop.* diff --git a/samples/videoplayer/src/videoPlayerMain/kotlin/Dimensions.kt b/samples/videoplayer/src/videoPlayerMain/kotlin/Dimensions.kt new file mode 100644 index 00000000000..903608d0866 --- /dev/null +++ b/samples/videoplayer/src/videoPlayerMain/kotlin/Dimensions.kt @@ -0,0 +1,11 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package sample.videoplayer + +data class Dimensions(val w: Int, val h: Int) { + operator fun minus(other: Dimensions) = Dimensions(w - other.w, h - other.h) + operator fun div(b: Int) = Dimensions(w / b, h / b) +} diff --git a/samples/videoplayer/src/main/kotlin/Disposable.kt b/samples/videoplayer/src/videoPlayerMain/kotlin/Disposable.kt similarity index 78% rename from samples/videoplayer/src/main/kotlin/Disposable.kt rename to samples/videoplayer/src/videoPlayerMain/kotlin/Disposable.kt index 07c9e495bbb..91567c5722d 100644 --- a/samples/videoplayer/src/main/kotlin/Disposable.kt +++ b/samples/videoplayer/src/videoPlayerMain/kotlin/Disposable.kt @@ -1,19 +1,10 @@ /* - * Copyright 2010-2017 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. */ +package sample.videoplayer + import kotlinx.cinterop.* /** diff --git a/samples/videoplayer/src/main/kotlin/Queue.kt b/samples/videoplayer/src/videoPlayerMain/kotlin/Queue.kt similarity index 60% rename from samples/videoplayer/src/main/kotlin/Queue.kt rename to samples/videoplayer/src/videoPlayerMain/kotlin/Queue.kt index b83b60434e1..b8ec33e9563 100644 --- a/samples/videoplayer/src/main/kotlin/Queue.kt +++ b/samples/videoplayer/src/videoPlayerMain/kotlin/Queue.kt @@ -1,19 +1,10 @@ /* - * Copyright 2010-2017 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. */ +package sample.videoplayer + class Queue(val maxSize: Int) { private val array = kotlin.arrayOfNulls(maxSize) private var head = 0 diff --git a/samples/videoplayer/src/main/kotlin/SDLAudio.kt b/samples/videoplayer/src/videoPlayerMain/kotlin/SDLAudio.kt similarity index 83% rename from samples/videoplayer/src/main/kotlin/SDLAudio.kt rename to samples/videoplayer/src/videoPlayerMain/kotlin/SDLAudio.kt index 53f4bb6d037..f402dfb407b 100644 --- a/samples/videoplayer/src/main/kotlin/SDLAudio.kt +++ b/samples/videoplayer/src/videoPlayerMain/kotlin/SDLAudio.kt @@ -1,19 +1,10 @@ /* - * Copyright 2010-2017 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. */ +package sample.videoplayer + import kotlin.native.concurrent.Worker import kotlinx.cinterop.* import sdl.* diff --git a/samples/videoplayer/src/videoPlayerMain/kotlin/SDLErrors.kt b/samples/videoplayer/src/videoPlayerMain/kotlin/SDLErrors.kt new file mode 100644 index 00000000000..cef42972d0e --- /dev/null +++ b/samples/videoplayer/src/videoPlayerMain/kotlin/SDLErrors.kt @@ -0,0 +1,16 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package sample.videoplayer + +import sdl.SDL_GetError +import kotlinx.cinterop.* + +fun throwSDLError(name: String): Nothing = + throw Error("SDL_$name Error: ${SDL_GetError()!!.toKString()}") + +fun checkSDLError(name: String, result: Int) { + if (result != 0) throwSDLError(name) +} diff --git a/samples/videoplayer/src/main/kotlin/SDLInput.kt b/samples/videoplayer/src/videoPlayerMain/kotlin/SDLInput.kt similarity index 54% rename from samples/videoplayer/src/main/kotlin/SDLInput.kt rename to samples/videoplayer/src/videoPlayerMain/kotlin/SDLInput.kt index f7cc2986afd..8b245c08a1f 100644 --- a/samples/videoplayer/src/main/kotlin/SDLInput.kt +++ b/samples/videoplayer/src/videoPlayerMain/kotlin/SDLInput.kt @@ -1,19 +1,10 @@ /* - * Copyright 2010-2017 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. */ +package sample.videoplayer + import kotlinx.cinterop.* import sdl.* diff --git a/samples/videoplayer/src/main/kotlin/SDLVideo.kt b/samples/videoplayer/src/videoPlayerMain/kotlin/SDLVideo.kt similarity index 80% rename from samples/videoplayer/src/main/kotlin/SDLVideo.kt rename to samples/videoplayer/src/videoPlayerMain/kotlin/SDLVideo.kt index 5cdc4e6ee11..33c1f04578c 100644 --- a/samples/videoplayer/src/main/kotlin/SDLVideo.kt +++ b/samples/videoplayer/src/videoPlayerMain/kotlin/SDLVideo.kt @@ -1,19 +1,10 @@ /* - * Copyright 2010-2017 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. */ +package sample.videoplayer + import ffmpeg.AV_PIX_FMT_NONE import ffmpeg.AV_PIX_FMT_RGB24 import ffmpeg.AV_PIX_FMT_RGB32 @@ -72,7 +63,7 @@ class SDLVideo : DisposableContainer() { class SDLRendererWindow(windowPos: Dimensions, videoSize: Dimensions) : DisposableContainer() { private val window = sdlDisposable("CreateWindow", - SDL_CreateWindow("KoPlayer", windowPos.w, windowPos.h, videoSize.w, videoSize.h, SDL_WINDOW_SHOWN), + SDL_CreateWindow("VideoPlayer", windowPos.w, windowPos.h, videoSize.w, videoSize.h, SDL_WINDOW_SHOWN), ::SDL_DestroyWindow) private val renderer = sdlDisposable("CreateRenderer", SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED or SDL_RENDERER_PRESENTVSYNC), diff --git a/samples/videoplayer/src/main/kotlin/VideoPlayer.kt b/samples/videoplayer/src/videoPlayerMain/kotlin/VideoPlayer.kt similarity index 88% rename from samples/videoplayer/src/main/kotlin/VideoPlayer.kt rename to samples/videoplayer/src/videoPlayerMain/kotlin/VideoPlayer.kt index 213ec53cef6..4ec998a9ff3 100644 --- a/samples/videoplayer/src/main/kotlin/VideoPlayer.kt +++ b/samples/videoplayer/src/videoPlayerMain/kotlin/VideoPlayer.kt @@ -1,19 +1,10 @@ /* - * Copyright 2010-2017 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. */ +package sample.videoplayer + import ffmpeg.* import kotlin.system.* import kotlinx.cinterop.* @@ -165,8 +156,8 @@ class VideoPlayer(val requestedSize: Dimensions?) : DisposableContainer() { } fun main(args: Array) { - if (args.size < 1) { - println("usage: koplayer file.ext [ | 'video' | 'audio' | 'both']") + if (args.isEmpty()) { + println("Usage: videoplayer.kexe [ | 'video' | 'audio' | 'both']") exitProcess(1) } av_register_all() diff --git a/samples/weather_function/function/src/main/kotlin/org/example/weather_func/Weather.kt b/samples/weather_function/function/src/main/kotlin/org/example/weather_func/Weather.kt index 6be28beafdb..84f34363918 100644 --- a/samples/weather_function/function/src/main/kotlin/org/example/weather_func/Weather.kt +++ b/samples/weather_function/function/src/main/kotlin/org/example/weather_func/Weather.kt @@ -1,3 +1,8 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + package org.example.weather_func /** Models the current weather for a location. */ diff --git a/samples/weather_function/function/src/main/kotlin/org/example/weather_func/curl.kt b/samples/weather_function/function/src/main/kotlin/org/example/weather_func/curl.kt index 188f0868654..e5a11a74b14 100644 --- a/samples/weather_function/function/src/main/kotlin/org/example/weather_func/curl.kt +++ b/samples/weather_function/function/src/main/kotlin/org/example/weather_func/curl.kt @@ -1,3 +1,8 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + package org.example.weather_func import org.example.weather_func.Event diff --git a/samples/weather_function/function/src/main/kotlin/org/example/weather_func/events.kt b/samples/weather_function/function/src/main/kotlin/org/example/weather_func/events.kt index ba275ecb2e8..1d7924001c6 100644 --- a/samples/weather_function/function/src/main/kotlin/org/example/weather_func/events.kt +++ b/samples/weather_function/function/src/main/kotlin/org/example/weather_func/events.kt @@ -1,3 +1,8 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + package org.example.weather_func internal typealias EventHandler = (T) -> Unit diff --git a/samples/weather_function/function/src/main/kotlin/org/example/weather_func/json.kt b/samples/weather_function/function/src/main/kotlin/org/example/weather_func/json.kt index 9cf7d8392eb..2ffa3a4f98c 100644 --- a/samples/weather_function/function/src/main/kotlin/org/example/weather_func/json.kt +++ b/samples/weather_function/function/src/main/kotlin/org/example/weather_func/json.kt @@ -1,3 +1,8 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + package org.example.weather_func import cjson.cJSON_CreateObject as createJsonObject diff --git a/samples/weather_function/function/src/main/kotlin/org/example/weather_func/main.kt b/samples/weather_function/function/src/main/kotlin/org/example/weather_func/main.kt index 154b33c7557..21f8adceba9 100644 --- a/samples/weather_function/function/src/main/kotlin/org/example/weather_func/main.kt +++ b/samples/weather_function/function/src/main/kotlin/org/example/weather_func/main.kt @@ -1,3 +1,8 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + package org.example.weather_func import platform.posix.* diff --git a/samples/win32/README.md b/samples/win32/README.md index a7b86d6242f..3d48fc52e37 100644 --- a/samples/win32/README.md +++ b/samples/win32/README.md @@ -1,5 +1,7 @@ # WIN32 Hello World -To build use `..\gradlew assemble` or `build.bat`. +To build use `..\gradlew assemble`. -To run use `.\build\exe\main\release\MessageBox.exe`. +To run use `..\gradlew runProgram` or execute the program directly: + + `.\build\exe\main\release\MessageBox.exe`. diff --git a/samples/win32/build.bat b/samples/win32/build.bat deleted file mode 100644 index a39c906b2f4..00000000000 --- a/samples/win32/build.bat +++ /dev/null @@ -1,15 +0,0 @@ -@echo off -setlocal -set DIR=. - -if defined KONAN_HOME ( - set "PATH=%KONAN_HOME%\bin;%PATH%" -) else ( - set "PATH=..\..\dist\bin;..\..\bin;%PATH%" -) - -if "%TARGET%" == "" set TARGET=mingw - -set "LFLAGS=-Wl,--subsystem,windows" - -call konanc -target "%TARGET%" "%DIR%\src\main\kotlin\MessageBox.kt" -linkerOpts "%LFLAGS%" -opt -o MessageBox || exit /b diff --git a/samples/win32/build.gradle b/samples/win32/build.gradle index 727b8c69b87..c1f2113a36a 100644 --- a/samples/win32/build.gradle +++ b/samples/win32/build.gradle @@ -1,11 +1,15 @@ -apply plugin: 'org.jetbrains.kotlin.platform.native' +plugins { + id 'kotlin-multiplatform' +} -components.main { - targets = ['mingw_x64'] - outputKinds = [EXECUTABLE] - baseName = 'MessageBox' - - target('mingw_x64') { - linkerOpts "-Wl,--subsystem,windows" +kotlin { + targets { + fromPreset(MPPTools.defaultHostPreset(project, [presets.mingwX64]), 'win32') { + compilations.main.outputKinds 'EXECUTABLE' + compilations.main.entryPoint 'sample.win32.main' + compilations.main.linkerOpts '-Wl,--subsystem,windows' + } } } + +MPPTools.createRunTask(project, 'runProgram', kotlin.targets.win32) diff --git a/samples/win32/gradle.properties b/samples/win32/gradle.properties new file mode 100644 index 00000000000..790a07d5124 --- /dev/null +++ b/samples/win32/gradle.properties @@ -0,0 +1,2 @@ +kotlin.code.style=official +kotlin.import.noCommonSourceSets=true diff --git a/samples/win32/src/main/kotlin/MessageBox.kt b/samples/win32/src/win32Main/kotlin/MessageBox.kt similarity index 72% rename from samples/win32/src/main/kotlin/MessageBox.kt rename to samples/win32/src/win32Main/kotlin/MessageBox.kt index a9aaa5048d6..528d47db842 100644 --- a/samples/win32/src/main/kotlin/MessageBox.kt +++ b/samples/win32/src/win32Main/kotlin/MessageBox.kt @@ -1,7 +1,14 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package sample.win32 + import kotlinx.cinterop.* import platform.windows.* -fun main(args: Array) { +fun main() { val message = StringBuilder() memScoped { val buffer = allocArray(MAX_PATH) diff --git a/samples/workers/README.md b/samples/workers/README.md index 85ab38fceee..0601c160bdb 100644 --- a/samples/workers/README.md +++ b/samples/workers/README.md @@ -1,11 +1,11 @@ # Workers - This example shows how one could implement computation offload to other workers +This example shows how one could implement computation offload to other workers (usually mapped to OS threads) and transfer data back and forth between workers. Idea of workers is to avoid most common problems with concurrent programming, related to simultaneous computations on the same data. Instead, each object belongs to one or other worker's object graph, but could be disconnected from one worker -and connected to other worker. This relies on fact that memory management +and connected to other worker. This relies on the fact that memory management engine can ensure, that one worker doesn't keep references to certain object and whatever it refers to, and so the object could be safely transferred to another worker. @@ -15,11 +15,13 @@ between workers, as long, as they do not refer to objects, having external refer The transfer is implemented with the function `execute()` having the following signature - fun execute(mode: TransferMode, - producer: () -> T1, - @VolatileLambda job: (T1) -> T2): Future + fun execute( + mode: TransferMode, + producer: () -> T1, + @VolatileLambda job: (T1) -> T2 + ): Future - Kotlin/Native runtime invokes `producer()` function, and makes sure object it produces +Kotlin/Native runtime invokes `producer()` function, and makes sure object it produces have a property, that no external references to subgraph rooted by this object, exists. If property doesn't hold, either (depending on `mode` argument) exception is being thrown or program may crash unexpectedly. @@ -29,11 +31,13 @@ is being created. Once worker peeks the job from the queue, it executes stateles with object provided, and stores stable pointer to result in future's data. Whenever future is being consumed, object is passed to the consumer's callback. - This particular example starts several workers, and gives them some computational jobs. +This particular example starts several workers, and gives them some computational jobs. 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 assemble` +To build use `../gradlew assemble`. -To run use `./build/exe/main/release/workers.kexe` +To run use `../gradlew runProgram` or execute the program directly: + + ./build/bin/workers/main/release/executable/workers.kexe diff --git a/samples/workers/build.gradle b/samples/workers/build.gradle index dc821bd5983..d34dfc21d32 100644 --- a/samples/workers/build.gradle +++ b/samples/workers/build.gradle @@ -1,5 +1,14 @@ -apply plugin: 'org.jetbrains.kotlin.platform.native' +plugins { + id 'kotlin-multiplatform' +} -components.main { - outputKinds = [ EXECUTABLE ] -} \ No newline at end of file +kotlin { + targets { + fromPreset(MPPTools.defaultHostPreset(project), 'workers') { + compilations.main.outputKinds 'EXECUTABLE' + compilations.main.entryPoint 'sample.workers.main' + } + } +} + +MPPTools.createRunTask(project, 'runProgram', kotlin.targets.workers) diff --git a/samples/workers/build.sh b/samples/workers/build.sh deleted file mode 100755 index 4366dee4717..00000000000 --- a/samples/workers/build.sh +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env bash - -DIR=$(cd "$(dirname "${BASH_SOURCE[0]}" )" && pwd ) - -source "$DIR/../konan.sh" - -SUFFIX=kexe -if [ x$TARGET == x ]; then -case "$OSTYPE" in - darwin*) TARGET=macbook ;; - linux*) TARGET=linux ;; - msys*) TARGET=mingw; SUFFIX=exe ;; - *) echo "unknown: $OSTYPE" && exit 1;; -esac -fi - -var=CFLAGS_${TARGET} -CFLAGS=${!var} -var=LINKER_ARGS_${TARGET} -LINKER_ARGS=${!var} -var=COMPILER_ARGS_${TARGET} -COMPILER_ARGS=${!var} # add -opt for an optimized build. - -mkdir -p $DIR/build/bin/ - -konanc $COMPILER_ARGS -target $TARGET $DIR/src/main/kotlin/Workers.kt \ - -o $DIR/build/bin/Workers || exit 1 - -echo "Artifact could be found at $DIR/build/bin/Workers.$SUFFIX" diff --git a/samples/workers/gradle.properties b/samples/workers/gradle.properties new file mode 100644 index 00000000000..790a07d5124 --- /dev/null +++ b/samples/workers/gradle.properties @@ -0,0 +1,2 @@ +kotlin.code.style=official +kotlin.import.noCommonSourceSets=true diff --git a/samples/workers/src/main/kotlin/Workers.kt b/samples/workers/src/workersMain/kotlin/Workers.kt similarity index 62% rename from samples/workers/src/main/kotlin/Workers.kt rename to samples/workers/src/workersMain/kotlin/Workers.kt index 80337fb4722..e1aea903558 100644 --- a/samples/workers/src/main/kotlin/Workers.kt +++ b/samples/workers/src/workersMain/kotlin/Workers.kt @@ -1,22 +1,31 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package sample.workers + import kotlin.native.concurrent.* data class WorkerArgument(val intParam: Int, val stringParam: String) data class WorkerResult(val intResult: Int, val stringResult: String) -fun main(args: Array) { +fun main() { val COUNT = 5 - val workers = Array(COUNT, { _ -> Worker.start()}) + val workers = Array(COUNT, { _ -> Worker.start() }) - for (attempt in 1 .. 3) { - val futures = Array(workers.size, { workerIndex -> workers[workerIndex].execute(TransferMode.SAFE, { - WorkerArgument(workerIndex, "attempt $attempt") }) { input -> + for (attempt in 1..3) { + val futures = Array(workers.size) { workerIndex -> + workers[workerIndex].execute(TransferMode.SAFE, { + WorkerArgument(workerIndex, "attempt $attempt") + }) { input -> var sum = 0 for (i in 0..input.intParam * 1000) { sum += i } WorkerResult(sum, input.stringParam + " result") } - }) + } val futureSet = futures.toSet() var consumed = 0 while (consumed < futureSet.size) { @@ -32,5 +41,5 @@ fun main(args: Array) { workers.forEach { it.requestTermination().result } - println("OK") + println("Workers: OK") } diff --git a/samples/zephyr/build.sh b/samples/zephyr/build.sh index 6bf9e158233..219835d1cb0 100755 --- a/samples/zephyr/build.sh +++ b/samples/zephyr/build.sh @@ -10,7 +10,11 @@ fi DIR=$(cd "$(dirname "${BASH_SOURCE[0]}" )" && pwd ) -source "$DIR/../konan.sh" +if [ -z "$KONAN_HOME" ]; then + PATH="$DIR/../../dist/bin:$DIR/../../bin:$PATH" +else + PATH="$KONAN_HOME/bin:$PATH" +fi if [ x$TARGET == x ]; then case "$OSTYPE" in diff --git a/samples/zephyr/c_interop/platforms/stm32f4_disco.bat b/samples/zephyr/c_interop/platforms/stm32f4_disco.bat index 34766bbbdd1..29691b380b6 100644 --- a/samples/zephyr/c_interop/platforms/stm32f4_disco.bat +++ b/samples/zephyr/c_interop/platforms/stm32f4_disco.bat @@ -1,16 +1,7 @@ -:: Copyright 2010-2017 JetBrains s.r.o. :: -:: Licensed under the Apache License, Version 2.0 (the "License"); -:: you may not use this file except in compliance with the License. -:: You may obtain a copy of the License at +:: Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license +:: that can be found in the license/LICENSE.txt file. :: -:: http://www.apache.org/licenses/LICENSE-2.0 -:: -:: Unless required by applicable law or agreed to in writing, software -:: distributed under the License is distributed on an "AS IS" BASIS, -:: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -:: See the License for the specific language governing permissions and -:: limitations under the License. :: This is board specific. diff --git a/samples/zephyr/c_interop/platforms/stm32f4_disco.def b/samples/zephyr/c_interop/platforms/stm32f4_disco.def index 461af256e6f..5ca817be221 100644 --- a/samples/zephyr/c_interop/platforms/stm32f4_disco.def +++ b/samples/zephyr/c_interop/platforms/stm32f4_disco.def @@ -1,17 +1,7 @@ -# Copyright 2010-2018 JetBrains s.r.o. # -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at +# Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license +# that can be found in the license/LICENSE.txt file. # -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - # Keep this one board independent. diff --git a/samples/zephyr/c_interop/platforms/stm32f4_disco.sh b/samples/zephyr/c_interop/platforms/stm32f4_disco.sh index e3a93190dbf..3334ff5daa4 100644 --- a/samples/zephyr/c_interop/platforms/stm32f4_disco.sh +++ b/samples/zephyr/c_interop/platforms/stm32f4_disco.sh @@ -1,16 +1,7 @@ -# Copyright 2010-2017 JetBrains s.r.o. # -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at +# Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license +# that can be found in the license/LICENSE.txt file. # -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. # This is board specific. diff --git a/samples/zephyr/src/main.kt b/samples/zephyr/src/main.kt index 5a21aa74141..46eee98e04b 100644 --- a/samples/zephyr/src/main.kt +++ b/samples/zephyr/src/main.kt @@ -1,17 +1,6 @@ /* - * Copyright 2010-2018 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. */ import platform.zephyr.stm32f4_disco.* @@ -34,6 +23,6 @@ fun blinky(value: Int) { } } -fun main(args: Array) { +fun main() { blinky(1) }