From daf1a5fb8cdba2aea97d3a0cf53ad919fdb02b13 Mon Sep 17 00:00:00 2001 From: Dmitriy Dolovov <41585329+ddolovov@users.noreply.github.com> Date: Fri, 26 Oct 2018 12:16:13 +0700 Subject: [PATCH] Kotlin/Native samples ported to MPP Gradle DSL (#2261) --- .gitignore | 1 + DISTRO_README.md | 35 +--- GRADLE_PLUGIN.md | 2 +- build.gradle | 66 ++++--- .../org/jetbrains/kotlin/CopySamples.kt | 55 ++++++ samples/README.md | 42 +++-- samples/androidNativeActivity/README.md | 13 +- samples/androidNativeActivity/build.gradle | 115 +++++++----- samples/androidNativeActivity/build.sh | 5 + .../androidNativeActivity/gradle.properties | 3 +- .../gradle/wrapper/gradle-wrapper.jar | Bin 56177 -> 54413 bytes .../gradle/wrapper/gradle-wrapper.properties | 2 +- samples/androidNativeActivity/settings.gradle | 22 ++- .../{main => arm32Main}/AndroidManifest.xml | 0 .../assets/kotlin_logo.bmp | Bin .../src/arm32Main/kotlin/BMPHeader.kt | 7 + .../{main => arm32Main}/kotlin/Disposable.kt | 17 +- .../src/{main => arm32Main}/kotlin/Engine.kt | 18 +- .../{main => arm32Main}/kotlin/JniBridge.kt | 18 +- .../{main => arm32Main}/kotlin/Polyhedra.kt | 18 +- .../{main => arm32Main}/kotlin/Renderer.kt | 23 +-- .../src/{main => arm32Main}/kotlin/Vectors.kt | 18 +- .../src/arm32Main/kotlin/main.kt | 24 +++ .../res/mipmap-hdpi/konan_activity.png | Bin .../res/mipmap-mdpi/konan_activity.png | Bin .../res/mipmap-xhdpi/konan_activity.png | Bin .../res/mipmap-xxhdpi/konan_activity.png | Bin .../res/values/strings.xml | 0 .../src/main/kotlin/BMPHeader.kt | 33 ---- .../src/main/kotlin/main.kt | 34 ---- .../src/nativeInterop/cinterop/bmpformat.def | 16 ++ samples/build.gradle | 70 ++++--- samples/buildSrc/build.gradle | 26 +++ samples/buildSrc/settings.gradle | 20 ++ samples/buildSrc/src/main/kotlin/Internals.kt | 38 ++++ samples/buildSrc/src/main/kotlin/MPPTools.kt | 76 ++++++++ .../src/main/kotlin/RunKotlinNativeTask.kt | 51 ++++++ samples/calculator/.gitignore | 1 + samples/calculator/README.md | 39 ++-- samples/calculator/android/build.gradle | 44 ----- samples/calculator/androidApp/build.gradle | 26 +++ .../calculator/androidApp/gradle.properties | 2 + .../src/main/AndroidManifest.xml | 7 +- .../src/main/kotlin}/MainActivity.kt | 11 +- .../drawable-v24/ic_launcher_foreground.xml | 0 .../res/drawable/ic_launcher_background.xml | 0 .../src/main/res/layout/activity_main.xml | 0 .../res/mipmap-anydpi-v26/ic_launcher.xml | 0 .../mipmap-anydpi-v26/ic_launcher_round.xml | 0 .../src/main/res/mipmap-hdpi/ic_launcher.png | Bin .../res/mipmap-hdpi/ic_launcher_round.png | Bin .../src/main/res/mipmap-mdpi/ic_launcher.png | Bin .../res/mipmap-mdpi/ic_launcher_round.png | Bin .../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin .../res/mipmap-xhdpi/ic_launcher_round.png | Bin .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin .../res/mipmap-xxhdpi/ic_launcher_round.png | Bin .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin .../res/mipmap-xxxhdpi/ic_launcher_round.png | Bin .../src/main/res/values/colors.xml | 0 .../src/main/res/values/strings.xml | 0 .../src/main/res/values/styles.xml | 0 .../calculator/arithmeticParser/build.gradle | 80 ++++++++ .../arithmeticParser/gradle.properties | 1 + .../src/commonMain/kotlin}/Parser.kt | 35 ++-- samples/calculator/build.gradle | 35 ++-- samples/calculator/build.sh | 5 + samples/calculator/cliApp/build.gradle | 22 +++ samples/calculator/cliApp/gradle.properties | 2 + .../src/jvmMain/kotlin}/JvmCli.kt | 12 +- samples/calculator/common/build.gradle | 23 --- samples/calculator/gradle.properties | 6 +- .../gradle/wrapper/gradle-wrapper.jar | Bin 56177 -> 54413 bytes .../gradle/wrapper/gradle-wrapper.properties | 2 +- samples/calculator/ios/build.gradle | 25 --- .../calculator.xcodeproj/project.pbxproj | 84 +++------ .../contents.xcworkspacedata | 0 .../xcshareddata/IDEWorkspaceChecks.plist | 8 + .../calculator/AppDelegate.swift | 7 +- .../AppIcon.appiconset/Contents.json | 5 + .../Base.lproj/LaunchScreen.storyboard | 0 .../calculator/Base.lproj/Main.storyboard | 0 .../{ios => iosApp}/calculator/Info.plist | 0 .../calculator/ViewController.swift | 9 +- samples/calculator/jvm/build.gradle | 30 --- samples/calculator/settings.gradle | 46 +++-- .../European_Mammals_Red_List_Nov_2009.csv | 0 samples/csvparser/README.md | 8 +- samples/csvparser/build.bat | 16 -- samples/csvparser/build.gradle | 19 +- samples/csvparser/build.sh | 29 --- samples/csvparser/gradle.properties | 3 +- .../kotlin/CsvParser.kt | 19 +- samples/curl/README.md | 6 +- samples/curl/build.gradle | 69 ++++--- samples/curl/gradle.properties | 4 +- .../curl/gradle/wrapper/gradle-wrapper.jar | Bin 56177 -> 0 bytes .../gradle/wrapper/gradle-wrapper.properties | 5 - samples/curl/gradlew | 172 ------------------ samples/curl/gradlew.bat | 84 --------- samples/curl/libcurl.iml | 14 -- samples/curl/settings.gradle | 4 - .../src/{main => curlMain}/kotlin/main.kt | 11 +- samples/echoServer/README.md | 15 ++ samples/echoServer/build.gradle | 16 ++ samples/echoServer/gradle.properties | 2 + .../src/echoServerMain}/kotlin/EchoServer.kt | 21 +-- samples/gitchurn/README.md | 6 +- samples/gitchurn/build.gradle | 38 ++-- samples/gitchurn/build.sh | 32 ---- samples/gitchurn/gradle.properties | 2 + .../kotlin}/GitChurn.kt | 56 +++--- .../kotlin}/GitCommit.kt | 17 +- .../libgit => gitChurnMain/kotlin}/GitDiff.kt | 17 +- .../src/gitChurnMain/kotlin/GitRemote.kt | 16 ++ .../kotlin}/GitRepository.kt | 17 +- .../libgit => gitChurnMain/kotlin}/GitTree.kt | 17 +- .../gitchurn/src/gitChurnMain/kotlin/git.kt | 33 ++++ samples/gitchurn/src/main/kotlin/main.kt | 19 -- .../main/kotlin/org/konan/libgit/GitRemote.kt | 27 --- .../src/main/kotlin/org/konan/libgit/git.kt | 44 ----- .../cinterop}/libgit2.def | 0 samples/globalState/README.md | 6 +- samples/globalState/build.gradle | 23 ++- samples/globalState/gradle.properties | 2 + .../kotlin/Global.kt | 26 +-- .../cinterop}/global.def | 6 +- samples/gradle.properties | 10 +- samples/gradle/wrapper/gradle-wrapper.jar | Bin 56177 -> 54413 bytes .../gradle/wrapper/gradle-wrapper.properties | 2 +- samples/gtk/README.md | 11 +- samples/gtk/build.gradle | 32 ++-- samples/gtk/build.sh | 32 ---- samples/gtk/gradle.properties | 4 +- .../gtk/src/{main => gtkMain}/kotlin/Main.kt | 17 +- .../cinterop}/gtk3.def | 0 samples/html5Canvas/README.md | 15 ++ samples/html5Canvas/build.bat | 27 --- samples/html5Canvas/build.gradle | 75 ++++++++ samples/html5Canvas/build.sh | 34 ---- samples/html5Canvas/gradle.properties | 2 + samples/html5Canvas/index.html | 2 +- .../{main => html5CanvasMain}/kotlin/main.kt | 9 +- .../src/httpServerMain/kotlin/HttpServer.kt | 44 +++++ samples/libcurl/README.md | 7 +- samples/libcurl/build.gradle | 83 +++++---- samples/libcurl/gradle.properties | 2 + .../libcurl => libcurlMain/kotlin}/CUrl.kt | 18 +- .../libcurl => libcurlMain/kotlin}/Event.kt | 7 +- .../cinterop}/libcurl.def | 0 samples/nonBlockingEchoServer/README.md | 7 +- samples/nonBlockingEchoServer/build.gradle | 26 ++- samples/nonBlockingEchoServer/build.sh | 28 --- .../nonBlockingEchoServer/gradle.properties | 3 +- .../kotlin/EchoServer.kt | 21 +-- samples/objc/build.gradle | 19 +- samples/objc/build.sh | 12 -- samples/objc/gradle.properties | 2 + .../src/{main => objcMain}/kotlin/Window.kt | 5 +- samples/opengl/README.md | 8 +- samples/opengl/build.gradle | 18 +- samples/opengl/build.sh | 19 -- samples/opengl/gradle.properties | 2 + .../kotlin/OpenGlTeapot.kt | 19 +- samples/python_extension/build.bat | 3 +- samples/python_extension/build.sh | 18 +- .../src/main/c/kotlin_bridge.c | 15 +- .../src/main/kotlin/Server.kt | 15 +- .../python_extension/src/main/python/main.py | 16 +- .../python_extension/src/main/python/setup.py | 20 +- samples/settings.gradle | 75 +++++--- samples/socket/README.md | 16 -- samples/socket/build.gradle | 6 - samples/socket/build.sh | 12 -- samples/tensorflow/README.md | 26 +-- samples/tensorflow/build.gradle | 62 +++---- samples/tensorflow/build.sh | 44 ----- samples/tensorflow/downloadTensorflow.sh | 8 +- samples/tensorflow/gradle.properties | 4 +- samples/tensorflow/settings.gradle | 4 - .../cinterop}/tensorflow.def | 0 .../kotlin/HelloTensorflow.kt | 9 +- samples/tetris/README.md | 17 +- samples/tetris/build.bat | 19 -- samples/tetris/build.gradle | 165 ++++++++++------- samples/tetris/build.sh | 53 ------ samples/tetris/gradle.properties | 5 + samples/tetris/src/main/kotlin/main.kt | 39 ---- .../cinterop}/sdl.def | 0 .../src/{main => tetrisMain}/kotlin/Config.kt | 20 +- .../kotlin/SDL_Visualizer.kt | 19 +- .../src/{main => tetrisMain}/kotlin/Tetris.kt | 19 +- samples/tetris/src/tetrisMain/kotlin/main.kt | 29 +++ .../{main => tetrisMain}/resources/Info.plist | 0 .../{ => src/tetrisMain/resources}/Tetris.rc | 0 .../{main => tetrisMain}/resources/config.txt | 0 .../resources/tetris_all.bmp | Bin samples/torch/README.md | 26 +-- samples/torch/build.gradle | 65 +++---- samples/torch/build.sh | 45 ----- samples/torch/downloadMNIST.sh | 20 +- samples/torch/downloadTorch.sh | 7 +- samples/torch/gradle.properties | 4 +- samples/torch/settings.gradle | 4 - .../cinterop}/torch.def | 0 .../kotlin/ClassifierDemo.kt | 11 +- .../src/{main => torchMain}/kotlin/Dataset.kt | 18 +- .../{main => torchMain}/kotlin/Disposable.kt | 7 + .../src/{main => torchMain}/kotlin/Modules.kt | 7 + .../{main => torchMain}/kotlin/SmallDemos.kt | 7 + .../src/{main => torchMain}/kotlin/Tensors.kt | 7 + samples/uikit/README.md | 2 +- samples/uikit/build.gradle | 64 ++++++- samples/uikit/build.sh | 12 -- samples/uikit/gradle.properties | 2 + samples/uikit/konan.xcodeproj/project.pbxproj | 29 +-- .../xcshareddata/IDEWorkspaceChecks.plist | 8 + .../AppIcon.appiconset/Contents.json | 5 + .../src/{main => iosMain}/kotlin/main.kt | 7 + samples/videoplayer/README.md | 9 +- samples/videoplayer/build.gradle | 108 +++++------ samples/videoplayer/gradle.properties | 2 + .../videoplayer/src/main/kotlin/Dimensions.kt | 20 -- .../videoplayer/src/main/kotlin/SDLErrors.kt | 25 --- .../cinterop}/ffmpeg.def | 0 .../cinterop}/sdl.def | 0 .../kotlin/DecoderWorker.kt | 17 +- .../src/videoPlayerMain/kotlin/Dimensions.kt | 11 ++ .../kotlin/Disposable.kt | 17 +- .../{main => videoPlayerMain}/kotlin/Queue.kt | 17 +- .../kotlin/SDLAudio.kt | 17 +- .../src/videoPlayerMain/kotlin/SDLErrors.kt | 16 ++ .../kotlin/SDLInput.kt | 17 +- .../kotlin/SDLVideo.kt | 19 +- .../kotlin/VideoPlayer.kt | 21 +-- .../org/example/weather_func/Weather.kt | 5 + .../kotlin/org/example/weather_func/curl.kt | 5 + .../kotlin/org/example/weather_func/events.kt | 5 + .../kotlin/org/example/weather_func/json.kt | 5 + .../kotlin/org/example/weather_func/main.kt | 5 + samples/win32/README.md | 6 +- samples/win32/build.bat | 15 -- samples/win32/build.gradle | 20 +- samples/win32/gradle.properties | 2 + .../{main => win32Main}/kotlin/MessageBox.kt | 9 +- samples/workers/README.md | 22 ++- samples/workers/build.gradle | 17 +- samples/workers/build.sh | 29 --- samples/workers/gradle.properties | 2 + .../{main => workersMain}/kotlin/Workers.kt | 23 ++- samples/zephyr/build.sh | 6 +- .../c_interop/platforms/stm32f4_disco.bat | 13 +- .../c_interop/platforms/stm32f4_disco.def | 14 +- .../c_interop/platforms/stm32f4_disco.sh | 13 +- samples/zephyr/src/main.kt | 17 +- 255 files changed, 2161 insertions(+), 2461 deletions(-) create mode 100644 buildSrc/plugins/src/main/kotlin/org/jetbrains/kotlin/CopySamples.kt create mode 100755 samples/androidNativeActivity/build.sh rename samples/androidNativeActivity/src/{main => arm32Main}/AndroidManifest.xml (100%) rename samples/androidNativeActivity/src/{main => arm32Main}/assets/kotlin_logo.bmp (100%) create mode 100644 samples/androidNativeActivity/src/arm32Main/kotlin/BMPHeader.kt rename samples/androidNativeActivity/src/{main => arm32Main}/kotlin/Disposable.kt (74%) rename samples/androidNativeActivity/src/{main => arm32Main}/kotlin/Engine.kt (93%) rename samples/androidNativeActivity/src/{main => arm32Main}/kotlin/JniBridge.kt (86%) rename samples/androidNativeActivity/src/{main => arm32Main}/kotlin/Polyhedra.kt (82%) rename samples/androidNativeActivity/src/{main => arm32Main}/kotlin/Renderer.kt (94%) rename samples/androidNativeActivity/src/{main => arm32Main}/kotlin/Vectors.kt (69%) create mode 100644 samples/androidNativeActivity/src/arm32Main/kotlin/main.kt rename samples/androidNativeActivity/src/{main => arm32Main}/res/mipmap-hdpi/konan_activity.png (100%) rename samples/androidNativeActivity/src/{main => arm32Main}/res/mipmap-mdpi/konan_activity.png (100%) rename samples/androidNativeActivity/src/{main => arm32Main}/res/mipmap-xhdpi/konan_activity.png (100%) rename samples/androidNativeActivity/src/{main => arm32Main}/res/mipmap-xxhdpi/konan_activity.png (100%) rename samples/androidNativeActivity/src/{main => arm32Main}/res/values/strings.xml (100%) delete mode 100644 samples/androidNativeActivity/src/main/kotlin/BMPHeader.kt delete mode 100644 samples/androidNativeActivity/src/main/kotlin/main.kt create mode 100644 samples/androidNativeActivity/src/nativeInterop/cinterop/bmpformat.def create mode 100644 samples/buildSrc/build.gradle create mode 100644 samples/buildSrc/settings.gradle create mode 100644 samples/buildSrc/src/main/kotlin/Internals.kt create mode 100644 samples/buildSrc/src/main/kotlin/MPPTools.kt create mode 100644 samples/buildSrc/src/main/kotlin/RunKotlinNativeTask.kt create mode 100644 samples/calculator/.gitignore delete mode 100644 samples/calculator/android/build.gradle create mode 100644 samples/calculator/androidApp/build.gradle create mode 100644 samples/calculator/androidApp/gradle.properties rename samples/calculator/{android => androidApp}/src/main/AndroidManifest.xml (76%) rename samples/calculator/{android/src/main/kotlin/org/konan/calculator => androidApp/src/main/kotlin}/MainActivity.kt (71%) rename samples/calculator/{android => androidApp}/src/main/res/drawable-v24/ic_launcher_foreground.xml (100%) rename samples/calculator/{android => androidApp}/src/main/res/drawable/ic_launcher_background.xml (100%) rename samples/calculator/{android => androidApp}/src/main/res/layout/activity_main.xml (100%) rename samples/calculator/{android => androidApp}/src/main/res/mipmap-anydpi-v26/ic_launcher.xml (100%) rename samples/calculator/{android => androidApp}/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml (100%) rename samples/calculator/{android => androidApp}/src/main/res/mipmap-hdpi/ic_launcher.png (100%) rename samples/calculator/{android => androidApp}/src/main/res/mipmap-hdpi/ic_launcher_round.png (100%) rename samples/calculator/{android => androidApp}/src/main/res/mipmap-mdpi/ic_launcher.png (100%) rename samples/calculator/{android => androidApp}/src/main/res/mipmap-mdpi/ic_launcher_round.png (100%) rename samples/calculator/{android => androidApp}/src/main/res/mipmap-xhdpi/ic_launcher.png (100%) rename samples/calculator/{android => androidApp}/src/main/res/mipmap-xhdpi/ic_launcher_round.png (100%) rename samples/calculator/{android => androidApp}/src/main/res/mipmap-xxhdpi/ic_launcher.png (100%) rename samples/calculator/{android => androidApp}/src/main/res/mipmap-xxhdpi/ic_launcher_round.png (100%) rename samples/calculator/{android => androidApp}/src/main/res/mipmap-xxxhdpi/ic_launcher.png (100%) rename samples/calculator/{android => androidApp}/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png (100%) rename samples/calculator/{android => androidApp}/src/main/res/values/colors.xml (100%) rename samples/calculator/{android => androidApp}/src/main/res/values/strings.xml (100%) rename samples/calculator/{android => androidApp}/src/main/res/values/styles.xml (100%) create mode 100644 samples/calculator/arithmeticParser/build.gradle create mode 100644 samples/calculator/arithmeticParser/gradle.properties rename samples/calculator/{common/src/main/kotlin/org/konan/arithmeticparser => arithmeticParser/src/commonMain/kotlin}/Parser.kt (88%) create mode 100755 samples/calculator/build.sh create mode 100644 samples/calculator/cliApp/build.gradle create mode 100644 samples/calculator/cliApp/gradle.properties rename samples/calculator/{jvm/src/main/kotlin/org/konan/calculator => cliApp/src/jvmMain/kotlin}/JvmCli.kt (62%) delete mode 100644 samples/calculator/common/build.gradle delete mode 100644 samples/calculator/ios/build.gradle rename samples/calculator/{ios => iosApp}/calculator.xcodeproj/project.pbxproj (84%) rename samples/calculator/{ios => iosApp}/calculator.xcodeproj/project.xcworkspace/contents.xcworkspacedata (100%) create mode 100644 samples/calculator/iosApp/calculator.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist rename samples/calculator/{ios => iosApp}/calculator/AppDelegate.swift (92%) rename samples/calculator/{ios => iosApp}/calculator/Assets.xcassets/AppIcon.appiconset/Contents.json (94%) rename samples/calculator/{ios => iosApp}/calculator/Base.lproj/LaunchScreen.storyboard (100%) rename samples/calculator/{ios => iosApp}/calculator/Base.lproj/Main.storyboard (100%) rename samples/calculator/{ios => iosApp}/calculator/Info.plist (100%) rename samples/calculator/{ios => iosApp}/calculator/ViewController.swift (96%) delete mode 100644 samples/calculator/jvm/build.gradle mode change 100755 => 100644 samples/csvparser/European_Mammals_Red_List_Nov_2009.csv delete mode 100644 samples/csvparser/build.bat delete mode 100755 samples/csvparser/build.sh rename samples/csvparser/src/{main => csvParserMain}/kotlin/CsvParser.kt (71%) delete mode 100644 samples/curl/gradle/wrapper/gradle-wrapper.jar delete mode 100644 samples/curl/gradle/wrapper/gradle-wrapper.properties delete mode 100755 samples/curl/gradlew delete mode 100644 samples/curl/gradlew.bat delete mode 100755 samples/curl/libcurl.iml delete mode 100644 samples/curl/settings.gradle rename samples/curl/src/{main => curlMain}/kotlin/main.kt (56%) create mode 100644 samples/echoServer/README.md create mode 100644 samples/echoServer/build.gradle create mode 100644 samples/echoServer/gradle.properties rename samples/{socket/src/main => echoServer/src/echoServerMain}/kotlin/EchoServer.kt (78%) delete mode 100755 samples/gitchurn/build.sh create mode 100644 samples/gitchurn/gradle.properties rename samples/gitchurn/src/{main/kotlin/org/konan/libgit => gitChurnMain/kotlin}/GitChurn.kt (62%) rename samples/gitchurn/src/{main/kotlin/org/konan/libgit => gitChurnMain/kotlin}/GitCommit.kt (60%) rename samples/gitchurn/src/{main/kotlin/org/konan/libgit => gitChurnMain/kotlin}/GitDiff.kt (64%) create mode 100644 samples/gitchurn/src/gitChurnMain/kotlin/GitRemote.kt rename samples/gitchurn/src/{main/kotlin/org/konan/libgit => gitChurnMain/kotlin}/GitRepository.kt (76%) rename samples/gitchurn/src/{main/kotlin/org/konan/libgit => gitChurnMain/kotlin}/GitTree.kt (74%) create mode 100644 samples/gitchurn/src/gitChurnMain/kotlin/git.kt delete mode 100644 samples/gitchurn/src/main/kotlin/main.kt delete mode 100644 samples/gitchurn/src/main/kotlin/org/konan/libgit/GitRemote.kt delete mode 100644 samples/gitchurn/src/main/kotlin/org/konan/libgit/git.kt rename samples/gitchurn/src/{main/c_interop => nativeInterop/cinterop}/libgit2.def (100%) create mode 100644 samples/globalState/gradle.properties rename samples/globalState/src/{main => globalStateMain}/kotlin/Global.kt (76%) rename samples/globalState/src/{main/c_interop => nativeInterop/cinterop}/global.def (58%) delete mode 100755 samples/gtk/build.sh rename samples/gtk/src/{main => gtkMain}/kotlin/Main.kt (75%) rename samples/gtk/src/{main/c_interop => nativeInterop/cinterop}/gtk3.def (100%) create mode 100644 samples/html5Canvas/README.md delete mode 100644 samples/html5Canvas/build.bat create mode 100644 samples/html5Canvas/build.gradle delete mode 100755 samples/html5Canvas/build.sh create mode 100644 samples/html5Canvas/gradle.properties rename samples/html5Canvas/src/{main => html5CanvasMain}/kotlin/main.kt (84%) create mode 100644 samples/html5Canvas/src/httpServerMain/kotlin/HttpServer.kt create mode 100644 samples/libcurl/gradle.properties rename samples/libcurl/src/{main/kotlin/org/konan/libcurl => libcurlMain/kotlin}/CUrl.kt (79%) rename samples/libcurl/src/{main/kotlin/org/konan/libcurl => libcurlMain/kotlin}/Event.kt (79%) rename samples/libcurl/src/{main/c_interop => nativeInterop/cinterop}/libcurl.def (100%) delete mode 100755 samples/nonBlockingEchoServer/build.sh rename samples/nonBlockingEchoServer/src/{main => nonBlockingEchoServerMain}/kotlin/EchoServer.kt (92%) delete mode 100755 samples/objc/build.sh create mode 100644 samples/objc/gradle.properties rename samples/objc/src/{main => objcMain}/kotlin/Window.kt (99%) delete mode 100755 samples/opengl/build.sh create mode 100644 samples/opengl/gradle.properties rename samples/opengl/src/{main => openglMain}/kotlin/OpenGlTeapot.kt (82%) delete mode 100644 samples/socket/README.md delete mode 100644 samples/socket/build.gradle delete mode 100755 samples/socket/build.sh delete mode 100755 samples/tensorflow/build.sh delete mode 100644 samples/tensorflow/settings.gradle rename samples/tensorflow/src/{main/c_interop => nativeInterop/cinterop}/tensorflow.def (100%) rename samples/tensorflow/src/{main => tensorflowMain}/kotlin/HelloTensorflow.kt (97%) delete mode 100644 samples/tetris/build.bat delete mode 100755 samples/tetris/build.sh create mode 100644 samples/tetris/gradle.properties delete mode 100644 samples/tetris/src/main/kotlin/main.kt rename samples/tetris/src/{main/c_interop => nativeInterop/cinterop}/sdl.def (100%) rename samples/tetris/src/{main => tetrisMain}/kotlin/Config.kt (64%) rename samples/tetris/src/{main => tetrisMain}/kotlin/SDL_Visualizer.kt (96%) rename samples/tetris/src/{main => tetrisMain}/kotlin/Tetris.kt (96%) create mode 100644 samples/tetris/src/tetrisMain/kotlin/main.kt rename samples/tetris/src/{main => tetrisMain}/resources/Info.plist (100%) rename samples/tetris/{ => src/tetrisMain/resources}/Tetris.rc (100%) rename samples/tetris/src/{main => tetrisMain}/resources/config.txt (100%) rename samples/tetris/src/{main => tetrisMain}/resources/tetris_all.bmp (100%) delete mode 100755 samples/torch/build.sh delete mode 100644 samples/torch/settings.gradle rename samples/torch/src/{main/c_interop => nativeInterop/cinterop}/torch.def (100%) rename samples/torch/src/{main => torchMain}/kotlin/ClassifierDemo.kt (94%) rename samples/torch/src/{main => torchMain}/kotlin/Dataset.kt (87%) rename samples/torch/src/{main => torchMain}/kotlin/Disposable.kt (77%) rename samples/torch/src/{main => torchMain}/kotlin/Modules.kt (98%) rename samples/torch/src/{main => torchMain}/kotlin/SmallDemos.kt (92%) rename samples/torch/src/{main => torchMain}/kotlin/Tensors.kt (97%) delete mode 100755 samples/uikit/build.sh create mode 100644 samples/uikit/gradle.properties create mode 100644 samples/uikit/konan.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist rename samples/uikit/src/{main => iosMain}/kotlin/main.kt (85%) create mode 100644 samples/videoplayer/gradle.properties delete mode 100644 samples/videoplayer/src/main/kotlin/Dimensions.kt delete mode 100644 samples/videoplayer/src/main/kotlin/SDLErrors.kt rename samples/videoplayer/src/{main/c_interop => nativeInterop/cinterop}/ffmpeg.def (100%) rename samples/videoplayer/src/{main/c_interop => nativeInterop/cinterop}/sdl.def (100%) rename samples/videoplayer/src/{main => videoPlayerMain}/kotlin/DecoderWorker.kt (96%) create mode 100644 samples/videoplayer/src/videoPlayerMain/kotlin/Dimensions.kt rename samples/videoplayer/src/{main => videoPlayerMain}/kotlin/Disposable.kt (78%) rename samples/videoplayer/src/{main => videoPlayerMain}/kotlin/Queue.kt (60%) rename samples/videoplayer/src/{main => videoPlayerMain}/kotlin/SDLAudio.kt (83%) create mode 100644 samples/videoplayer/src/videoPlayerMain/kotlin/SDLErrors.kt rename samples/videoplayer/src/{main => videoPlayerMain}/kotlin/SDLInput.kt (54%) rename samples/videoplayer/src/{main => videoPlayerMain}/kotlin/SDLVideo.kt (80%) rename samples/videoplayer/src/{main => videoPlayerMain}/kotlin/VideoPlayer.kt (88%) delete mode 100644 samples/win32/build.bat create mode 100644 samples/win32/gradle.properties rename samples/win32/src/{main => win32Main}/kotlin/MessageBox.kt (72%) delete mode 100755 samples/workers/build.sh create mode 100644 samples/workers/gradle.properties rename samples/workers/src/{main => workersMain}/kotlin/Workers.kt (62%) 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 29953ea141f55e3b8fc691d31b5ca8816d89fa87..91ca28c8b802289c3a438766657a5e98f20eff03 100644 GIT binary patch delta 47732 zcmZ6yV{oQT)HRxkZQHhOb7Gr!Y$w+w6HYX-Z6_1k$;7s8oAW*O);Zs)_x$Lp{?k>f zx_0eed#%;C%@8r=5Wjig(kx1bM8LqnG~z|oq0{eOZ(YB|_Y%anc*0-%>ZM*of`Ki< zC0>!@C4T=#2VT7p(~1r?RI5HCZBrWYrs8Xh&# zDi-cU83e7*jI*5Xp=7umi7ub6t7)vs6tit7IlDC@4{k;`PfrP-k}a1f)`Fa?CZ`u1;iN?XcVy{wSPnS}=U<&Y00G{4KklVufjC_{)kKn=^Zo|F%pk zNbsQv4V$!snI%K&S8=7Pu4w6aSCJlOz!Il@vn7p3lZJe{Z7dqwg)Q!cvVpPOVtuP? ze1WGdxbL~Y0OeK2eQH{l=@BI2BAgCmZ9`SIGvGtXx02R+sl?**IcYVmIN>sWudmw- zvMW(d$Wx`e%ZOJfx1{LkV}zM-ZlqJ0{5#Znq#@H(RcK*S9a_ur6Su$M2XYLu>l)*K zr*>>Y*RhzVm}q%}RiQXYG2V@S^M8{UlIb(tNX%oP?f-2;zcL5|&)7})?OP*Ol8bR4 z1YnQG>MQNiV(Zcs#v9nzcCUkJzc2ACr!>ce%TlFJ=0!(zn)!9?&9EXQLjmCl0(o{xscuF+|rSZ zU04f0j^Tw^;HXquD1Q)JRl?Q)?S0sv(BTph~Vpk5ZkIZ$<<1 z8tnlmEqjZ3wQ6O>B`4Ghsnjq%K(i@LY=G`>00YU*RfcF2}z0<)Xx)OBf&nbM0=zOclw{1@fTImxx( z?Gv|kbLz|ENWs}!9&c7nS>cuP9R6drgl`_YDiPJUBx{<+l5>gOo)WyL>JDyGCoG$8 zYhIBeyTDdm;`dOHCtbIk=zWQlIG`lDe$aq4Lp1FWQ#)t<${LXSnu`LS>(fYFtRL(d z@Nlp8otP6kgbi#U2Ok-S8feH?k@{)4_Wr5(-5KTYvThnzt>N{@;Zgw$vL+bz;xvPtt6 zq1~iSNm`@kKc2=_*wWGwFM&!k0BX0m+}f>MeeZ|&iFLFhQUr}RG(9dnQQ6K81!Vu1 zG0CrfmVaOOnBnaCrYtBbtZGsR)7kxq3HmudV83Nh%Z{A-{~~oMb35P;Ce9*b4Rl9) zRx0qwOXb||*9BiuNfwczi4Si{Oc+-te-Yrlev$iv`K|x~i3tV<3yc0=pA-YL3AV5* z{BO7T-=avoCB;s3o`6kUg~kWMa{5S|$(RMj>?Q2sTAFe~^zk@w=gbgMo?u*VQ@yFY+!JCLpwe@dXQMIK)IzF#@FKVD`ot z3Rksy_1pCKU6i8#9L~DU9?Fdj-Zhw}INV}Dn%{Ab+qICF)zfjUlL%PS?TR!y9|5u} z_7Zw4$ef4(&Yrr?enX$T*?C_1F}L|VMs%%I~4lW|>-QSmMeSJjbj=Xmx@m4W<%_&w54sS1}^#;~F0rEIg2=#OTG zq)g zOk!>$Dq(N|BCOg!Ah;lzq?tanfh>%MBjR6LMow%zER&r>O@+J*I@&nSlO5tJ9@CTE zkuRWq6dlR+W=ELD@++cE%9m52@&4}|LVy1g8@ch{NKz#`f839Vs78JYa03G}0tx6< z7uVzh=mktWfStuwhX>&1SWe1ILH0j4ti4(0nOcS1vctAV3syN z9tB(lJa_v|cU^Zs9{0SSPJ^$|G2;TVJMBTHof-pM))x1=tDTIQ+6QMWCofq+#)B-N z7fT3eM_g~L98WXh@PnJ#PJ@MOp%#e zCH7Kf%wUuv7>E^`|CfiD69U4-2dpX-dKqK zIqX1w$&B#0f7FIK;je_Jy8A~N_w7@M{O+P(lhq*LB?oVZ#V4oaG(5>Di&qb0w)HTz z^-iTeLsVtKcc1-hIE1eh!UfD0MK!hCEJ;Q&FX7?hoO__n4nenFOWTq=&J9r;+Aj@F zwnv$i#ODc8Q> zkA>zVC~-)GW++c2cqDw(q|i`jZ-z9N`mrLW#q6F7EOYM*0+Xyae_0W8`C8$aPOFoWGwrvG| z4g>C1K~uleqH|czDZi^|>(Y6N(MBf$*ZV2?OcHk%e!6A(=#+T3o|!H=n$v5X6FWnx z>g0^7tW`EL)Dtg^1)$TE_H>0Jy-jXi0Hjp1pu0iGz-8(q$2X+{{jo}^)CJ;7E-&b) zu-cw<**;-&%y7*_IX!r;F`iNgM={9wb9_jiPJqA;L$v)w2rx)lvKv*{FO&UQw4Q5T z7BD|Hm6K7iDk-HBub6sJC86Qqu~OJP_tw%IA^DSy2c&c}m{e>}%9268s;b3zn`mVk zd~;P@e;glVMV_i*!1#VgujGGpUSR?LroV$4(m+X9sdLX~&ns3(f zyYEX&@U7*T)iE5+x#o9a4!~0JA$QV@&y)MFxpp_ZA|3}RgSsnH>l_+{xoxELjO<7Y zgjby{6<<dbq2`}BS5*t~VqKiEKCSzzi-Bt*W z5?bmcXx8o*#~-gA`>8*>-6&}ODV62``s!d0HcC(_6i z0`y{%sn!u?etk~`DH0CzPnd3j?sRaH0X%xLZK~{2C=7rMMyG1$fra#(yOfMN_xw)_ z1sXiTSw&Tos;IQYJp-0kSz(fD1{r^2>U6a}+_7?+Y6<&5#OZW1wH#M@N=4Hs&=JPy zx>S96jc{^2C!6^%-9AMSV=+GU?VmDkV2IB}I4(==$w4ai&7gws^vHcIie8B~LpI$^ z`3AD@HZhzZj#YbtrI4YHTl23txGJAt`T3kdg&q4TWjnH7_aV!~x?-REk9N?~gd2oN zsUAtKq*KtVE2x3ZNOqL3!(zGts#Wf%_Kgz1FWc#K&EC5O|5%wv~+HiYMLan4%JUgpvJ_ZT+hekvF-mo%!HCEuG}>UR}bGw}rE? z?X<>VjdMkx+o4>s*~PEj&yRntU8qa@v!$@e4&K;8_K&=>nNfKie`{kWs41j5F*6m~ z(!TGuT7jyDcBl{hoQb+ZPdp(K`2GHZaCWDo`J?@Z{x9}1c_#{ocbH2ML*ianefPtj-$0Yd7OS`1c(K(4GWNOLutx;r4XSPbq^O}DAU!_ol&cUVw=vvbfSJO>>3f87OR;^G1lgb=7 zC-0(B5>XJSgjGUke2C_%SutNU(tYU{tn*tUoZN}U@+!BfGp(_e!;*!;&lju7fBJjo z)Ab&k_$54#LUbf+VhOA@Af3}xUNy$=t8v!Zj6UqW5M?w+Q^A$t@BAHI>ppw*wLB>^ zg$s=cH#4Kj(r9)?WUu7Yz$poiWxJus*yBmr!am*2a)uDL|`_${3(Y`-!5l!`Bd8>Yj=f7x}pD81tmWkF#+fGAM*~;a3to${-|C zMD~vD|7s_vP>eC=Wwm~`V%ph(qj^(i?Pd4RRye85z&9$S#L#K#ZansTpBh%|@6vv3 zN>;>g1Z4KTd|B2a08}2l8=(M|IgaV8q=^WlG2GetagRU4jot4ja^`x&9UDS1$d_u6 z9S%`;6e>%Z1F>p|rhVZI-Iw2r-8kBw-)+E|S1Uf1Y*`MbX0flDP80gAjnN>6L441K zgQLErrvAI8MvI4$R2~z0>n{`i5zUa+Jf_i2#F$Gh`SsyXpt+E^#f-^O0d~8ctMM7qpvPs_)RY z7=e2M+@^eU`u_Mhwl|^^na5Px;;-&}il}zRGnJ+$FUEp={|>iXkQL zY{LrXwxRkX<57*N8#WJsI>|zgzm+h=v|P_cyww~5T(Yz*a4j1&KP@yZR5&>(TT_^8;Nkike=&~V>wu{*lq1)ew$+r>ZIZMzq*ujL2q-Z#^JwJU&!t9*pP z8z%4vau)>2ut20{3_8m`%q_F{AsO^b2i_jQmGne=m}6}*{P$hL8^xCH7Jd4Oc;S|^ zc2DNU2(P%H28`zE&e@Cwrj%Yas`N%!10nK&Q0DuIw}`OlIAf4fD$A$fpE%X_kb{)- zR-vtwA?3a!b50D4+wU{#br?hiu5XhSH*WM?wQi3XO!CD)-X|ZTf&?_Ny6q zlG+fOd!+|w3AqN9Rx$eKgq0Kaq{d#uZu=3v??tVUbhAW3I85kueOS%PNT!yeh5NR0 zt_Ug}ni44y6caqNNih~Teh#gy8%KA2dZ&bylRt01l*v;-RkygNsB9VFqrKBo4JOn0 ze0?z@BYTCw{NcqEHu%IN95r(;qVNYaV&kBAW3_oqX@^&HL`zBgoUti{`eaGb56+xB z+lBlEqg2tOJA*N_|KcZB(TwX*d{d3=q;V$Nzr6{GzE@{am&^W3xZlHe)H$MY=PgOJ zYVxjC(~WfQQ|4HbL|ot${St-davae%645de$q6cWKYe{Hdf|;XQaY=CQGEiyvvlJ~ z2JYS0_%gV7o_UEr_g~SGT|vk(;6v51eIBe>q7c#>x3_`pYNyW z#@CGW4eI&v&m3#FZf9@oc;bL|Qf=h{i>gmk_g^8ZgsHIWQgMmh2KhFaBG+A*)hEb) zlu;E{`%x8I!PPQ`XVkhN9l>4|R_xML^V{zsLQLqth8~}EI@uQbq|c)b2NsgqSA->+ za*D-C4x2vNw*05jnn{j{Uf?{EDELC}WZ-r&8{!%(<>CM}BC3gqt_q=8^gc0*#Y-Hj z3!GI1*WAt4VWWtoT(ty|7+p1WkQj`dDGQcQCM&QvQU8`#8b8F8votL1cPvm+$Od979L zbW^H^L_%5Lj_#;gke8z=&S}wMi5e-wXF}(NAMibQ0{?&FNMHmjnh`V@*dapVE}j6O z?}l-V7bvVdw|36Ojm(QS!Zjnwz7qT(O5Z^#-KRn7_Qz#EM0{y3yvw_(vPSENf{L8N zT9JdV{92gneC84Pe7Y4i8tQb2K@&%pV`)!bYTK!jwXf=%f5)GAlva%C7lH2Z}F~B3*aU9nqrd#%ka{GO5gD;6K`JEG)QayS(979pZ6+DLaMz zt|I#BK@w1dq3xnH;DLmI-%U58E|@Li1FHHi=n2~USkc*q3fkJkItpP-(|M0PTQRS3Ol-_luzgY3m zFjAA65ivVabu+w^j%xLU~2%2@r48OEY-f(WLglSG>@^LJ`dY?o3 z<1_A(G_tFxuuy7U^H(h|dh}d#-Pk0826psT{vKR_TrAa7!7b%nz7(6^1oNI=^$!*i zMgw~2uZfD;iK~AC6DN2g}M(@y5und%4Ubvd$W_J9Cn3*rF>@FLgghQ##?qSJm2KCrh7F)NrclMhpK?ClOLJw$0l2SA*0`dy_K_g4? zrkof?n=D-CZSS)e1Zuz-beQu%Zy+HnYXk(iw4Dufcc>GBVE0=nQT4jA?i+OX&ujb_ zVk0t@u&lYxAnnCI)NZF8m{!mZ7uN?WkM2b{_tc`{BVlSHvoq`UV)ma?-yq$)Vl3GP z+j7c`Ln`p}RH1E+Ms^mARM3u0eBm-uRYw9JRJbmjo%NOxmRov2M-0-zl&a^4LKe!BSh>z9a{=+%$(7 z6TBcf+PqW;c{!^MFhTSTAZeYMJ}{Z01eQ4V@ib=qBKuiFZj=qjfgQS$I8_xmf-j}4 zi)G{}XT4;XE(aWLGht}@UOwu@P(v*Ypmd(dnq0TDn1_-TC}|z(E=PQ^gc*+4Ky7%g zHKl~jD)km}a7~xP+(lzez}Xw3;9j04O|W=GeHEW@pWq1aV4Bo`1Npd~(}r=4OBcCJ zROwk1c4pYXD(%NxW~4pkTPMa>l*kfqk!g(+ZG{w!hxG&is}r5AXl?| z?7#4pM|w4-Wz$~`B~h#qb(49yB-ghu8&FU5( zk>50!@mE$mqRu}VObA=UH^KRYh9EdNWi|4Z!2M51i~rFrw{CbfKwrth99O z01ys4_~Z4+AOpRuTLZB83wndJLc{~5ys<$351=979}LYcm=xLoD1R4Gl@KR@HsX?( z%(K4j`p_`U3&w@|;4c(=$uGZ$8$?cDhZ&Vv>w`XYr&jzD8MK=2V2XoD;x+#iYX{jV zVsbpw3+yj3L7CA4_OCF(oa5Fu+#)+Q~K!bH>|N1 zA}lzXF^BVxs=r)0-GQV7xY3<5c`GC#F1|;yIt|9_D864{E^Hb+0FM`58f&v(;*?75PU9%tbV3KOFaJ#BX7kaq~^pm*_L%7bpR12p80!xG4i*?(=+*lBM%X zBqUAmEr7>;I-5HDTb5g`w0W`9UX0Nz~6t+?1#S=vh2)4g{p0uv~ox`-Y0f zm;I+x|4jYOFVX)3t(&$SN-l{=t`*^l7$-MH8rF8+kB&`C{X{i?)>D&8r|++>4U5H+ z7XnlM#kX*S8tH}zgfl+%J6=$UyOwBrKC%37mUdocn^*$>pD%<921fs1EjqbcCqDn@ zZS72=0ogh*{us-6|3rQV+`ZcWv}Ywp6a!SQoFIj;zE95qHo@>PB>maxbtl5lo$$V{m-?A-#Q)Xpgh^6PuUlO z->Njj+A1}}o1*ppK7>DdC@fgC^BL$bDn%q*Mji$C%0-uoGJ0q#Qu5&~8A=j2_Gu13 z1ypzwl4#wc`D+Y~+_+%n_F}*bm+z?4H}A+{-O8LAb34SD4 zJS34Ar$l$}jc8-}E3LV<7<6Ba5Zyf!1p2EFwcI#BZQt&9B)s_1cgKpE(+Nm2PKNR|g&g!u4@>(uHG zY%)cq!qXM?edqA!_VFZ0H6*uIxmLD_PR}N8%RN<}uFkLUC&W@GgR#+)9b>4>m$-vo zACV-$yOG^O<|@eRi)J(B2)WgMzU{V>C36<~`pc>e9c)3pRn_b0nHUZ##)QeJ18=e$ zu(`6Q`}@-Loda7}UYqK73bX6QxK6#dH#GC5 zyZ2?`AAw28OU9VY!a}vxsLle^dK5YBL-BTH{Ml$rbRY)j>uXhK?$VH^aJZ3g@$Ii{ zJ_@AP(sb~mJsSX^uKgKQ5Wy#-m0o1?eU zhd<;hh^7YjC_beZB4YIUI5PvfsR_9pb^c45H3C zqxZCsT6V0EWL!8pW<%lSfB}{pPD9NTW$7>gfpG2!ku7s14HG{w(wOe0DQtVEWsr~h zyDK9G$4P_IKN&dN7ox!0U6hx?U=h#@$5($*23=XUuWywM$?}c%htk0IEeaB7qkI=L zr@XJ<5dN!t*Z8HSR}JOaW4xO%u3<+ISzr=lw6#304u+S8hEos+Xi;GKvTj~4p?f-6 z((&VWpj=T^N5AedI00YqAvK=NNoj74zs0L_U)LcU6fDsT^qnyX|6^IgB;S0GwL32v zNxK-*9|13-iDB8A?QozMCeS3ECzvZ)R$wp(vd3{dz5P`-BUxOgHVCf7i1|%Q!>&M@ zQEkvnY2g=@`=dB z?IacwgA6m~{PclWh=AX$M7*Y*Y>P0Tf{p|2*Ij}@RcXxk%{6z!@hZ+s0sn;vy$l^P zE%`_?rK*IzVAGC-Om$_t>AP857dDA?yD>3}t1$NlAqw$3>}sX-PmCJfs9tj76!AQRdM>KA#U6la$TxMD7URXX2y5Jl;e3$Z*w~8+pMWk zEer0CT^nwK053{Z_o=XNPV>SsI}6GD{AKy9V!x~&jvCX5_7tRySz$URf}MlvIup0F zkq_0=0-Ls-;7G6_d&lW5Jw8{}hrY|`LyV>%E$tN{h4UjJ^DjZ>i)aTVC_g?)%PP;+ zNASncR!+~yP#HM-alH*=?*@TQTen$R*3wmrW=p7NK)-&uD|{+6^bcIeS7&q=bLi>t zwGV&g$T~RYKyz>j$-@|m3fffHzR!^d%Ze-W6X7Jh;mk?jpPQV`QH{v)+tLg^?_In) z-k%p6i|SPZG)Ir__4c7j`WeQLZq zB@e_gwZ*Y(Orz2?H^oZIK+-rYBSK@ThI^4Rb`$XL~@o;@K zacK|sVWNPxjsCzl^11^I{(bLI8CGQ98E+_8AReaLP{I>j*Ic>vEh_8|nx)+h@l4p- zMqlmPhq*X;x^YY0|1Kx<+5WIn=!Fe^wv~=0eE9zO>s$sX%!N^yk&GMTy#-Qda0E=ZV{#V%kRhp^X~SU4Zua zQ?y9(z@tJ=%cGz_zNE5Opv6_jt!%pLTxSnI-Uh9uXm$uGuCBvH_@H9)2+5q&kMF9N zIn<8V;YHT#!L->Ko3b=(h*Ty;kx~ekSx+o58{Fl-#v9r0BX`<1_?4&5S-}u5_lkUMBC9`z=Ov!^N0|Fub zaf}ux5hCy5s(q)e%pN$#{YYv~k840|%Puh*aS6WV1&yPf?D7~pIi?jJaK-g_JRD%2 zg%LnJV%VfXZt9;0XWWT$AeR>bW}-9|vr?({Eirl*b^S^j;7`k{>$IBPA%;Pz?LL~y zo=Q_a98jx^*{Ozy&BmhGEeAS{9o|jN{km1h#%_63s8f3haQ3to%ZVd3+#|8I?x~xf z?%4}|+FaaL^>k5_x&|3TmL1m;QWo&~VVTsLZditOMxzYm2T0Ku7 z%24RMl+9Bi`msy!7iTU2N^Zi0dz-pyp7zzf39udwpjtbzJ-tGH$7%g#IWur=_*84Y zD(#E?L0^c3We?S)Se~pn#-(^c?aQYK827!jumyRsd3bR+6gR~r%?w7j{WSW$SwS>C za1UoJcY=^M6`XeX(2H7Ja>PsFXiQ`cC&90U|BuVm-Ih()1VBFv>oIiW4%+M;YFx8|v{?yRTDXuWa zfVKIH0ioebr=lS9Qa37a3|+!0n7;WD~oTE=_4Se1%BEtLs}X|o9}vot(zO=j^4JE3#8G+@b{ z@{^w8o-Y+D{Lb3-pfmHlT)2h{Ddw*oSj5WACA=cAlhRFHM)xJy1y}r4s8?QY(QkLrhiMYUqb~CT z7SRgCYa9tF17X&qt^eiKn6dKmQ23FBR;24~)Lh5OGfy`L1HwVkk+uq+Tt_@tD%e&H zBx7<3`c=xI1Q39f^tLj}8@1Q2uZH%59-p20O>Z}cZo~IUJ^#5I*IR!2ogfgeB~TMR2LK_yb#G+t0I|&w1)uYCC{j${=oTMXE*%rg8j;ujMz=@#8{@43iC`(r$JAmfR%i6 z8qd>}pSAN^T?|Cqy_r~!wnZz3RO3_WIk8TA`uyE7*Q^6VS8_zhmYp!$i?>4l#v>?2 zK57;sgK+?-VDUb9j#k72CgSw+ZM5P)T%6OU6czky)TnvJMr(tr7|S7i?iW9Q6YEZMevHL`U)gG;h@-Vo_18@%D&*TgmMytW=5^0?%S zzq(`RSf^q+?l{i@&F0w{qS5!rU|g=2Z-pM&^J9Cu>KEOWlZXS}Yr91AWxF|jG8-+> zC~*Wr%m0b8JLxaI8EK=RxzPyr?y#8i>`;81tbgiruH|bq{t=40_mBAE@T}v-1C?oJ zrB=ZqElhrsEha_dnNz%6(i?wQgPc7^mL4rzn$rVrZGORCOk|yQ8G?YVSF6^)c0hOo z!Dr((umHQd9*i@JKG@abO z^NNZ~IC}R~7mnmH9U{dVwEM^#%PJ%?G~}vHcCDXWKlR_~8#)``$s_+-Zj`VBp@w&l zzC$>YRV-^e2cGyWp1+5?W2(I9O zShEX8!SZpPwowr!7I%s637448u_fJCI4XZfEI5bow#BNV_*0Q{$j)C3*GnFNC!J{z z*e3PNieoAB>P$A{$ho=+w55{)6mjt}eC#g427)rw!ph7>lo-a8IL2f$UsK8d`hVy} z1=tE*Y0+&|zPaS$4~ywdm9brD$C=3rg+iR+Ay(qB78nhaJ<=mhlXxb#p&~RivVn(a9^yY)4vvgw>lKmq6{)(0 zGQSQVt;!PIqTxe4L6l!xm=r?iljp#K2QZol&L#Z?MX=&zGBdgwkZaO5Sgmw775wAw z?3xpSEoA43WxU$e&eH2D`}oB9-*0VN3YIP$1{hcs9T*sC;w}qOViylA0Ozl9*d#*3 zkuHG8tWVlo7b{EYw-W!uMmAVdLKJ*Z6wA@dF#(}rP{4~+ta2$>=hAFbuaVh9fbgt#eeHPtZR`A;;WO9InmX}-oV3Td`+c${>k*jp>W*9fdU|k^ z{EuuAZsT%yH-db@1IdtSz{-+zpZZSaDIVOoFF$a1jt zN(s`5w%l5PN@xiYXC!mz&r9h9H>Wwk1rx352;pZmgeiI(UKR1uDU|B_t)XnNafgx(ik+KskLd)BwHRS%42)>^qdq!yx)mgWjbe5$&mYwH>>|s5 zy?nma?zn+>CQKvcdFAvseba+CO4FxO%I16&&ljVudb)pQ|0BIC9m;ZZ9~$VG5Y+UI zKQ6Oa7iZ_uKfa#;(=q;P7>w(#1gv^@621l6ruw__0M2`xQlNc&iTG~yH{0E5T7S78 z+@sHPU`=;6B2J0dfG3C^yvn5`cOWn}qR#i5mvd>^!lAW9w}50qHoOc((Ll6~St0Kf z9H`@fk} z7iTd+PG}Uf%1Ottqa3u~{5G5tLx8XCu(r}#iNc!kX7AHkZpXKQP=uHdxu9u`)JOfGC)}` zK&)hgR+8?BKyW^P-(RfX&~8g+RwYEAWZmJQliLBES#l<{YeNsZnA0Xu?cyd}N*ry{ zGib1^^ehBsocobTkM&Ilk?g4Ei>Y$+mTBxh+$R8)c?y zg1=$yW+yX1f3F|%me1IC{)@h44e`v<7NLYF88$rlQh?Z)+!pf|U;Fckq^-vm7%9+< zjm~&CWi_Id2C;TGd`jljsi9)XO`PyA>0Y}=quGHNm%k$(mA>;~(u{OthI4bpOgf!K zR9NQtBv^~*Zq!)a=mSav;py1f3uA857vR=XyvqbuT4iF{nwhWIh5CU5DZPuEh@}OrPO-fW3Snw=9#O<9sapes&|mnwqsW>5Mu=o=1G+g219bCszLm@1QDA0W zv*iE{)9NajGRxSVO|(}jQ9 zsV;f0pt%$wAuG{*4y^ zJGE^2)5!-L@+o$hS0|&~5m&@Zu2&Ay4xMcV@A9KeVbDyEP_@KNrr#j*u_E4{YmYZI zuc@@i9RX93GLvgn7j?F<{Xk`YNDa^_qf~$L`Q~#wPI47&R)TD!vT}z1f<~5<`|Fx5 z?}c$$XUs#go493StBS>5z}$|@Rqf}5Y(g-_A3jlV8VL)-sn!ENGRwcFB7EUG5`tLs z4Uuc+QHL=nu6ne7?2%4)vR9ypSR|TuKQ~uYbX+dX>&)h_+RUc{PYya5ifBKE9(DffFrLY-rvc|m!xI=6qJUs*z z<@2I8Dha#znF>K7J$+~%mXt}H?Ea(q$x0s~1ei8PH0E)Y_06`~1hS@w#-`*+CQp7Z z)Y_6|%~AGbqk>e;H>`lXIW*u*{j~IfBN_SxFIiY-xy&8QuzIfWAx-}M)s|Jb8eW|{ zK)E=;y;?rEvjtj*r+bG`@wQNL8%GycN7{s$ z#C-35`23GXP730=y)GTAy*edX?n-#BB9*P*$*>-zQQ;57gmeG>c>K6%-=bf@{rR!n zblqDw_IwXvRtKXg{1@HMGJr z75Em8PDI9o$Ir=2>niQi$-4y|-Ch$3>dI$!NF}yie)Rr3XSV5T67ET$rLF0*!Tfhp z=kM7ZBd4!Tja{1%&w>MW-Rv1s-&|M!xR{2eILsgWH z%9K6%11;0g*RO0qaZp_EFT1*2eX6>sW~5pEhCD||Mg_G-7GtdSoSE#HSh{Oi12#&j zT?hWUDk(-q6G9^z20frZ^HMezce@WyqV)>r^5OL&N4WSC)Ud?aWHg#hPm)hkxiRud zPm;W)euLM=APXQj65P5&!u#h8pZXVoTf<(kH+coNGNg#2?di6A*N;K?SAX}BKD2)2 z3(eJjh5EKn`Mid}YQn6CcX@li12E0>WPev({0sSy}jJA}rfl?2P1qRZVltoG{n z$Nq>WRX3fGosy~ui=|Sbr~pmCUDc1Al6}a!%&+bZ(F35I$oO3p_21OrJyv`BlQ(=> z#)FBD6n+#-8yuNfiWiTFyVujsMM0b?lncDZo!8!0GKnG5LX$8wbFB8B0KTXEPXD8M zOk{_|%&|p%zx;zDQ0CAJuba`8$zJ2_H&Ae+qWP8H`gQ#AA2p+ZXH5pa!Q8!rN1qM^ zG&{;#asyO6+egZg9f5RP@5%Bcvm}^bqKC%!i}e4(oFw)HUHWBAGx6fRr9mw_54F8` zU@OWKE==&IbfOCQ1cw68m`?Asa4rC$JYXPqdUO7jWE$nlJcFTNP&<*I2pVp@bkE@t zUep)cWv#!o6VvMIW9Rtcv1$yc9O4@h$(w>!h13OZ^o zi}AuOlcC^Fjlw~d2J|yPISzc^USc5*`?@!D+$^T?IZE3}IQ-po6A4S*QbX?$B3*tJ zVI}AA^BYV_x2ztdlU%tV5KWTNdqLBys%190qadp)SIDsC-x}qvXXr@?%TnK9KvbH% z0K^#N1_+k(*4H?We`=9ajHKl^2_&&6Ak{k}q>31aXLnr^jKQAi%e0SZ=92S_9?Y_V zE`s2MoL6DZEjBObStQ_-bD*H{I2g-NwDc#spwd&r#IO1O*@zLMQODJm#4&YA|D!${?|!>RVB;S~ zw(^rsZjD6x6hGD5I0vsAxU5=>pooL*=-0E<)S#;X3@4Q*g-gKLVaB_Gsy!f^5 zvP-bDZ6ir{LhQTYHV{nJCQbDAqISR^^!scs!49Kj3w6=_?*!OHS?iX0F@P+>+Q3%X z8$Csk!qPnNV~vCiZa&DN=uv|NgbA``!vr;yF)*Ir$akb|IJ*= z5OLb@k}RXGmT!3o`WmuoQ)M~-6Fkrm3Es&6IO$PcY!wV@4PGXu zRQp{{NW5@-Ebh0OmP?4gWwMOTglXo$qfKc7%BB4U;;bY;2Kz*Qx<>RCpz97{HAa~6 zAoYeGzlo8)auuoJxt}qfQ^a->U3&}N6`-M$ z$dU`kB^(`x{041frms7LGf_)hdr?{-obdpz6zHFpRXkIVn8ZM8N2OFqFDpEq;ubT& z#BeO%9^VZgc?ZJVl;rsd$p65eWvZ)%@f$zUdgJHJgcd@XxzypxESV=dc|9Rmxg44j zsE0{al_7B))B)pohc6{8-dX#Wv8J`9GM^!&(78V{%kh=*U-V>ale3FGZChqO)jO)w zi|Ah~dD=ByZ~_N1@xQu)IIAVmab1T`%nDUOg%7E(yz4eU(3UqpK>UF9ieu!HG*w0i zi~TTbe=WpGUlyIYEMwgajfIyn-@ZHz6W4>K@mA(N!&nItTvH%@D&|aS{)WH4D;{H| zDll2hiinlpP>ylLdg8w(MqopuC3(vrovIq_%jSud-V7&@mv_+(BTb)&V8a%WctzDi zo6U7D+>RnGK4`KGd_I5`;VN{Ti1EWVVE-Sk&M`QXX#4s}CYacq*qPW)Cbn(ccAoHw zZQC{`&cwED+j{fApWb_`x~uwgch^39uk%~$D8}RWA<&x(pBTJijJKm`69`O&TuE{X zZvitL;om8FlOe~MQ;|zqQ+lgkCX(c4G~l+Rv2)vOg2^_`${Ht>W*ig!E^m(*wfvPG z-8|bJpBs;;%0~-W{CGG)R->Asn4Z8IQ-1KN$>V|9ARSL=$YcO)^lLY~aL;aQo#63` zDgIn>W2x9s4-Y3`jVzq}d?<49#K1tRhEEzQt**?^DYxoK3V8KsnG*yt^tIXn8^Gx7 zD4K}y52m$wNusss%2iV?8vz7hKxbok#mvU{re@i2AK);oOBHO#hYdpt7zZ@?-{1K? zc(zZdT9BpYzzYE0h4cPZ4JuY*RT})W>z$(S!M{9QuPnG_9g}eU0&$CcLu>wN zUVzX-Bu^!8>$>`3>?+M^zpSIwm`V5|=kMsks9+q>m)=15_%yzQl%Wf3DK!$uXg(eO z7$H!Gdo?YVxdxeU$Lnefl9tqnj;aq1LAh!so@f@DJz&&&U4mWgao^RpX64{zeYK+AA(yfMeyWJm>CK>))(Kmf z_jAD?^Q3?@ecH+;?SfE`#ioVln3?@t#nw%K$LXzEG0Y}nJMkVnb3X9|-1=WLcn8kx z>_1eChOnMdX9z2y8A2riP7o$c}M=wjzF`F7t)}yJ8s&2Aezya{@mX zf*=w6zPwuoRUScDJ0X;ab;HguG4HvjvS8 z(5rw=F-;{8122N$yUP;qE2619YjyNh9$iw8iEMCOX;91={dggw39TZ=dsJ@Y+x;}| zi6c;Ps#YycTcb{xoMFwWQEYVaYqP|a>9W*1kmVDK8e9YpN1l*JPf~;g>S+MI2Nb!`0%65cjv64aAivMDEYc{_{5$gm#F$4cu3Fng=be5Z@5%=a}4kuj$vH zAsYmLPDolW_5Pg64QGA9NCE_tuIp@O;A@9)+f#j`K3|n6s_7XLLlLGmjD1jj5N5_fR~t_t&v=Ied!)Wp3R8SytWP$bfGnr zD?FCs{Ml+uS3I6iu^vNq!xbFe@(-w0exZvm(cW83G@CD|ysz|N@K93`8el$@4RXXu zjJ$|!t;S>9IjBCl(1Vwg2<}mc0H18cvL9=Ht)gnQ(HOtF{j+tzoHdZh3>xsEm7XW~ zmE9Z$#&|G1o=r&jnRBmqqF*+srg|Xd=}1w<^$mn9zndL%J2qU+vwb0c*m*k1aN#|l z6ZiYHpk8)Ws`80ZPrtxMUI-3(9kZOgCw=nU96r=Wlj8A@N0u)+Ehoh*r9U?$zUS^| zuJ|sma5jA0x8#|zJ>!}=x`>-)b7#o89$j!=f~%%-PEBB)%f5jR=JH@_($;meW={%CpSlATghNh-h30D&J3Q5 zzT-hbLA2<)LVI(yQ^^1lt4&s({6%&df%1Sdt*NbyHlu z7%-5l-I#;EyE8DS7e+NH*6AD!PMHnEEogTETA*G zpL{!x{FCBlrmhvN2CYjXz7aU)yNsKSxGlI=v`L)ZET%axlpQIvk^%!?1N6oEpvTq#9Dfe#DxPCz=@VT< z8OfU--QUZ%ibTP%shNCivP5u7Dhk>rlqsqv3n=n1b}MfhrA6`8T8?}9BKw=I=yG>> z8O}4L#fnX#*N|sBaz>how8GX301@H&iKNflgKPTZIrX7Vz}*cHb3UjkA-o#K&;GYQ z2^B`AVf2=Tt@18s=Z0VDk2#M$8jjGPGGm%m1UnSOm&~JcZroOHdNC~$`TJk8_ntw5 z_om=ak!J`PG$CmU4UG}EzPO1rDiLV;#-NSNZZdT<3V0&*fUF=! zBgR>1QvKihJT=cYnJa4E+4d)&gvGe^X}LSEuhQnN6&})lK#0wb>_1^$V#((<5vKob$`L!mlhVnb3 zt|GvU-?jtxxLSYZ(cI))ZzG*-&jwBAZA* zyHPSzOom7xIdM#S@`cZXp}%3VpgT0 zQXjzfa(Lbu$f0GdTeUnu-QFM&hWk1zMBCBGKH`D6s|FymXHu*q5Ggv8Mile$8MtDu3=l^d4TLQU z@3b8zr}oiWu?MmkApE!ckNuCcGXp+@gsWC+yQJYC->`3>+b z*lBsr3g5DN{_$D5Blp}8K!>)H+8?K>`|T-aM}-Gz<)4?OF- z(QV-5V1$|h^RJPN=5TOU<7@ti1q(X}~zbUVMb8q~5jLDqGrA>n#bN01bE}C_>LA^Y~tmhu6`b6JRsM%I2ec zbdJ(+WJ>^IjBWO;;+(Cge*riiBxwbKxH>9_m#F5iHOtzK@riXz^sxF762k#MgiKv9EgRXwVmOpteKe>!n=V4kG)qcWY@T;Zkzqdw>ICN0Cx^F zx%Auk(jCx!9&4LhNQlj=>tu$=Y~C`adIUS?rC-oG53D8%`jIImn#5qxMEO7m&WzqUR)X<*sdqW&!3)*A%K``VW^k1A+Wm4qK;59 z`t&%iS7aKm*IS=XY!LA2AP`0vw$QwpUfV8}Pcjx-4=`N^^~wBzq0n zUqOK8%RE?u2cFV-^JwW5;u%z6E6=JpluC)V)zeJ4MU=3k< zdqi`VGtWU4SJCm_iI+Yd(2bN@rr@D#Du~+ql zG2RL3VgOvF*U{a0t}>pUs4Cvy(Xao{t&04ADP+c;<6H6HIbOWbARr9?Ssf{+@c>b( zT1r|fXrF8n97MRIoh;&7g-tye^u$o0eohU*BT*K|4b2e2xbS1E>g2 z8BY3Lq^VPHdP$<}UUKzSWr-F4<^i^CAe>+hea!m`F%>xJ#Oo*rWC)aLB-|^J$J|Sh zsnwHqlh^l)F|GL42mdN|Pz=1Gyb6$9ZVN%A2e|k*FKb$Rcz#aq&h`-x+)M9cL^)-w z`p_oMjtf&BE(6nk!m`L{m=4ZJn~6x7xcI+9_p@YLfmQePg!_4ouI4s*Oad4l%w4T? zT2h)G66pdp9B7;JSAdzAQMMEo#^Ass8g69C2VlA;hOn7K-$Lcu%D^s^4&h|%$CvR^mcFUC2Il5JvX zhPp`-fU$umMRf^YKhufR24Kz&Tf6~vg?7Vvlv7iEYkm(w!DUdyKRW({B-++0nk<1o ziEmWHRz}EU6)Z~RA6-MTv?_jo3LWRe3Ca`WFM|`xJumhTf}?^1P>OF0v`yQfA3P(8 zfu-!CY2=BSlh1ByS87tzo~M6kc8M|%WlDK#C?>dO%v0I|lf-2aA)wmuhxV321hjv3 ziL$0>M+LEeA&k(VZHl3oc>QN;b)2Ml%Ev$BGv(4D$hU}@S-RLaa z@fmNm)|JkoqsjpJr9_-!9fT6OahdoY2}E-^94>?g`cq!T@*o1e=wWDXZh#It!5%7l z&Mq^0&Ypib{dG}54M5pD$_^Y-Zc`DAHYr8@4{cGDjV)RY_1ZhznY;(6@!6OYOeUvm z(qoda`z{qVN#KaHw4oT-!joa{s4^+5wm*IITEn&O(C<`tZm@+v#E@3T@`f6+tBcL& z8Qz}{=bx#U!+R;4?&ZY+ZGIb{_5hmC1L%CI}zjH~OqyfrX20vTU2u79oJxw%! zqnh#Gm^5dNm+z3i02hc;nkwW@Oa;NzM}NL?CFo3{ExADwvuZe!?T68QAijyEu_kpw zYEN1b+7}JpqC)(;9t+UNprB3D6__Eu-6Aw!bx9~ zet`Nkc!8+dR*O88&^B!3b4Eemr!%-ma!Xqkaz*)BEq{ejHv`G~thq5a4JrkT1Y5 zKcD!5C^L7P85&WAQ3VcN+*_#HKAGeodR>S0M#+Mh@g|s{2hk+6Q!BS}?H@aH1M^+Z z$A$LW+tidE$l*0*h*au`K3fECB;2I~|Ih>v`%{}o&x9aOgawcB^rH>`^|>m0txkwR zt%JEQ6Z{ZNWYxq&30&~zD6>MC3lA95&d#}MP(sgvm1FA;srrsQt>OAX0 z8j_0?X6AmE?9o-1omZrXlz%;zi;De?Hxph#E^9H{A@SW(j8-O)Ooy*7(GMM~9oy)w89mVLkn;HSv0QSrNtV0v|Zc443Ik^htfgiWa*h zzgs*W1q6i`+2nZ00q7-FbLs7ho=va9GJt-DfGCFEgrN;QU*ysM)I;kc_2#_)p`V#^ z&XDCwIW-(}#@}-QJB_}v^?3zP12`pWr)CjOOxX9?&y$f~ zi^Fb>+T*dK5jtQSD?&2~?4f@@6^i0?BL4hhc;D5Mj4gy?DgbY*f|M8~bSg}{`k{zK zm>?Nj30I#B-c|rPGD;XDaaV{auHYw4C7{SO>_jH60v{hQkSx(K3sp$^$5Jx35l&Gp z;P_h~fUB3KNMG{#GYV$RHNXA=``^Fl>SqY(&`%JM#BVB$@;@u=_B1*mNiEC^^?UZL zilgz+fE&iDWefxPAsEl-)*6rYOKJU8p7xjJ+@OY(l~-6LdIkD6i-n+P;fc;_BT=WE z=TM{mOe-{Rp3K!7-&d?}mdD>pRl~gdyQ8PgjsBz(lZ z38vF);h%D&KX)_Xpyh4=lUjoAR#d zPU3u_D+WE4_D*&Hy?NQ1!iXi1vUI7U0?f2J)RO8J8M^iN+Ge906nDR<6~*pxSGLTh zPDLr^NELDzZxdbgxhbn3MQPB030zf*6t*Sx1A=neAyRSY%9R9gUNdIR-Wv{mnKQKG$G=V% zCcX18CHiQ~nX2?m>UUP`PcQUGS;x;9i>8a*sVx#Q-fa zRBR3b;Ng-O6lS-hv5hu`C%yxsFH9<)SQn+2>BGy~3&HGg!*oSl)%9H|t+kDvDqQ1q zsP-avX!a`H|8`HEz#B*nAlMEmq&TBmpld3nYK{H{14H=b`!BtmRI!}3YI}(028KDK zbNs$h(oVLWrC^(aO;n;+PD9#5nZEFZm_@4}FqQgt_ZtZR4r}@zk1fOJ6Cbc_ljx{{ zOld1S!_3FX8ikEKSA|=qM}=jk_Z_6s-D`*b9U|$+D~M`t+=EUUWRzQBC;jM9$OGF7n}z87*94NU<*PFlMSKe}707 z84>;+&7YIqS|%483#|3F*{BunTFKIYlEM3cDp@*D=nSJkZrqH}t+plvxr{;VPg!II zbHY?-Q_a20uAr@-uf)Szu7OVc;J@_@C#v07CtKj~a;@MrAqSdJ%%ASU352VeZkZ0> z)*~ve4UkO9&1y@kS^$(IcW}^JyCmPS3LCzN>$_=s^!HxsBh~q2-nLI4k);j*g0tf@ z0OQA~#UEJwoolGoS}T@mM$5M3eXmXNNH<9>Wk-WgtePZHwwTnoG%d|K1f zRTg@p4WDC*5zzd01v%vCcw7&BNDk>IP-J2Oen z>mdBm&2%S(BM|0hbh@G>JG5jSCTg`j*&PAmJPr^t&`i5vlN9l4b;Q1D940JNMn&qP zsy8e#3nq=@1q+*6MpsQ?olTFMypNlmXsO3Miz^vt7ZdP;wHupj=2tcV6t4{We3w7& z-2;z&y_;@{$lb1C=P|n)JRzxjZkWk4tx+8-fA~RLj38X)o!#Q+ZQDnA|Fy+bd(rF0 z_@wswX7+<}eSr|+{)1SL!8~47B6bALS2F}35+*&e&z$^I$>AHX?qE1SL%_Sja$99` zqK!9kftD*wAVTXAs1z^@*kMXPoDtyGqM|*V;Y=xAR}~iS&hYKRhXf#2Qs7w+Nd6j| z!TZ$&P}a`$DuE^S6D@5RtexZn)XQx*L=ee?@gLdJlG)^LO&!(PfE)4A zmPdmkqg3g8{P0iiahY!cKa5{OmY%HY^aHvF+`7n?A8W~}tM_Q!`Xo!fDufRh?f34f z%V;bEDZ;)IDWWf`Y5(tvrtRR0VkVBR3VO~BU99}oiPj{LY>B#Y_?bIrBl<(TgI&v3 z1~>arxN%}(sGCD=sF3LEwo1-3K1DHB3SeZ%g1bH?Hh~3&69R1cRChkugg* zXbE{rC;9sb+8dv->Gw(g_};pBEGo6O8w=NXY!JQvC9_sk)Wf3 z>2mA%L(^Bz)iJqnl4^xE8QTUv3EWWIV490~zI57#kk}CL&)4!S0!k9tVr_MvK zy^DRiZpgmkge#jYB%u0S--0cF6v~<4chz2PxFuG*pmZs$=o|q|Mz^a9L4(?ZjoyMp zUylv&+ntjn4E-jN$|1gskANM{o{9vV?;rEmjSDXXF`qlg$z}+`=OMrEa|r;1 zT%DGt{9b1bd&e0%v^g4IJmLu(n1w{#KFO7T<2KFTTWP#fll~Dr-a;mln#g07_=}?< z%BI>1@+KgQ=4KuRrH@11NInFrE)sseAtjzpQ!rVjke&Y~s!H~AW&tj*ex!cs`@Sey92l5F~}hOEl?f7B-C090kqV9ed|)POa}U? zj$wu9dFZk8L52Tdi<%^65*2^JW6D5SSe=t%_e~pNm<$U0M zBDmy8h@+CvCX#7nIz49lygY82U8V7VeO@4fTon-QpzvYbgat*2-yK8;sjMf}0=+Wd z6LT)5hQCM391`wGfQvPp5vrE=iy@MpA?r2s1dWiX6GfJQ;7ax=Qpo^u4%@>}|V{da`af$)m5 zBs!}?rFochZ@o;Bxm}v546BVylWLTu%8bGyXeWb8J_BX8Nhoaf5VtXV{_^Z@L+6 zj#!%q`3LLMIKz{rM?9Nm^<=y)F^NUpvNUKv9wN??ahVYHinQp);_on*qU6Zz{4z(@ z!0;X><-(Fvz)Z7ZS%p4?I{ zZb(JGiHdZK!@Q}Aq#%sq{4Dg#4@Cjwhc72640ipL83fG^FC8uwOfkq6b$f4)y!s;p zjg4WA?SgxI;01)$xfu;L^sioSJ46Zoz)5?QbQ3R{aO^BUb$uIU8t<^ooaTw*xmBfD zoigSG^goZdCq1E`fn%_qdl%C8lN2tnDy5Kop$g0KGZenoUCdZ{wXWun${={!wC=^< zB1JkkyQ?<1k3~5)6rWUp>7ELqq1?tjGD35LdS8F$(&V@XkPU&Vos;yeuOTTrH zy0#&t)1+{?oEI0xZtNS&Cr%k)C0F;naZCsxe&pW!2uR%d+(+Z{M;q)5wby-V?iE7; zdbNxlS^XK}oD(AdpJx#uk3%k(RgIEUK2*)gAE)Q-qcn#b9C>SAR`( zKqT|*3cX^~H$b9JBpeYsLoa*Wr`~7Gnhy~<7orb#)pm2Rc5`szbo+z-%%i?p_(sQW z$=@kC%qegZ%)xe-gdNZ_IJ-|RL6IFuRzGYb30wCJE6wqfm%E@@aqLbiqbqp<&Gzrx zX!n0l>&GPUw+S{5%7CS$fY1Pj*4m;sXPn}=G+`#@Q>(V$t=FL5l#CKm=(GVE>-*X3 zZyTt$pEs|N+i(*oFw0B^Ya$yWfjyi@0VTWvuXzADf-+16WX}&}2V~b6Ab7A8rzyBf z4yyFb%0; z_otlth*T;0Qrm+x66WS*-P%ZvDeiB@aO9GFX)lZRjJX>55)Vb_;6+{I%01O>H*2qB z%VnU63PDDK!MS%aYRKol6WwFNqejiG!mu76u%-up#=-G)vL2kX=l;%JN(<K`u) zhqrQ=b6w*5A98{MTpSJ?6a>WVo86&Gn2E(p;F(2C;BZ0%)W}eYE1-eFKyS93v|CHC z*KZ_#vLSwg01{he^1u@WF_W`A8m_*NEIN8R`_;ociRX-$iIPdG1X~TCw*^~b-TR(M zwbPANy~1%I0PTe*=V1s|1B1*JGZqBENh@m$WDfWxk(WBcO0m8GjVP&Z+^9^91?hn6 z{)m$8Wl$Uppl8V_T$fWk>1O0TN>E_SU}S|ZT5W4M!z*O#s?Hh=K@(Y1LpKalG(Ya~ zqPT~2=(gmk%u-A|;M$R6YI?;aYn$pG`V5J{l!|Vr@WpnIi!kUul~=9c>m|nfYKbiuREtd4+R@5Rv7EHx~bJD5O zt)byhXY|_x><0r-_Ry81nshnd*JjT`^HRSbOfHJIb)xXZjYaj7N75LOIsiv zepiOe{t(!914w;>+|7H2+!ziL>UI%3j<{FblDKMlfN%o|QMzaz7VN80%74=e51JUs zbd^>L9hiGdNC`=l;f6zKLK1LG!7XIKdN?gnkpSyt>kXP@GG|#`CA-p<@Ty-c8WZ?Q z(|i?};pIAYEYMzOZbRitLbMq54b4TEumwZMd8Mj(_4()*ZEIv)Hn&+g?DLLkV$Ceo zQANRK0G^s8r{v4nxY(b4QlTdU+9ncBoC$=q@p`>X)I|^*y2%Xd!&8kgD*;7^@U$7s z_vfu`_4ycg37!fW4gnnAMjlnh7Mu%dh1+XGhEPhe!tfqjU5y_nggacokbu&&G5G*DUIVN{835R-;t%Vds?9|- zyRsCx2{+*xiQGkXNJ(k-K|v zS$Jq=2q=fZ{2CFClH?R@kzU#Jcn76k0PVR-tr*-7!-M94CkL@XC>Xwfi2*V8YJzG; zjK6=ldk_5x<%JkQrTTpd3fAz-Yt?TpR2_~0jHO+ z!#qn#n@>#S0Ts#|F1%G6hV%9_FY|7?N%7|8ToADZ=@dnm%GZ@hxB7F3<{R}2Yn60$ zPjFT0NGPTlgbZgQRxJ{3a=i5ejm zLmH5lgamarJ8}TZ0Y(k$@8m(ZfQ}EAFQ!RP%q0ZF*gK+0U$I|(?_J5hU{oJyc@c8c zk3VnHW_Yp8WeZ8C!&8)^Av_dIF zbBE;!Q+Un<+U$427VJ9%7s2Itrcf=iu|zVvfsb>{16i1i(!R#QDGXp7fJIqc;=BGv zbl(bUv5vP+=`%`&@|ICY@=0r?d3+A2dRdf#T|NqPbmPEZxiCzFO=|Yz5FUYg0)nz; z!sPhwPvM+nKb&Q`<#`v3@YPnTq@ya-Po7%w-TFF46@oa&(H)9;JF#z?{t)Tq61AK8 zWUg)eL6K#FSXqWMUfx-P1MHIy>cnza20A@bajD-=N|@H1AyQ)B_(aOUS{RU_WaQ{a z7`ak-nw#R2Xu!54X+XlFnn-YI#Ovz1&^vJnS2r2M|J^A-JD|!W_m6ci*Ct-#M9n{6 z^F@^Cd-9D@FSdFzx~DaUgoq2#ZN*mw4f=^nDjN!()1Yf~A zqeh>SzII#!`7i0c)d-W6;5aw(uk#^-@5w#NVO-~{q%rT%4U|4WIK2sWnsacJJ$ltL z>1sIUCLGlF3ADDy*#}14C9xeG_MM-RQT)efZyi&-k?Nrwayfs@Z~5Z*2GM zriJ&=Z)I?l`(BDC%{HPY$7C`^=-It+_6JLP&0kow?YVpxA!f9LNg;j`3|4u+2Bql^ zu%$Oq)CTJ13R~!wXwu|Z#^bjXzSS;e!`8(=W=C*p+Hozu|4*O6q-PRS{7tnUf8Uhf z%Oh#RwkI|~Xi6RpT%;HEpKB?t1(?KxJspo<2#S(+yFK3>KY{7y*@rvWFjB}*A>p87 zYun~+o2t~>VVN~aolC0;3Jbh77m};^ZVfV-* z3HeW`n`XmAl5;d3(Mg=3gihFA(M~=|;g`6?Dd!JbZ?j{FEwD&$NGz|M*Qj^+2ii36 z|Bo2>KVV=Pfoq-T2MEY0^!Gf5o?st_k}&Q?447=Lt)-Pm`n`!v?XSCxA>2c(DNm=U zDV_xWMQc(8Ym#D(d4ui^vh@QM{&(0-PFT#Y5Z2K-1`S4gaP0HZcxD>sR$5wC8t?bS z{{czpZvtHvn_&?qWgbWqXFVKZu#U<|yvw%~DS^aDx9cAY4b3Ml8G9}M&j^_cD0nb03DXdEA0GC3FPYLs&pq>)j#G^hfN zucyx1EoCv26eY+i6x0ZWD0bvCyWaK20H}&ec+f%-c}Fw@jrHG0I35!hW3S?EwuL8R z7<8V?*-_e|wUr)2aGIs1>x!#NL9X-G^pO+rgllYvRrD3mn=L=?D~p(~)K@OHxLL;& zXEXR2+zIk^c)3IW^k1TRd5pyt-1ntd;dJ+FXan94WQdC zBVbNNXFM9>$!5H7H3>9WUx>qeEw(*BrAYkqWbvE7dWXx+I_}#=84#?r9autT=(3oo z#5^yPq;;tZq}Kq(IW?*9GIFvPyP_-c;?G%x=QTV*C;jz8U!VaS3O$t`Ia*MpV!zgyf{k&Fu^!%-O$^m3bZZ}W4l z%w&FGyAsqXsMc-NJHp~=qV7oc@HqXbnHQM~2*-aNYnk!#g8=i+MLzQHIr=qmCc8Q@ zvne!B5bYg+6fOL;^YX_FRHw1o5idjJM@C@G1c`V(;mI(5iUWErXSy`05ujC|g|qZ( z2AqCI`I#hW>RPlrSD?p@#nh00+5yCYRWQAnVNL9A6SPpp)(vFKl2noya4x@6@3t=q z1!WvzZiek#MjT$!6ag&_a3=n2VLW}PBHBb1 zcg=gW6R4uYd9Pt8zEKx^v1Njl6X}-oo0(K?{dcd^Y;CjFR&$4$_Zrcd{z#R5$vCgp zX&&Rr)iMq|@Vqmn>wwo|Z>>7^v>Yk9W%pXNpLl@>Cqdtjo|bK7`Y8OT-~cPozj!@T zGJ$WQcENw0NYxwJ#=7mxHWe_4ZdLuPBy(5;m&~2e;YS6SFjK`y6M@utX^#`3XF-RB zi>SMYztL>H5)PUBb;3qww65$x9U-!An#!qw$RwR({Dyrfw~6N*xaXE+kbfckH%pCZ zGG<4pME4639@S<5Ak#uix1q0F#kYLNt9v+Ey>LJxFY4cwYBBsskjN{dh={ggW_&_& zfouU2g`EY!`!f?oFMgg-o}07zAwE5NbZn3@y^P^#{L8kTBu42Ep#)9A5erc87%Xa5 zO2XT^PBAv+S|lj15er6R5a30R`GZB*E6whIo`(aiMF_Y7X%~r zB=H920}?xuwKj@4{qC_d3;GA(S!lU)oMj9Qe{{_(cv2Gi|NKZXrWe!_K#$ zgxMsrmD;cy$fzagm^GArAHf;)3Clf)pgGvQ#WhF&LGXc`mHqdZ5Q9H_H1mg}-lWeZ z=akRmdc#xAcWs9MgY(T#{F`O8WMb-5-yI%_t)(G}kOI{nM30vHXB=##(gWa2BHH^s z)I_9x)Jn8R&X>R#=@Q)$iNwYMgWG})d2w|w>KtuAY^S-Pyr9@(rCF{xr(|W?S&g&i zu`z91p(@ni7^J%hztJ^r@3Z>rle~}7&TZR~IRkDsy{(Ed6A2h)+F7aLHt!fklh>i4 zV3ko`6yY&O3Ed92qjHgFVF6fjt}wvNI7pU*JSa9WU(}SbVPOfN^@xvrbQY$7SANXp z{dd9#+h1#eX0uQaD`&mI!qKIVn$)3D zlI48In}I5$$#Mrb{RxE zDk^CZeX6jymLXT}rD8q%JraM?d$+kG*;L`uI;4wymD57mkKYY>1?c%Av)!fCMb3j# zN!>J{!9qL867_u+ZYt?sf@1kA;KctRN%INoUFU8H^_gRS*&i~Gk7;EM`okI-)D@o~ z&L(m3XN5nG)fyYx6`IpEcr&5`;X@=vJ);XqC5>vsm=4H`Lj<)Z0)pfDWbR8CVkjb! zYP7qwf>nvnJBiUYmn`Pm_aA04Fk;Rk^fStxGMhDSACrkja9nxEz(&VJa0q?;ws4Ej z?k^cZDe_fBnL41^z5gw%5VMW+&&dORmoamIwlBEsOZ#>Q^g&PR7VzKopt~6sx}5i0 zbXois%|-vyS<)?#0g9B?Z0G(U@t$d~Lxunw;pLSzC3D*p*nI>j6~KiB!_hz$%e(C2 zqgF=isMpG#(LagkJJ7q|4RRQ>oo@ia*Y8ar*y?yYZAP3<>C%=@38EFg>m5ais0La8nvIXla? z0UPjBRZ66+5tKFny@d#SuGhJEQhGIj`u8PwXyO8dh_--@6vR?sEAH3#9R4g;`ZOs$ zOXlC`eLt4*boqDfZNqEJXXNV3`wq`fG!jxC!UPh24eTe$Zz2po#NSHz`$UsM?1(ss zYiVCZ(9ryzq{pB%03fnoq;59vd58u$EE_Y~kJ3K`^lxP6KlSTHyzCR-*) zrRb5#A8R7D9untQ!#QAz425b4k|wQ7QdR&yC|Hof>jsClgz!`UsR}P$4_Uy%Bts7KlY}x>U_uew& zW4MLbJZOeAEQ_-2+F)g?WsOoL#ic8PP<$seAW4DBUQv}$jv6(Un~r|XdO_Jb zkhx;G_OFUlpc>Gz26c6wiDZR|_{twQG_ltcdMMpvsy(_ z)>9J}K(2x)YVxQ$5S?jthDhGWAV)E+(Uq{=b4TygW{KRKe_wYYFWj+$7>!w(y6~6l zuqwWyP&mG%i8tOxj1hLX!I~?pWOirN$N6S%bdp0VmPbG)+YP=maiTy&E9WxTs<3 zDsC~*_0@+UUBq zp~bC0@dk(B?rz21-QC?KE$$ZFonpmZTHL+3yIYGx>7TdX{qJ{qvsTucwew`p$(fxq zXSO`sgx;QNNspBS+9lScY01|ej;?}rBO7@}L|&hAC-7vUgHh4nJn*vRoOrBAMZ=8_ zM@W9ic9? z@Tp`3cR1`e`d7>_WyaV%9Y8<9wsz>7`8bVA*ev{~Y|z2j;x9kTfv%@4d|yN1^|e6V zSwR^z5Cwm9!CNgaI2TQ)k_+9j+2hyt?Yg?Q_Q@y(%_U@WA%ohxw+@Pc9#;ti-NI zo?CK*#hQH`H~cjFGa(6V@*aAa$+Bcf!ao?%4-xG2awq%T_OzjeUCawW-tLXDZ*X{gy*(;|ZE@qCt($Cqh z2(J#d7WKy$`%?Q2f*6H-C|_5I$ax{h+a7XE`Dw9SteVd$*!3@It` zd?tHwy0iga->Qt*=jH92;^LT)J5Xg?BKGoS!3c;%oX;Tey<4#8h*Yo(q~3qPVG;!% zC31t{wvIEFRSd1W5&Fucm6vz4^bdX(gJlNv)pB~$-MwMSb{wjO&FpTFJ`M;de7-z2 zSUpJk^*c5MUg;oDNlKjklMaj%gMaGN{hvhWRXKp?3~qnGSm}krr6KEEuU_2yf6+km z$Zp*gL3UbqkQ*UC#E%F55ibqG#-|RClMAeaH$zDv&5M`_!=uVDV(!+&ogd3M$8kiS zz8~OvwDu#7i0#7-fD%f&T5TFbO+iTkp7AsvJWrS||Mh?=^_0iL{NzofrjX81K9(n> z87r?ZNZj8}i`&5o+CTM5A>Y2k9@k;p3FYR^px{ zF4)z#*z5L3&RRJsSLpPhJeS0ZXi$%oQ_^1$iSewwBWdnNui)kwv6RC9ddAr#_Ymp0 zZ3KMazWqbqe628_ou}?5!ks&C_b#Q zaV22T(E0^;K|tDp4%8|iN}cMSyiuEq5)^wVZ08~3_W5?31E^DVTam+zi-sv+s4IX=d2->}q^m`ij^|$PP9Yn#uIGwAo{-6 zks$}J@rSQHpbFGK?F5bMk7h4D_3kKs#0Ham{md-;BwySbC#yI z*BVioNdlfHa(+o-q%SV`qM{ZbNS553*$0C=D6xPxT6ziFaS4S9`;k)cQ=I6Syu4I0 zNor(jwB`O7517yOj9BQKKYUGiJ0b;3nTVu3xNI zt*ekd_5~zGyaGLT^Im^xf{2sTmI=qe-2{sZ)B@y-d#g;He*37lR`cPV;p_Z^;=ov} z8D0fb=|N_Nqn6Lk*rU7-CgT0&u^g3b^dYp4{5SHo=7^Kk4Ync~#%@Ylkof}Z7xkpz}r(QpRTI&V{GS37X!LH`L&Lc3Lr0zbR63n!k z0IAZw8C43TkXx%@pl@ggD`|n*?7)~{T6Y%-$YkuC{E_7g?3_xDd48>QkrtXM)~Hgf z%}@?Juc8XMXcjIr5p#7SlQN6xK3meAeiz=Z&YrKAiGB_q<2L3VKBFnw=2EW`ygI8O zsf?PK*^*}8I+-h!yQUATSoYussr#oshfN#ewu}rjBiHcy2ck6<&1S4a38zL?a6eBS zGaL=o(UXft#FRFUlX!w*`Wp+x1QK0}^%Jv%*gyYz68SM80|HN{SiQ;c2J@vdfUvGa zMF`lC9{UU5)wAwnNu_BHHIbMq4|>qS(c-OD(k8Lr41s)ns1y&RNVn(EQIADNCKLT0$>cP|E7; zGaZIm`6ns*O!}Qqbk;a-8B{B@L3-qNy)}2@X$zqz=?>?t@O!`o9X_OMS`e(rW|<`U z4_0ShhSniw{4*zL!@PRVmP>+i0G?#11-^%V#Uo?$iH{NakXqMxOTDMjykDnkVTySr zTV6;Uy{s~>eMD!j<&Zx7_>}IR`^sfzfkQHg^2c>+@o$=2A2$ZhaGf$_ zIQ)N))WguD6rNo%M7baxg0|UT)NcKXGdrKYAK4t38MFyQ{7gT-n2*isR^~cPL3O^R z?CTqvb_n+%sB&wKPZJbBB}ZgInXQ+kUgC<5&q9L2>z5C=m10237DCq!oZm}--#1Cp zX>NJ{CrLazbMuTYC^qWVavWj0$+ZJpcZUvWaf!XI696 z+g}ov7-k=OTBbIW#bQ?OYY*3qaR(#TMU&iuf6XVl@k`-jdcVc$o^qzG^~Fw+ZP#$H zF=*>{ct~r_IU8Y(b#890?uIwIGd3JUVKLH)D&0g_ zkKWa;dh(c`)Cc7~Rf_1#nqH{TwPUlhUQpXwFk2;y+Dn*xjLwy?XMb^nEKS!AU=h(Z zO=MmyWXtMNof*qOzwL}ak`eX6ogfu&1T1MxEl<`;>C?k_ni^tiNv0{#1{-X~VsQ)V zevtkgw3KA#|L5~NtOE&{`+J0z22T2-mT*NHMq{4-f^l4WS9AIR(ZlHerEmRF3)R{9F7FZ!^ST`pXhv$+I*vdu2$T8zRb2Zp%*R9!m;1vE{O4tVBQCd+rTs-f6`Gr_9CHv*Gr*cj9LGX ze<7X5ftjKrV9f$g&zaxXy}8vK{^CBxHcBBNru_rI(?!EF(aXU&#wZJ4= zIpaIAOphvTAuFwzPYe1h<*l*mH<|M1bK+6W{0L_xAOgiVtf+iGN5KrKAniT*V-TAj zwa5F6*ypC|ZH%{g>v~d_j)K@c$a}xCn6Zub@qglWv!Gn+jHC7XnH$G$&h=2vd19AW zJ++IB2keFC$9brwVWSgj8XpdsNTm((!WpCga?$R8PZ*_Tg2!k0*#C8B{!DmKmHwn9 z0ufGQ-udl&+8mZ7Ch_d_ZQ}sf0+5SvA+r7E(zeMzL?|`4KbR!=sTjvl)r4q&}{_SoSJOdG1sE zqCND4B-RsYxEcrfLW|4f)M(xdhp{FFZGJy(0Y0Vl%v9IM_UDgv6_S$j~Qz2FF* z7V9_iba}#p3p!wc=o-JMPVny}%LahxQ|Q%B%xAU_zEoL{9~nwyhk)>lwOKJM#>`jTZcJ8ki6sp_MBlYKBoLQ|Yl6(OW!&QeQ zl>KLChqed+WvfjpzK1jdweVO8DGrHL!e$`Tu%fBMLKl?@FN%-`OUN-(_x{(rvw zN~gpg*)vj13V-HV@qm{i)V4Y=jlrj$$zf+DJtqci$U6s45h|@4)h9^p-dY z5Nl~CQ(8Xf9X}KfL0LN6k$PBHz@o0!zKM$!Cm|CulA7aJgj3fH&Zk)QS$mhEz=rQTvt57+vLp_s zB!e$x?qt4Un*qeZU%8Wexa&~TD?0G!UtBE$K(h1JIK7MRkd59s=si2`*XxXFk!KaF zmXgPQqlBCcc~_Q??`B~ZVkm9X=))*tP%vF_H;JXT@bWpzvR8#euhrl`eZUJMVzg1@ zx)(tC`Bt~s6>ncxYo9M|VE?&#zC4{TM8F}3w0otMttyAixJjtnub(lV8iRMKi=JN^ z1VXxm3H8S0aWD>jm-pR1=>a{(n-|zHL$gd-)TrA+2wv?WoZ(K;9e_E<>;(L5k<3V6 zBHM0dyy949kt#WmF*F*V^^E;|Yp9TWjx}oKTb^l_O>xl_tH04^2k$h@{uw^4#Q*I( zQ$M0O6P}<<3aTNYa54$$Op1sxs5K1?N+LPGf8{(zXv;srL(H@t5~*PQd#m(b!~kO# z;Jo?qP|r{R2QB12HNV0sC`7LI2l5bo*MrP)x&GjD^?{9rVND4G=O;|X3$M*-a|X_B zS1(*t$ea@vf^TOES-=#qXi1pokO$G47nu3OG7;=>^NH7fKPN>T{sS_Ez^cI9Rle{ z7^0NUTl?$hD|cC4{^#Snzb~3Epmv>gMNoE-c$ud~DzcctJ-hwgNrBd5ADuZOZBbm7 zc5;aN0b-zM4A0TFcHkS71V#1ob6_w!&-s*F-wwSFKPC; z#fckf%)VyB7Mg(yEk?zJbK&62Xn3Fza{D`Gpb>hmmX75kaSz&~R%kpHYQDNk!_eIi z%AXig1^(={zZ>YL8RfbRP2uAkY6XHDPKkOz%lAaPguL#12gHZg+^a8vYxJo4x1bHO>^$J zZm4wR_`0UJp-l443wNVdxGv!lwQkqlV(@n%Kd15xCEtYTsF$cTyo*m32`+uui1w+V zAIsua#L6x|Nejue78U!Js@oDV)isW#m>A*pJ`|B0MWu135DG!9@Tkne6AP)1m#Jg- zCJRG0-fy!_rJi`B)CVr2gIRJJq7;7iVnvwZ*l0bQPHeNQdq?nNn%G%53sgS;E19H2 z&rv%A5}~Q4{)hT(I-VTFXliHd>YA8G*NPtFGrf8+X}`zt=A03|( z59zlsS($c21m`-OmJ5xtbFZ-z$Ml2;E)kfWO@7 z!LS)gRx0JDAz1~51~{}Mtnwr7mHD_uqLM+&WndZka<|G-;j$EO=(2pxB8@Y8B$9Fk z?Mfn9Hy(8b)%xO$AA81ySw!*X8T6X7KJL4bpDNXSs*#33HaA@oU^ce~nr_tlcsA`( zbn5zLvlJjC&}6VQ_rl~#;Of3aG7fE>4~!18`(X~YLmTq8saFRx zyg`UAk?M=ALe9Ku!Nwh1U4+!rkXJ=$QO|TTwpA}gr$<=Hfq%jNnooDGpuub=yHX-^ zi{MC+QrZMLS^l)g9upL*5sqt?r!alcep}tpcfS(E4}y zmzV6r-B)xQiu37=`?Ka+fGe+2@gXog0079ri-J1Nt;oM%%?Vi?+W2{Jx-I@*91>x!>Ba73JXiGE?$H!)!#EeupT zoCu!**+i|Y`Y~C}+n!#iwu4hT=m(%bi z#}hG-bG?Awbi_+?z7%z>&L$0=Wm4x!L3YYaE>+|8nQgO)E>?b?lUPG9iX(?9=}nH_ zHPA;iiT{u35BDs2bN@~oAa|$TpqKCHpiIpYFWat?sKMYN-MBM`n3fIylyR}jfoOMK z9ZETHK$b?Zbq7UvtH=_zRNl&LxP`wI>l-%c$jpI_Sza#Cigq?hO#eq}ys&FH4wx&0 zf5ns*ktZK>UR2_I@wP@#vnaKG+${7umSc=k$6?@v)3lDv7RV{Ea+tm}JhPE0gV$`; zQuIyc92H!Wt;T*3GmlhDmM(o2I%Kt%loa!RH)XJm!HOKY*0yf=6gXfzV1iQ0WhV~e zmOH`I-6S?tmqwSOLY`v+P?6=th*fC>qLf-xS7rfb4m%s@odZ@+EzpC~6RZ!<%tQIq z#h;lAw6%E22~HYJ%E(+al65*+Dn`-7ZHh_6s!;P=W`5K!98=lpnS?%heVL4;Fgfm= z#*eCFY3MW1(3|cGmJ!xO)&Bf!a#|1i%%|IzUS>YCYe^%&=V$B_RA`y&EnH(%39mof zY!)ptNUFPK5xN53o$PzmM~tZ{c#&fjj^9*A9|Y282Q=}XhPM|tAZtB@zt9e)OEuN{ zzYC#Wt>@Y~Qi>J`$`98)O6lELUzjU4Vf9@Vu{|Sn*GqkzvIIp)!hWq(3atV;H%r+o z%zRPQn?6$cF&>LXN5rJvW|ffFU}u6(eNf7K@V!8J!aVZVk71`+TP78<6grI0$!4xy z$3C_VO!M7D()kx-&WScjfVa)tIB&VOfp2qF>zOt=MQ08%EHkf&hzf@t#27JWKp2KN zSc<`IJ7zUH?ABaGV!YnrTE`+F^s3CulkMe0nsWzvACv(0JFB{d_?lBT3Nq!M;YD`!BpvWu@wx7cEY6UuDD|cTL0?6MlyR;seAOlSjipnA>je zNk^)4V2A24YEl;{;=2^irbJx+tyc(jPv2 zcb2vvI@m)#ZO}7Pp&a(Cf73x}p^Z{wbVc!0H2oCv^W6T}xt-K=D4T{4yokSK>ked# z-{XFF>7MB^jF-01@fDEsmXv)aDFie4dD>>Z z{A6)9Kjqaio?!TZG_~9Wh$LBOP2^O@y3P1@EcsD8a_jr41J9NPzMpMR~DK=<97XOb=T?= zUj&ZnHs4%dYES>Ib;wSmQ52@kx;|on_P+V5HS%CJCXer!SCl)6@gJjZxRDRFh89W5 z?e6)oPh&40?lCcxDhuTWtf?;!?QLHSS1m(#Oc7MJ$V6tjtAC#fPTymn9V&N^$J{jz zf_XI6=69FDAO&UXbmJZm-1jdjwqH)(;XDlYCV|h08FA#d4fyw8szb=K=b_z2ZfA;s z*gHVaS+@@#PhBu8-I2$s1o)U9)FW~$zQzU2cKxn>(Kjb9%`He1Cd=sROKC07*|4Wv zOpPwD<`a-#RPow5=_()y`g|nDM17agc4#;tsLJyE$W+k&FZ#MCfBQBiq72)+nbg1Vd6DA&SXzNT2lPfPrvH} z<=<~!>4LI}KRjpg9_>8qG5e@b$bCjM68J?G0$!!{Wnc2s-|FIS%-GtO4>$&!H$KKrZ%m<+tIgbXD{%|4Hd3``7+c+tV+3?x#mO5!D(+y(2#pde={xtDF*6 zvl6*D#4;Ya;8}`iBg0HIEFVjX(DULx=)lj;bzOo2 z+zdfgmo`lK`$-_zA>jafw}`j+I1=ne|Fw^y`xI9=KK$NvUUiKXI@`MfBbfSStdr9e z=+@NHZjme}bgFpPL-MPLAnvkt;_G)NXo!p;s&2i^Jm4Xn7Du?Zdq7xSI97k82C|Jv zmp4+bqM8E!%F^$6s0{67})fy3JeBsGAfkp)L4FSUgvtO6X3~MSRG|n*ei< zDWT{Pp6fd~%F$f@>3K9E`H`;+b}|go-tIRDBh+6yYE00RBU@b1)ou981kq7Y3LZ&7 zNI{>ITGe2=%JwpF4D}t9zq)9j8PgZ4`>A?hFPtoq-4sa)Fw~Xowdvt=->yQD!DzroX?g#L7^;-tn)&g3Cic3LM z#eQn^LyxNsQA&q#;r9$>!A^7P!Jz2(&V1slTV&fd{PIjIWPP&Z9AD4WT3CW9$CDZ6 zBu_eWcnuS(hkVm0wRa(H*{fyd=F52S2CR7&J+k8-o_yw*Q;>AZ37NYqk10}q&;*we z^c}q&T(86%AAY#zJWPf1XHC6t3^ye-tx0EDA4s#eL`m-A!>?`~drL*j%Leiezds;d zOxZ#>>PQP!88~2OSe1)3=I?D(Pct1HGnJJxK2V5WT*Nop2Yr~FVJnm3p_854)Zn||hSn^$ zW1I{?*eLXiDcy*@*x@NT$fWN6RW!O+=6V@8UK`Pdayc32!;QYTvlNONkTKRcx@|0K z%4Pg4{`|={lV;jLRXUp%dBR{|gKf`skEbJ$xDFxkCsx2mRDLZG+1;jkPi<<7fNZCF zdRYNaOkv@HP|?k^WMH}Lykg7#5O+q(m1;`y*MJ!LTcK~;QUXpB2+Me5XXER0$xJxFzXr#@NpVwQfWc*J(%F-=wzSl0`Eg?f%r${6-G$LH8WmE0% zaP;&|A`l5tO+5#Kgn#i)Y#!J#G+OmlpIKFwaH`ui8}xpgY9cw1o;oP~X*i7Rd+YkB z(cP~j^FYZkMRVXz<_34Ta_#8kmiM9wvjm;9^~vs?Kw+hz&XS(HTVv^j?ryd#-cvFz)u{HvrKuts`)`a?d%s*^K7ZRjJLiAyAHLF#!h0iXL2@n_M`@{LzS=}kGt8+FSI0b~Do)JAhsC-!N z+|4#QXiOb<07(-p$Cc#&w!&O?H1<=M-^GHtbiBXYU8qedjEw$SbCAH|e>)R>QSk0h zK1||+khaTCy6XVv(fQb)J)b(cZL^H$jUzhA?9R7Y%!IyhwW&_0gr63EQQ%;O#u;sZ zYlxaxK22XdtCV;XTK+N3z5aICXzW0nZx>gk^>#4I8^a*dIoegPo29!pZih0dHg^Zw z<<_<1N5u|nY^tk2&LACkK;%yH>g0hJ_Fx5%!OnPhBcPi6_YFWuzAfgS+~DWIi_q&B zm9CdVS`wtU`yj;40|e*x{C^iuvgQ)#1Ek@b#LCdj$6EEl*fpT~EO&}IPbkHdS6S2! zP#&;C<1Fo@gY@2(OflXvX?iF^S4K8}Dx|m=HY3HKE$VX-J0eghh3o!m;)7$yr6zh8 z9~*(}da*8v}=P&IweT8Jb z3VHo&Wx(3tQE9#IIxl|m9c}zv**t8CH!D|qn7I%hph>E$H(lt1QLJ5Qo3%`oQ?aRL zemtKY@SOd`I}BrYu&)BttvY}T0UQz4TXk9i`cQsi11HWM3BvEX()%*KWDosh`MVg1 z9Ea~?gU>9M=0Wm>E@s~IO>Tul*=143iM(2kH#3_JIz$OmtQEMZb6<5bg26F{l56JD z9Fakc--nW{vEidqbf~R^eo^{gI?t6`g&?{*D{~;Jw&iEL(8oq&@TfO6L|QDKYZOo4 zS6Zmbi>P7Yud>YHb>5hZ@U&YqJb=Bsu2!5KQwW6$Hp9oI>bpI zj?L3#)o{oP7|uvMPDq8zrNPR3O3?6yGfhw{?^V=2{TDneRh5zrl+V3xgZEk?8d5b z6>qNj1>wBHqt!8cb1Yhb-{X@ zVe)T?5t{G;kFBU5=L%MQ;2W_yo(@A>6Thk}{x(}$XlRv&TKOT`Ey7=zQoanluGcG+ zJ-@>_UO)ix3g4aY{Q(76w1_oYRF_)M!{p5_^i^s%?l+pYSzX2g?|=7L!-idPBI;8e zwSaWAH$w`Hpq?@Xoi6D*9N$rM2fxKU*Z#xnpnY6NqSY;Vsf@3Q-4Wzz?x)#(cj*r+ z^!**B+4(*fTN8%{)-!@o%GG<$K8bVlXSMFhOIJkrPG|0{qq1GL7~F*R1uxx*PPp%? z2TXPG*khYXf!NQ1nv+1)AWw0@!p+os>@bi-bs!Cd(HiREH;0D#vqU!)OX+6wJ)xxc zTC`Cq)||?CMWN1$^ zoGetNS=jCg4mrwMy=|V2wQ2+zCFdiuTo*1{E{|jJy71Xmge+O&JItOD6dwb#PbNV* zO>ko8lhO95A5d*IC}X&1pPZWTJG`l;f)-(Cb<`qQu%?<61DJ;%#|u(MGnBQ6{bGXb zepOHkIubOMM;&^?^pPOgy~`*<>7YJb#C4;l9#h*{-0@bR-}1_5HlS5@k|ln3scAz6 z`Y0KXL--CcNH64)^y|{$%OlA`7-uEupCeL=2f=94k={@2pP0?gI}+PrX*@sVx9TEn z2nU-anViDyy0a+MhL~)_CH}TmqL4dSsFCkc&nk*fywtSIZH>`5Za|fUb0F&s^`$_O zY%j<$kdTTsd2*t^6C~5G{W?V85$x=-H}Os5yu&klBABJ;0Gis*gKd}axeBx)QU(?p z_hjAmWr=uVj?%BG{lK&x&=HJc0F*A|cg})dlG-wkCJil}j*`4&c^OQj+~$r&cTBv0 z@0H|1)H9e}O)3H%yN$Og6^9|-gE)e;aXwL`xGgP{1@KE0^$XMpRsgk;-%`0vgt$h_ zc7Ld}Jc_tuL8FS=gtnkMN>eH`a38NIlt-fI;5X zw_We;$L{d9D6*cQ7QL8HDU21@VQ;1R_x6tEyI|k?!>p(-kgheNS?3PdvJrJeTA8^+ zu0wA{01~fM!Ix486;N#$#c6SM=e1Va1V%$98e&j^Ia|Qm?Zf%?mTKkQV;eSK?ydE2 z6iNdRgJQY>YE=7og2Ut3UGJQ)?_m!4UsFSx!AbXF;8*o(xaT{w*s9yLAjdHWz zbyy$F?*pGh2Nq$0UeX8pHSgHw@4vF1nC{QdwyFIWX-Z&xziG&cb&ZO}7Ltik!nYA!NnqD~UW82iNB>(%{K-?sVk~LD^lYA|>HyLig=%x2|ZrD-r~cgy}nG=d3AGQa5^= zw*E7?Of&d|f$p#jsn^6{bPLI%Eg&_pewbdY+9$RqdXKf3LZ%1PKwE^}a8V6ixA7!t zRTBdTG;L$&dVsycNt0N$$YJ5YDmmne7wyd#n6yjRWO^9ddkkE#EtxW89o)N7Z=W{O z&{wf%7ckaUV+2_{IjRyUF{d$QrG6w*K>wH}@YyXRO8~dyyH3X330>^8jnk+qbCOV8 zVl224b@)YA(Iu=k-^6D618iCOnv2bIYdj%d`}gBOvl-@KW7xN)HkyF2GudH+$Amd2 z!g?g2LdDliAXl39P1@kX`h3fzc=#uF&F0q3dON1(-dm7Yto9SnA6EJyQB_(Z8!wnd zeu5rp@2}IW0@Li?pWG02dQ98+*AzICu0Hmv(pcU88SoA@H}y?j_!5>n5gU3QPPY!* zsau*HN+(&n&hto;>?Ub#q#uOzXSl1PN8gsc(_d~Tb9gGK;PWu!jOQl>3=}d2UmKpP zR2mhDBoARwi5Eh#SM<<4X@Mce(`jM#6zv8nHMs;2dBf}*{;wuK4v2dj<16r8Ak6Qi z0iV`QDVpkzNfU*l4AJ>S-{JcchpJL-9b(L2JO|#E={u*f2ilaW73SU#mWdL*C!9-N zo*Segx~e#FOZ>B)c#}lG1z*aSxMS=x6%XhKvS8~ddr4qeYl10$Ngl>*x_i>?#{+rD zyOfAO{2X3mxA4PvvlJUpp{DzAy_p#J_Dk(MvuD%Pfd{mhrKWBk;^aU7V!)0P;jja@ z_3OMLcwdh*;06r?hT=;H#}4X3f2=58;@AM*yLLgCQK*P>`K06nJw40LB}k zLrgO(=@)_s)WC8hs?ZtWyb%`YF7V6=B}`d^KZqfA5ykQ^KU0sT;5TFZxsMj&sNSD+)@ zzuE@JfT#iC%oqlceCs`AC@3~?<`@N-Xq*`UQ|7a#2l?+SLk9kO(BZ_8uVRBi3W9uySqEB#Dl{{w;pZ;q1!4omB_#=3V7i18Fav_E?uv_?H~^UQiJd3(E+cTmAnFF zsQo^wItc+MI$1M^BLhUJo&-an+L{E+jiLXxgtU;is}aP_np;J-|kP*8lY&gW+Z z0pNqj?I^&qGw3jXIp_>$aNdyGgRjy7VDJnT%s+H$;4X-)+2OB@e})+FiZkq$LR_c6 zAn92E;1$u#D-e+f`133;;J<_}{~i{SCqxT5gx-Y!yzv7a@DDY`Kjkho5R+khr773v zFVF*o`PW?jOG)sbx|siBll;N?KNJApn*L9T@_#>t94&tStBG-r1MsTE^cBcE_%Enn zjvnyu5}g0y>ZAUGQ0M6YuL>Rhi+~)}#zH_ekeUY|;GaD5Zpg2zf|w20D^PL5U(n$^ z3E)+7?<-Jy5(LBx?wUgfp#E>#=)dQwCFQRsyet&(w*_>-t2Dh=+OpIC1I)z%(=MXJ z{F5jJ7F@)6GsPY&%Q}#$G`O{NEb@WRd$nuWvnIkri4vyxxCg{}0D9 B@>Bo- delta 49462 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

Gauk6VzRKaGELdj)1bl0ug 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 + 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 29953ea141f55e3b8fc691d31b5ca8816d89fa87..91ca28c8b802289c3a438766657a5e98f20eff03 100644 GIT binary patch delta 47732 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 B@>Bo- delta 49462 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

Gauk6VzRKaGELdj)1bl0ug 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 + + + + 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 29953ea141f55e3b8fc691d31b5ca8816d89fa87..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 56177 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 i;x|p)^~-yfPOPa3(|vBayXKz \(.*\)$'` - 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 29953ea141f55e3b8fc691d31b5ca8816d89fa87..91ca28c8b802289c3a438766657a5e98f20eff03 100644 GIT binary patch delta 47732 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 B@>Bo- delta 49462 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

Gauk6VzRKaGELdj)1bl0ug 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/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) }