diff --git a/samples/concurrent/src/kotlin-native/Concurrent.kt b/samples/concurrent/Concurrent.kt similarity index 100% rename from samples/concurrent/src/kotlin-native/Concurrent.kt rename to samples/concurrent/Concurrent.kt diff --git a/samples/concurrent/src/cpp/MessageChannel.cpp b/samples/concurrent/MessageChannel.cpp similarity index 100% rename from samples/concurrent/src/cpp/MessageChannel.cpp rename to samples/concurrent/MessageChannel.cpp diff --git a/samples/concurrent/src/c_interop/MessageChannel.def b/samples/concurrent/MessageChannel.def similarity index 100% rename from samples/concurrent/src/c_interop/MessageChannel.def rename to samples/concurrent/MessageChannel.def diff --git a/samples/concurrent/src/cpp/MessageChannel.h b/samples/concurrent/MessageChannel.h similarity index 100% rename from samples/concurrent/src/cpp/MessageChannel.h rename to samples/concurrent/MessageChannel.h diff --git a/samples/concurrent/README.md b/samples/concurrent/README.md deleted file mode 100644 index b47c99fdeb6..00000000000 --- a/samples/concurrent/README.md +++ /dev/null @@ -1,15 +0,0 @@ -# Concurrent - -This example shows how to implement concurrent programming in Kotlin/Native. -In this example we start multiple threads running concurrently and exchange messages with them. - -To build cpp use `./buildCpp.sh`. -To build kotlin use `../gradlew build`. - -To run use `../gradlew run` - -Alternatively you can run artifact directly - - ./build/konan/bin/MessageChannel/MessageChannel.kexe - -It will print all passed messages. diff --git a/samples/concurrent/build.gradle b/samples/concurrent/build.gradle deleted file mode 100644 index 67e90c622c3..00000000000 --- a/samples/concurrent/build.gradle +++ /dev/null @@ -1,14 +0,0 @@ -apply plugin: 'konan' - -konanInterop { - MessageChannel { - includeDirs "${project.projectDir}/src/cpp" - } -} - -konanArtifacts { - MessageChannel { - useInterop "MessageChannel" - nativeLibrary "${project.buildDir.canonicalPath}/clang/MessageChannel.bc" - } -} \ No newline at end of file diff --git a/samples/concurrent/build.sh b/samples/concurrent/build.sh old mode 100644 new mode 100755 index 9f00cc79695..05b8a6378e1 --- a/samples/concurrent/build.sh +++ b/samples/concurrent/build.sh @@ -1,8 +1,8 @@ #!/usr/bin/env bash - -DIR=$(dirname "$0") +DIR=. PATH=../../dist/bin:../../bin:$PATH +DEPS=$(dirname `type -p konanc`)/../dependencies if [ x$TARGET == x ]; then case "$OSTYPE" in @@ -12,24 +12,19 @@ case "$OSTYPE" in esac fi +CLANG_linux=$DEPS/clang-llvm-3.9.0-linux-x86-64/bin/clang++ +CLANG_macbook=$DEPS/clang-llvm-3.9.0-darwin-macos/bin/clang++ + 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. +var=CLANG_${TARGET} +CLANG=${!var} -rm -rf $DIR/build/ -mkdir $DIR/build/ -mkdir $DIR/build/c_interop/ -mkdir $DIR/build/bin/ - -./buildCpp.sh - -cinterop -def $DIR/src/c_interop/MessageChannel.def -copt "-I$DIR/src/cpp" -target $TARGET \ - -o $DIR/build/c_interop/MessageChannel.kt.bc || exit 1 - -konanc $DIR/src/kotlin-native/Concurrent.kt -library $DIR/build/c_interop/MessageChannel.kt.bc \ - -nativelibrary $DIR/build/clang/MessageChannel.bc -o $DIR/build/bin/Concurrent.kexe || exit 1 - -echo "Artifact path is ./build/bin/Concurrent.kexe" \ No newline at end of file +$CLANG -std=c++11 -c $DIR/MessageChannel.cpp -o $DIR/MessageChannel.bc -emit-llvm || exit 1 +cinterop -def $DIR/MessageChannel.def -copt "-I$DIR" -target $TARGET -o $DIR/MessageChannel.kt.bc || exit 1 +konanc $DIR/Concurrent.kt -library $DIR/MessageChannel.kt.bc \ + -nativelibrary $DIR/MessageChannel.bc -o Concurrent.kexe || exit 1 diff --git a/samples/concurrent/buildCpp.sh b/samples/concurrent/buildCpp.sh deleted file mode 100755 index 8b8319d26cd..00000000000 --- a/samples/concurrent/buildCpp.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/env bash - -DIR=$(dirname "$0") -PATH=../../dist/bin:../../bin:$PATH -DEPS=$(dirname `type -p konanc`)/../dependencies - -if [ x$TARGET == x ]; then -case "$OSTYPE" in - darwin*) TARGET=macbook ;; - linux*) TARGET=linux ;; - *) echo "unknown: $OSTYPE" && exit 1;; -esac -fi - -CLANG_linux=$DEPS/clang-llvm-3.9.0-linux-x86-64/bin/clang++ -CLANG_macbook=$DEPS/clang-llvm-3.9.0-darwin-macos/bin/clang++ - -var=CLANG_${TARGET} -CLANG=${!var} - -mkdir $DIR/build/ -mkdir $DIR/build/clang/ - -$CLANG -std=c++11 -c $DIR/src/cpp/MessageChannel.cpp -o $DIR/build/clang/MessageChannel.bc -emit-llvm || exit 1 \ No newline at end of file diff --git a/samples/csvparser/src/kotlin-native/CsvParser.kt b/samples/csvparser/CsvParser.kt similarity index 100% rename from samples/csvparser/src/kotlin-native/CsvParser.kt rename to samples/csvparser/CsvParser.kt diff --git a/samples/csvparser/README.md b/samples/csvparser/README.md index b5546aecbce..0cc8313a165 100644 --- a/samples/csvparser/README.md +++ b/samples/csvparser/README.md @@ -4,16 +4,12 @@ A sample data [European Mammals Red List for 2009](https://data.europa.eu/euodp/en/data/dataset?res_format=CSV) from EU is being used. -To build use `../gradlew build`. +To build use `./build.sh` script without arguments (or specify `TARGET` variable if cross-compiling). +You also may use Gradle to build this sample: `../gradlew build`. -To run use `../gradlew run` +To run use -To change run arguments, change property runArgs in gradle.propeties file -or pass `-PrunArgs="./European_Mammals_Red_List_Nov_2009.csv 4 100"` to gradle run. - -Alternatively you can run artifact directly - - ./build/konan/bin/CsvParser/CsvParser.kexe ./European_Mammals_Red_List_Nov_2009.csv 4 100 + ./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.gradle b/samples/csvparser/build.gradle index c59195bfa8a..0e066cf8231 100644 --- a/samples/csvparser/build.gradle +++ b/samples/csvparser/build.gradle @@ -1,11 +1,72 @@ apply plugin: 'konan' konanInterop { - stdio { } + stdio { + defFile 'stdio.def' + } } konanArtifacts { CsvParser { + inputFiles project.file('CsvParser.kt') useInterop 'stdio' } +} + +build { + project.ext { outputFile = "${projectDir.canonicalPath}/${file(compileKonanCsvParser.artifactPath).name}" } + doLast { + copy { + from compileKonanCsvParser.artifactPath + into projectDir.canonicalPath + } + } +} + +void dumpCompilationTask(Task task) { + println() + println("Compilation task: ${task.name}") + println("outputDir : ${task.outputDir}") + println("artifactPath : ${task.artifactPath}") + println("inputFiles : ${task.inputFiles.files}") + println("libraries : ${task.libraries}") + println("nativeLibraries : ${task.nativeLibraries}") + println("linkerOpts : ${task.linkerOpts}") + println("noStdLib : ${task.noStdLib}") + println("noLink : ${task.noLink}") + println("noMain : ${task.noMain}") + println("enableOptimization : ${task.enableOptimization}") + println("enableAssertions : ${task.enableAssertions}") + println("target : ${task.target}") + println("languageVersion : ${task.languageVersion}") + println("apiVersion : ${task.apiVersion}") +} + +void dumpInteropTask(Task task) { + println() + println("Stub generation task: ${task.name}") + println("stubsDir : ${task.stubsDir}") + println("libsDir : ${task.libsDir}") + println("defFile : ${task.defFile}") + println("target : ${task.target}") + println("pkg : ${task.pkg}") + println("linker : ${task.linker}") + println("compilerOpts : ${task.compilerOpts}") + println("linkerOpts : ${task.linkerOpts}") + println("headers : ${task.headers.files}") + println("linkFiles : ${task.linkFiles}") +} + +task dumpParameters(type: DefaultTask) { + doLast { + dumpCompilationTask(konanArtifacts['CsvParser'].compilationTask) + dumpInteropTask(konanInterop['stdio'].generateStubsTask) + dumpCompilationTask(konanInterop['stdio'].compileStubsTask) + } +} + +clean { + doLast { + delete outputFile + } } \ No newline at end of file diff --git a/samples/csvparser/build.sh b/samples/csvparser/build.sh old mode 100644 new mode 100755 index cef6007f6a7..5922d14c1da --- a/samples/csvparser/build.sh +++ b/samples/csvparser/build.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -DIR=$(dirname "$0") +DIR=. PATH=../../dist/bin:../../bin:$PATH if [ x$TARGET == x ]; then @@ -18,14 +18,5 @@ LINKER_ARGS=${!var} var=COMPILER_ARGS_${TARGET} COMPILER_ARGS=${!var} # add -opt for an optimized build. -rm -rf $DIR/build/ -mkdir $DIR/build/ -mkdir $DIR/build/c_interop/ -mkdir $DIR/build/bin/ - -cinterop -def $DIR/src/c_interop/stdio.def -copt "$CFLAGS" -target $TARGET -o $DIR/build/c_interop/stdio.kt.bc || exit 1 - -konanc $COMPILER_ARGS -target $TARGET $DIR/src/kotlin-native/CsvParser.kt -library $DIR/build/c_interop/stdio.kt.bc \ - -o $DIR/build/bin/CsvParser.kexe || exit 1 - -echo "Artifact path is ./build/bin/CsvParser.kexe" +cinterop -def $DIR/stdio.def -copt "$CFLAGS" -target $TARGET -o stdio.kt.bc || exit 1 +konanc $COMPILER_ARGS -target $TARGET $DIR/CsvParser.kt -library stdio.kt.bc -o CsvParser.kexe || exit 1 diff --git a/samples/csvparser/gradle.properties b/samples/csvparser/gradle.properties deleted file mode 100644 index 54639beb5fa..00000000000 --- a/samples/csvparser/gradle.properties +++ /dev/null @@ -1 +0,0 @@ -runArgs=./European_Mammals_Red_List_Nov_2009.csv 4 100 \ No newline at end of file diff --git a/samples/csvparser/src/c_interop/stdio.def b/samples/csvparser/stdio.def similarity index 100% rename from samples/csvparser/src/c_interop/stdio.def rename to samples/csvparser/stdio.def diff --git a/samples/gitchurn/README.md b/samples/gitchurn/README.md index 8948dc03565..4bf58c7a3ae 100644 --- a/samples/gitchurn/README.md +++ b/samples/gitchurn/README.md @@ -1,17 +1,13 @@ # GIT frequency analyzer -This example shows how one could perform statistics on Git repository. + This example shows how one could perform statistics on Git repository. libgit2 is required for this to work (`apt-get install libgit2-dev`). -To build use `../gradlew build`. +To build use `./build.sh` script without arguments (or specify `TARGET` variable if cross-compiling). +You also may use Gradle to build this sample: `../gradlew build`. -To run use `../gradlew run`. +To run use -To change run arguments, change property runArgs in gradle.propeties file -or pass `-PrunArgs="../../"` to gradle run. - -Alternatively you can run artifact directly - - ./build/konan/bin/GitChurn/GitChurn.kexe ../../ + ./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 56c831c9465..bb5d6bc83d7 100644 --- a/samples/gitchurn/build.gradle +++ b/samples/gitchurn/build.gradle @@ -1,14 +1,76 @@ apply plugin: 'konan' + konanInterop { libgit2 { + defFile 'libgit2.def' includeDirs '/opt/local/include', '/usr/include', '/usr/local/include' } } konanArtifacts { GitChurn { + inputFiles project.fileTree('src') useInterop 'libgit2' linkerOpts "-L/opt/local/lib -L/usr/lib/x86_64-linux-gnu -L/usr/local/lib -lgit2" } +} + + +build { + project.ext { outputFile = "${projectDir.canonicalPath}/${file(compileKonanGitChurn.artifactPath).name}" } + doLast { + copy { + from compileKonanGitChurn.artifactPath + into projectDir.canonicalPath + } + } +} + +void dumpCompilationTask(Task task) { + println() + println("Compilation task: ${task.name}") + println("outputDir : ${task.outputDir}") + println("artifactPath : ${task.artifactPath}") + println("inputFiles : ${task.inputFiles.files}") + println("libraries : ${task.libraries}") + println("nativeLibraries : ${task.nativeLibraries}") + println("linkerOpts : ${task.linkerOpts}") + println("noStdLib : ${task.noStdLib}") + println("noLink : ${task.noLink}") + println("noMain : ${task.noMain}") + println("enableOptimization : ${task.enableOptimization}") + println("enableAssertions : ${task.enableAssertions}") + println("target : ${task.target}") + println("languageVersion : ${task.languageVersion}") + println("apiVersion : ${task.apiVersion}") +} + +void dumpInteropTask(Task task) { + println() + println("Stub generation task: ${task.name}") + println("stubsDir : ${task.stubsDir}") + println("libsDir : ${task.libsDir}") + println("defFile : ${task.defFile}") + println("target : ${task.target}") + println("pkg : ${task.pkg}") + println("linker : ${task.linker}") + println("compilerOpts : ${task.compilerOpts}") + println("linkerOpts : ${task.linkerOpts}") + println("headers : ${task.headers.files}") + println("linkFiles : ${task.linkFiles}") +} + +task dumpParameters(type: DefaultTask) { + doLast { + dumpCompilationTask(konanArtifacts['GitChurn'].compilationTask) + dumpInteropTask(konanInterop['libgit2'].generateStubsTask) + dumpCompilationTask(konanInterop['libgit2'].compileStubsTask) + } +} + +clean { + doLast { + delete outputFile + } } \ No newline at end of file diff --git a/samples/gitchurn/build.sh b/samples/gitchurn/build.sh old mode 100644 new mode 100755 index 5bb81754457..4aebf21c0fd --- a/samples/gitchurn/build.sh +++ b/samples/gitchurn/build.sh @@ -1,11 +1,14 @@ #!/usr/bin/env bash -DIR=$(dirname "$0") PATH=../../dist/bin:../../bin:$PATH +DIR=. -CFLAGS_macbook="-I/opt/local/include -copt -I/usr/local/include" +# Uncomment flags if your paths differ from these ones. +CFLAGS_macbook=-I/opt/local/include +#CFLAGS_macbook=-I/usr/local/include CFLAGS_linux=-I/usr/include -LINKER_ARGS_macbook="-L/usr/local/lib -L/opt/local/lib -lgit2" +LINKER_ARGS_macbook="-L/opt/local/lib -lgit2" +#LINKER_ARGS_macbook="-L/usr/local/lib -lgit2" LINKER_ARGS_linux="-L/usr/lib/x86_64-linux-gnu -lgit2" if [ x$TARGET == x ]; then @@ -23,15 +26,5 @@ LINKER_ARGS=${!var} var=COMPILER_ARGS_${TARGET} COMPILER_ARGS=${!var} # add -opt for an optimized build. -rm -rf $DIR/build/ -mkdir $DIR/build/ -mkdir $DIR/build/c_interop/ -mkdir $DIR/build/bin/ - -cinterop -copt $CFLAGS -def $DIR/src/c_interop/libgit2.def -target $TARGET \ - -o $DIR/build/c_interop/libgit2.kt.bc || exit 1 - -konanc -target $TARGET $DIR/src/kotlin-native -library $DIR/build/c_interop/libgit2.kt.bc -linkerArgs "$LINKER_ARGS" \ - -o $DIR/build/bin/GitChurn.kexe || exit 1 - -echo "Artifact path is ./build/bin/GitChurn.kexe" +cinterop -copt $CFLAGS -def $DIR/libgit2.def -target $TARGET -o libgit2.kt.bc || exit 1 +konanc -target $TARGET src -library libgit2.kt.bc -linkerArgs "$LINKER_ARGS" -o GitChurn.kexe || exit 1 diff --git a/samples/gitchurn/gradle.properties b/samples/gitchurn/gradle.properties deleted file mode 100644 index 04f83d41802..00000000000 --- a/samples/gitchurn/gradle.properties +++ /dev/null @@ -1 +0,0 @@ -runArgs=../../ \ No newline at end of file diff --git a/samples/gitchurn/src/c_interop/libgit2.def b/samples/gitchurn/libgit2.def similarity index 59% rename from samples/gitchurn/src/c_interop/libgit2.def rename to samples/gitchurn/libgit2.def index 2bec48d14c7..24d1edc187c 100644 --- a/samples/gitchurn/src/c_interop/libgit2.def +++ b/samples/gitchurn/libgit2.def @@ -1,3 +1,3 @@ headers = git2.h time.h linkerOpts = -lgit2 -headerFilter = git2/** time.h \ No newline at end of file +headerFilter = git2/** time.h diff --git a/samples/gitchurn/src/kotlin-native/main.kt b/samples/gitchurn/src/main.kt similarity index 100% rename from samples/gitchurn/src/kotlin-native/main.kt rename to samples/gitchurn/src/main.kt diff --git a/samples/gitchurn/src/kotlin-native/org/konan/libgit/GitChurn.kt b/samples/gitchurn/src/org/konan/libgit/GitChurn.kt similarity index 100% rename from samples/gitchurn/src/kotlin-native/org/konan/libgit/GitChurn.kt rename to samples/gitchurn/src/org/konan/libgit/GitChurn.kt diff --git a/samples/gitchurn/src/kotlin-native/org/konan/libgit/GitCommit.kt b/samples/gitchurn/src/org/konan/libgit/GitCommit.kt similarity index 100% rename from samples/gitchurn/src/kotlin-native/org/konan/libgit/GitCommit.kt rename to samples/gitchurn/src/org/konan/libgit/GitCommit.kt diff --git a/samples/gitchurn/src/kotlin-native/org/konan/libgit/GitDiff.kt b/samples/gitchurn/src/org/konan/libgit/GitDiff.kt similarity index 100% rename from samples/gitchurn/src/kotlin-native/org/konan/libgit/GitDiff.kt rename to samples/gitchurn/src/org/konan/libgit/GitDiff.kt diff --git a/samples/gitchurn/src/kotlin-native/org/konan/libgit/GitRemote.kt b/samples/gitchurn/src/org/konan/libgit/GitRemote.kt similarity index 100% rename from samples/gitchurn/src/kotlin-native/org/konan/libgit/GitRemote.kt rename to samples/gitchurn/src/org/konan/libgit/GitRemote.kt diff --git a/samples/gitchurn/src/kotlin-native/org/konan/libgit/GitRepository.kt b/samples/gitchurn/src/org/konan/libgit/GitRepository.kt similarity index 100% rename from samples/gitchurn/src/kotlin-native/org/konan/libgit/GitRepository.kt rename to samples/gitchurn/src/org/konan/libgit/GitRepository.kt diff --git a/samples/gitchurn/src/kotlin-native/org/konan/libgit/GitTree.kt b/samples/gitchurn/src/org/konan/libgit/GitTree.kt similarity index 100% rename from samples/gitchurn/src/kotlin-native/org/konan/libgit/GitTree.kt rename to samples/gitchurn/src/org/konan/libgit/GitTree.kt diff --git a/samples/gitchurn/src/kotlin-native/org/konan/libgit/git.kt b/samples/gitchurn/src/org/konan/libgit/git.kt similarity index 100% rename from samples/gitchurn/src/kotlin-native/org/konan/libgit/git.kt rename to samples/gitchurn/src/org/konan/libgit/git.kt diff --git a/samples/gtk/README.md b/samples/gtk/README.md index 8063d27171f..6bf2c0e9496 100644 --- a/samples/gtk/README.md +++ b/samples/gtk/README.md @@ -3,18 +3,15 @@ This example shows how one may use _Kotlin/Native_ to build GUI applications with the GTK toolkit. -To build use `../gradlew build`. +To build use `./build.sh` script without arguments (or specify `TARGET` variable if cross-compiling). +You also may use gradle to build the sample: `../gradlew build`. Do not forget to install GTK3. On Mac use `port install gtk3`, on Debian flavours of Linux - `apt-get install libgtk-3-dev`. To run on Mac also install XQuartz X server (https://www.xquartz.org/), and then - ../gradlew run - -Alternatively you can run artifact directly - - ./build/konan/bin/Gtk3Demo/Gtk3Demo.kexe + ./Gtk3Demo.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 088870bda9e..0c3b890ec36 100644 --- a/samples/gtk/build.gradle +++ b/samples/gtk/build.gradle @@ -7,12 +7,30 @@ konanInterop { 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' + defFile 'gtk3.def' } } konanArtifacts { Gtk3Demo { + inputFiles project.fileTree('src') useInterop 'gtk3' linkerOpts "-L/opt/local/lib -L/usr/local/lib -L/usr/lib/x86_64-linux-gnu -lglib-2.0 -lgdk-3.0 -lgtk-3 -lgio-2.0 -lgobject-2.0" } +} + +build { + project.ext { outputFile = "${projectDir.canonicalPath}/${file(compileKonanGtk3Demo.artifactPath).name}" } + doLast { + copy { + from compileKonanGtk3Demo.artifactPath + into projectDir.canonicalPath + } + } +} + +clean { + doLast { + delete outputFile + } } \ No newline at end of file diff --git a/samples/gtk/build.sh b/samples/gtk/build.sh old mode 100644 new mode 100755 index 32deb160975..4113fc961c1 --- a/samples/gtk/build.sh +++ b/samples/gtk/build.sh @@ -1,12 +1,12 @@ #!/usr/bin/env bash -DIR=$(dirname "$0") PATH=../../dist/bin:../../bin:$PATH +DIR=. IPREFIX_macbook=-I/opt/local/include #IPREFIX_macbook=-I/usr/local/include IPREFIX_linux=-I/usr/include -LINKER_ARGS_macbook="-L/opt/local/lib -L/usr/local/lib -lglib-2.0 -lgdk-3.0 -lgtk-3 -lgio-2.0 -lgobject-2.0" +LINKER_ARGS_macbook="-L/opt/local/lib -lglib-2.0 -lgdk-3.0 -lgtk-3 -lgio-2.0 -lgobject-2.0" LINKER_ARGS_linux="-L/usr/lib/x86_64-linux-gnu -lglib-2.0 -lgdk-3 -lgtk-3 -lgio-2.0 -lgobject-2.0" if [ x$TARGET == x ]; then @@ -24,18 +24,13 @@ LINKER_ARGS=${!var} var=COMPILER_ARGS_${TARGET} COMPILER_ARGS=${!var} # add -opt for an optimized build. -rm -rf $DIR/build/ -mkdir $DIR/build/ -mkdir $DIR/build/c_interop/ -mkdir $DIR/build/bin/ +if [ ! -f $DIR/gtk3.bc ]; then + echo "Generating GTK stubs (once), may take few mins depending on the hardware..." + cinterop -J-Xmx8g -copt $IPREFIX/atk-1.0 -copt $IPREFIX/gdk-pixbuf-2.0 -copt $IPREFIX/cairo -copt $IPREFIX/pango-1.0 \ + -copt -I/opt/local/lib/glib-2.0/include -copt -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -copt -I/usr/local/lib/glib-2.0/include \ + -copt $IPREFIX/gtk-3.0 -copt $IPREFIX/glib-2.0 -def $DIR/gtk3.def \ + -target $TARGET -o $DIR/gtk3.bc || exit 1 +fi +konanc -target $TARGET $DIR/src -library $DIR/gtk3.bc -linkerArgs "$LINKER_ARGS" -o $DIR/Gtk3Demo.kexe || exit 1 -echo "Generating GTK stubs, may take few mins depending on the hardware..." -cinterop -J-Xmx8g -copt $IPREFIX/atk-1.0 -copt $IPREFIX/gdk-pixbuf-2.0 -copt $IPREFIX/cairo -copt $IPREFIX/pango-1.0 \ - -copt -I/opt/local/lib/glib-2.0/include -copt -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -copt -I/usr/local/lib/glib-2.0/include \ - -copt $IPREFIX/gtk-3.0 -copt $IPREFIX/glib-2.0 -def $DIR/src/c_interop/gtk3.def \ - -target $TARGET -o $DIR/build/c_interop/gtk3.bc || exit 1 -konanc -target $TARGET $DIR/src/kotlin-native -library $DIR/build/c_interop/gtk3.bc -linkerArgs "$LINKER_ARGS" \ - -o $DIR/build/bin/Gtk3Demo.kexe || exit 1 - -echo "Artifact path is ./build/bin/Gtk3Demo.kexe" \ No newline at end of file diff --git a/samples/gtk/src/c_interop/gtk3.def b/samples/gtk/gtk3.def similarity index 100% rename from samples/gtk/src/c_interop/gtk3.def rename to samples/gtk/gtk3.def diff --git a/samples/gtk/src/kotlin-native/Main.kt b/samples/gtk/src/Main.kt similarity index 100% rename from samples/gtk/src/kotlin-native/Main.kt rename to samples/gtk/src/Main.kt diff --git a/samples/libcurl/README.md b/samples/libcurl/README.md index a20851dd194..d523daf4440 100644 --- a/samples/libcurl/README.md +++ b/samples/libcurl/README.md @@ -2,16 +2,11 @@ This example shows how to communicate with libcurl, HTTP/HTTPS/FTP/etc client library. Debian-like distros may need to `apt-get install libcurl4-openssl-dev`. +To build use `./build.sh` script without arguments (or specify `TARGET` variable if cross-compiling). +You also may use Gradle to build this sample: `../gradlew build`. -To build use `../gradlew build`. +To run use -To run use `../gradlew run` - -To change run arguments, change property runArgs in gradle.propeties file -or pass `-PrunArgs="https://www.jetbrains.com"` to gradle run. - -Alternatively you can run artifact directly - - ./build/konan/bin/Curl/Curl.kexe https://www.jetbrains.com + ./Curl.kexe https://www.jetbrains.com It will perform HTTP get and print out the data obtained. diff --git a/samples/libcurl/build.gradle b/samples/libcurl/build.gradle index 5f2769e627e..e4145783fb6 100644 --- a/samples/libcurl/build.gradle +++ b/samples/libcurl/build.gradle @@ -2,13 +2,31 @@ apply plugin: 'konan' konanInterop { libcurl { + defFile 'libcurl.def' includeDirs '/usr/include', '/opt/local/include', '/usr/local/opt/curl/include', '.' } } konanArtifacts { Curl { + inputFiles project.fileTree('src') useInterop 'libcurl' linkerOpts "-L/opt/local/lib -L/usr/lib/x86_64-linux-gnu -L/usr/local/opt/curl/lib -lcurl" } +} + +build { + project.ext { outputFile = "${projectDir.canonicalPath}/${file(compileKonanCurl.artifactPath).name}" } + doLast { + copy { + from compileKonanCurl.artifactPath + into projectDir.canonicalPath + } + } +} + +clean { + doLast { + delete outputFile + } } \ No newline at end of file diff --git a/samples/libcurl/build.sh b/samples/libcurl/build.sh index 33e4f74b5f5..acd5a115dc3 100755 --- a/samples/libcurl/build.sh +++ b/samples/libcurl/build.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash -DIR=$(dirname "$0") PATH=../../dist/bin:../../bin:$PATH +DIR=. CFLAGS_macbook=-I/opt/local/include CFLAGS_linux=-I/usr/include/x86_64-linux-gnu @@ -23,15 +23,5 @@ LINKER_ARGS=${!var} var=COMPILER_ARGS_${TARGET} COMPILER_ARGS=${!var} # add -opt for an optimized build. -rm -rf $DIR/build/ -mkdir $DIR/build/ -mkdir $DIR/build/c_interop/ -mkdir $DIR/build/bin/ - -cinterop -copt "$CFLAGS" -copt -I$DIR -copt -I/usr/include -def $DIR/src/c_interop/libcurl.def -target $TARGET \ - -o $DIR/build/c_interop/libcurl.bc || exit 1 - -konanc -target $TARGET $DIR/src/kotlin-native -library $DIR/build/c_interop/libcurl.bc -linkerArgs "$LINKER_ARGS" \ - -o $DIR/build/bin/Curl.kexe || exit 1 - -echo "Artifact path is ./build/bin/Curl.kexe" +cinterop -copt "$CFLAGS" -copt -I. -copt -I/usr/include -def $DIR/libcurl.def -target $TARGET -o libcurl.bc || exit 1 +konanc -target $TARGET src -library libcurl.bc -linkerArgs "$LINKER_ARGS" -o Curl.kexe || exit 1 diff --git a/samples/libcurl/gradle.properties b/samples/libcurl/gradle.properties deleted file mode 100644 index 2e09d1407aa..00000000000 --- a/samples/libcurl/gradle.properties +++ /dev/null @@ -1 +0,0 @@ -runArgs=https://www.jetbrains.com \ No newline at end of file diff --git a/samples/libcurl/src/c_interop/libcurl.def b/samples/libcurl/libcurl.def similarity index 100% rename from samples/libcurl/src/c_interop/libcurl.def rename to samples/libcurl/libcurl.def diff --git a/samples/libcurl/src/kotlin-native/main.kt b/samples/libcurl/src/main.kt similarity index 100% rename from samples/libcurl/src/kotlin-native/main.kt rename to samples/libcurl/src/main.kt diff --git a/samples/libcurl/src/kotlin-native/org/konan/libcurl/CUrl.kt b/samples/libcurl/src/org/konan/libcurl/CUrl.kt similarity index 100% rename from samples/libcurl/src/kotlin-native/org/konan/libcurl/CUrl.kt rename to samples/libcurl/src/org/konan/libcurl/CUrl.kt diff --git a/samples/libcurl/src/kotlin-native/org/konan/libcurl/Event.kt b/samples/libcurl/src/org/konan/libcurl/Event.kt similarity index 100% rename from samples/libcurl/src/kotlin-native/org/konan/libcurl/Event.kt rename to samples/libcurl/src/org/konan/libcurl/Event.kt diff --git a/samples/libcurl/src/kotlin-native/org/konan/libcurl/Program.kt b/samples/libcurl/src/org/konan/libcurl/Program.kt similarity index 100% rename from samples/libcurl/src/kotlin-native/org/konan/libcurl/Program.kt rename to samples/libcurl/src/org/konan/libcurl/Program.kt diff --git a/samples/nonBlockingEchoServer/src/kotlin-native/EchoServer.kt b/samples/nonBlockingEchoServer/EchoServer.kt similarity index 100% rename from samples/nonBlockingEchoServer/src/kotlin-native/EchoServer.kt rename to samples/nonBlockingEchoServer/EchoServer.kt diff --git a/samples/nonBlockingEchoServer/README.md b/samples/nonBlockingEchoServer/README.md index a880602f453..cda8c5d979e 100644 --- a/samples/nonBlockingEchoServer/README.md +++ b/samples/nonBlockingEchoServer/README.md @@ -7,20 +7,17 @@ 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: +Compile the echo server (in EAP only supported on Mac host): + + ./build.sh + +You also may use Gradle to build the server: ../gradlew build Run the server: - ../gradlew run - -To change run arguments, change property runArgs in gradle.propeties file -or pass `-PrunArgs="3000"` to gradle run. - -Alternatively you can run artifact directly - - ./build/konan/bin/EchoServer/EchoServer.kexe 3000 & + ./EchoServer.kexe 3000 & Test the server by connecting to it, for example with telnet: diff --git a/samples/nonBlockingEchoServer/build.gradle b/samples/nonBlockingEchoServer/build.gradle index a784b7cdda1..c8a26b5ea2e 100644 --- a/samples/nonBlockingEchoServer/build.gradle +++ b/samples/nonBlockingEchoServer/build.gradle @@ -1,11 +1,30 @@ apply plugin: 'konan' konanInterop { - sockets { } + sockets { + defFile "sockets.def" + } } konanArtifacts { EchoServer { + inputFiles project.file("EchoServer.kt") useInterop "sockets" } +} + +build { + project.ext { outputFile = "${projectDir.canonicalPath}/${file(compileKonanEchoServer.artifactPath).name}" } + doLast { + copy { + from compileKonanEchoServer.artifactPath + into projectDir.canonicalPath + } + } +} + +clean { + doLast { + delete outputFile + } } \ No newline at end of file diff --git a/samples/nonBlockingEchoServer/build.sh b/samples/nonBlockingEchoServer/build.sh old mode 100644 new mode 100755 index 06900482954..4962195956d --- a/samples/nonBlockingEchoServer/build.sh +++ b/samples/nonBlockingEchoServer/build.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash -DIR=$(dirname "$0") PATH=../../dist/bin:../../bin:$PATH +DIR=. if [ x$TARGET == x ]; then case "$OSTYPE" in @@ -18,15 +18,5 @@ LINKER_ARGS=${!var} var=COMPILER_ARGS_${TARGET} COMPILER_ARGS=${!var} # add -opt for an optimized build. -rm -rf $DIR/build/ -mkdir $DIR/build/ -mkdir $DIR/build/c_interop/ -mkdir $DIR/build/bin/ - -cinterop -def $DIR/src/c_interop/sockets.def -copt "$CFLAGS" -target $TARGET \ - -o $DIR/build/c_interop/sockets.kt.bc || exit 1 - -konanc $COMPILER_ARGS -target $TARGET $DIR/src/kotlin-native/EchoServer.kt \ - -library $DIR/build/c_interop/sockets.kt.bc -o build/bin/EchoServer.kexe || exit 1 - -echo "Artifact path is ./build/bin/EchoServer.kexe" \ No newline at end of file +cinterop -def $DIR/sockets.def -copt "$CFLAGS" -target $TARGET -o sockets.kt.bc || exit 1 +konanc $COMPILER_ARGS -target $TARGET $DIR/EchoServer.kt -library sockets.kt.bc -o EchoServer.kexe || exit 1 diff --git a/samples/nonBlockingEchoServer/gradle.properties b/samples/nonBlockingEchoServer/gradle.properties deleted file mode 100644 index f0f9e55f899..00000000000 --- a/samples/nonBlockingEchoServer/gradle.properties +++ /dev/null @@ -1 +0,0 @@ -runArgs=3000 \ No newline at end of file diff --git a/samples/nonBlockingEchoServer/src/c_interop/sockets.def b/samples/nonBlockingEchoServer/sockets.def similarity index 100% rename from samples/nonBlockingEchoServer/src/c_interop/sockets.def rename to samples/nonBlockingEchoServer/sockets.def diff --git a/samples/opengl/src/kotlin-native/OpenGlTeapot.kt b/samples/opengl/OpenGlTeapot.kt similarity index 100% rename from samples/opengl/src/kotlin-native/OpenGlTeapot.kt rename to samples/opengl/OpenGlTeapot.kt diff --git a/samples/opengl/README.md b/samples/opengl/README.md index 326d29478b5..c8174d8ec97 100644 --- a/samples/opengl/README.md +++ b/samples/opengl/README.md @@ -3,13 +3,12 @@ This example shows interaction with OpenGL library, to render classical 3D test model. Linux build requires `apt-get install freeglut3-dev` or similar, MacOS shall work as is. -To build use `../gradlew build`. +To build use `./build.sh` script without arguments (or specify `TARGET` variable if cross-compiling). +You also may use Gradle to build this sample: `../gradlew build`. -To run use `../gradlew run` +To run use -Alternatively you can run artifact directly - - ./build/konan/bin/OpenGlTeapot${target}/OpenGlTeapot${target}.kexe + ./OpenGlTeapot.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 9150132e845..46da90254d9 100644 --- a/samples/opengl/build.gradle +++ b/samples/opengl/build.gradle @@ -1,20 +1,39 @@ apply plugin: 'konan' konanInterop { - opengl { } + opengl { + defFile 'opengl.def' + } } konanArtifacts { - OpenGlTeapotMacbook { + OpenGlTeapot { + inputFiles project.file("OpenGlTeapot.kt") useInterop 'opengl' - linkerOpts "-framework OpenGL -framework GLUT" - target "macbook" + def osName = System.getProperty("os.name") + if (osName.equals("Mac OS X")) { + linkerOpts "-framework OpenGL -framework GLUT" + } + if (osName.equals("Linux")) { + linkerOpts "-L/usr/lib/x86_64-linux-gnu -lglut -lGL -lGLU" + } } +} - OpenGlTeapotLinux { - useInterop 'opengl' - linkerOpts "-L/usr/lib/x86_64-linux-gnu -lglut -lGL -lGLU" - target "linux" + +build { + project.ext { outputFile = "${projectDir.canonicalPath}/${file(compileKonanOpenGlTeapot.artifactPath).name}" } + doLast { + copy { + from compileKonanOpenGlTeapot.artifactPath + into projectDir.canonicalPath + } + } +} + +clean { + doLast { + delete outputFile } } \ No newline at end of file diff --git a/samples/opengl/build.sh b/samples/opengl/build.sh old mode 100644 new mode 100755 index aaec67237fb..5ce3238908d --- a/samples/opengl/build.sh +++ b/samples/opengl/build.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash -DIR=$(dirname "$0") PATH=../../dist/bin:../../bin:$PATH +DIR=. LINKER_ARGS_macbook="-framework OpenGL -framework GLUT" LINKER_ARGS_linux="-L/usr/lib/x86_64-linux-gnu -lglut -lGL -lGLU" @@ -21,15 +21,5 @@ LINKER_ARGS=${!var} var=COMPILER_ARGS_${TARGET} COMPILER_ARGS=${!var} # add -opt for an optimized build. -rm -rf $DIR/build/ -mkdir $DIR/build/ -mkdir $DIR/build/c_interop/ -mkdir $DIR/build/bin/ - -cinterop -def $DIR/src/c_interop/opengl.def -target $TARGET \ - -o $DIR/build/c_interop/opengl.kt.bc || exit 1 - -konanc -target $TARGET $DIR/src/kotlin-native/OpenGlTeapot.kt -library $DIR/build/c_interop/opengl.kt.bc \ - -linkerArgs "$LINKER_ARGS" -o $DIR/build/bin/OpenGlTeapot.kexe || exit 1 - -echo "Artifact path is ./build/bin/OpenGlTeapot.kexe" +cinterop -def $DIR/opengl.def -target $TARGET -o opengl.kt.bc || exit 1 +konanc -target $TARGET $DIR/OpenGlTeapot.kt -library opengl.kt.bc -linkerArgs "$LINKER_ARGS" -o OpenGlTeapot.kexe || exit 1 diff --git a/samples/opengl/src/c_interop/opengl.def b/samples/opengl/opengl.def similarity index 100% rename from samples/opengl/src/c_interop/opengl.def rename to samples/opengl/opengl.def diff --git a/samples/settings.gradle b/samples/settings.gradle index 4fc25b0efa3..981a02417bf 100644 --- a/samples/settings.gradle +++ b/samples/settings.gradle @@ -6,5 +6,3 @@ include ':nonBlockingEchoServer' include ':opengl' include ':socket' include ':tetris' -include ':tensorflow' -include ':concurrent' diff --git a/samples/socket/src/kotlin-native/EchoServer.kt b/samples/socket/EchoServer.kt similarity index 100% rename from samples/socket/src/kotlin-native/EchoServer.kt rename to samples/socket/EchoServer.kt diff --git a/samples/socket/README.md b/samples/socket/README.md index 19ec18db354..5e3e877065e 100644 --- a/samples/socket/README.md +++ b/samples/socket/README.md @@ -1,17 +1,16 @@ # Sockets demo -To build use `../gradlew build`. +Compile the echo server (in EAP only supported on Mac host): + + ./build.sh + +You also may use Gradle to build the server: + + ../gradlew build Run the server: - ../gradlew run - -To change run arguments, change property runArgs in gradle.propeties file -or pass `-PrunArgs="3000"` to gradle run. - -Alternatively you can run artifact directly - - ./build/konan/bin/EchoServer/EchoServer.kexe 3000 & + ./EchoServer.kexe 3000 & Test the server by conecting to it, for example with telnet: diff --git a/samples/socket/build.gradle b/samples/socket/build.gradle index a784b7cdda1..c8a26b5ea2e 100644 --- a/samples/socket/build.gradle +++ b/samples/socket/build.gradle @@ -1,11 +1,30 @@ apply plugin: 'konan' konanInterop { - sockets { } + sockets { + defFile "sockets.def" + } } konanArtifacts { EchoServer { + inputFiles project.file("EchoServer.kt") useInterop "sockets" } +} + +build { + project.ext { outputFile = "${projectDir.canonicalPath}/${file(compileKonanEchoServer.artifactPath).name}" } + doLast { + copy { + from compileKonanEchoServer.artifactPath + into projectDir.canonicalPath + } + } +} + +clean { + doLast { + delete outputFile + } } \ No newline at end of file diff --git a/samples/socket/build.sh b/samples/socket/build.sh old mode 100644 new mode 100755 index af9625e338d..4962195956d --- a/samples/socket/build.sh +++ b/samples/socket/build.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash -DIR=$(dirname "$0") PATH=../../dist/bin:../../bin:$PATH +DIR=. if [ x$TARGET == x ]; then case "$OSTYPE" in @@ -18,16 +18,5 @@ LINKER_ARGS=${!var} var=COMPILER_ARGS_${TARGET} COMPILER_ARGS=${!var} # add -opt for an optimized build. -rm -rf $DIR/build/ -mkdir $DIR/build/ -mkdir $DIR/build/c_interop/ -mkdir $DIR/build/bin/ - -cinterop -def $DIR/src/c_interop/sockets.def -copt "$CFLAGS" -target $TARGET \ - -o $DIR/build/c_interop/sockets.kt.bc || exit 1 - -konanc $COMPILER_ARGS -target $TARGET $DIR/src/kotlin-native/EchoServer.kt \ - -library $DIR/build/c_interop/sockets.kt.bc \ - -o $DIR/build/bin/EchoServer.kexe || exit 1 - -echo "Artifact path is ./build/bin/EchoServer.kexe" \ No newline at end of file +cinterop -def $DIR/sockets.def -copt "$CFLAGS" -target $TARGET -o sockets.kt.bc || exit 1 +konanc $COMPILER_ARGS -target $TARGET $DIR/EchoServer.kt -library sockets.kt.bc -o EchoServer.kexe || exit 1 diff --git a/samples/socket/gradle.properties b/samples/socket/gradle.properties deleted file mode 100644 index f0f9e55f899..00000000000 --- a/samples/socket/gradle.properties +++ /dev/null @@ -1 +0,0 @@ -runArgs=3000 \ No newline at end of file diff --git a/samples/socket/src/c_interop/sockets.def b/samples/socket/sockets.def similarity index 100% rename from samples/socket/src/c_interop/sockets.def rename to samples/socket/sockets.def diff --git a/samples/tensorflow/src/kotlin-native/HelloTensorflow.kt b/samples/tensorflow/HelloTensorflow.kt similarity index 100% rename from samples/tensorflow/src/kotlin-native/HelloTensorflow.kt rename to samples/tensorflow/HelloTensorflow.kt diff --git a/samples/tensorflow/README.md b/samples/tensorflow/README.md index 80f5e7d07a5..0385b01791b 100644 --- a/samples/tensorflow/README.md +++ b/samples/tensorflow/README.md @@ -10,22 +10,14 @@ showing how a TensorFlow client in Kotlin/Native could look like. ## Installation - ./downloadTensorflow.sh + ./build.sh will install [TensorFlow for C](https://www.tensorflow.org/versions/r1.1/install/install_c) into -`$HOME/.konan/third-party/tensorflow` (if not yet done). +`$HOME/.konan/third-party/tensorflow` (if not yet done) and build the example. -To build use + ./HelloTensorflow.kexe - ../gradlew build - -Then run - - ../gradlew run - -Alternatively you can run artifact directly - - ./build/konan/bin/Tensorflow/Tensorflow.kexe +will then run the example. 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 diff --git a/samples/tensorflow/build.gradle b/samples/tensorflow/build.gradle deleted file mode 100644 index c763adeee1e..00000000000 --- a/samples/tensorflow/build.gradle +++ /dev/null @@ -1,14 +0,0 @@ -apply plugin: 'konan' - -konanInterop { - tensorflow { - includeDirs "${System.getProperty("user.home")}/.konan/third-party/tensorflow/include" - } -} - -konanArtifacts { - Tensorflow { - useInterop "tensorflow" - linkerOpts "-L${System.getProperty("user.home")}/.konan/third-party/tensorflow/lib -ltensorflow" - } -} \ No newline at end of file diff --git a/samples/tensorflow/build.sh b/samples/tensorflow/build.sh old mode 100644 new mode 100755 index c6b81253d1c..fcf0a41171e --- a/samples/tensorflow/build.sh +++ b/samples/tensorflow/build.sh @@ -1,13 +1,13 @@ #!/usr/bin/env bash -./downloadTensorflow.sh - -DIR=$(dirname "$0") PATH=../../dist/bin:../../bin:$PATH - +DIR=. TF_TARGET_DIRECTORY="$HOME/.konan/third-party/tensorflow" TF_TYPE="cpu" # Change to "gpu" for GPU support +CFLAGS_macbook="-I${TF_TARGET_DIRECTORY}/include" +CFLAGS_linux="-I${TF_TARGET_DIRECTORY}/include" + if [ x$TARGET == x ]; then case "$OSTYPE" in darwin*) TARGET=macbook; TF_TARGET=darwin ;; @@ -16,9 +16,6 @@ case "$OSTYPE" in 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} @@ -26,19 +23,16 @@ LINKER_ARGS=${!var} var=COMPILER_ARGS_${TARGET} COMPILER_ARGS=${!var} # add -opt for an optimized build. -rm -rf $DIR/build/ -mkdir $DIR/build/ -mkdir $DIR/build/c_interop/ -mkdir $DIR/build/bin/ +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 +fi -cinterop -def $DIR/src/c_interop/tensorflow.def -copt "$CFLAGS" -target $TARGET \ - -o $DIR/build/c_interop/tensorflow.kt.bc || exit 1 - -konanc $COMPILER_ARGS -target $TARGET $DIR/src/kotlin-native/HelloTensorflow.kt \ - -library $DIR/build/c_interop/tensorflow.kt.bc \ - -o $DIR/build/bin/HelloTensorflow.kexe \ - -linkerArgs "-L$TF_TARGET_DIRECTORY/lib -ltensorflow" || exit 1 +cinterop -def $DIR/tensorflow.def -copt "$CFLAGS" -target $TARGET -o tensorflow.kt.bc || exit 1 +konanc $COMPILER_ARGS -target $TARGET $DIR/HelloTensorflow.kt -library tensorflow.kt.bc -o HelloTensorflow.kexe \ + -linkerArgs "-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 ./build/bin/HelloTensorflow.kexe" diff --git a/samples/tensorflow/downloadTensorflow.sh b/samples/tensorflow/downloadTensorflow.sh deleted file mode 100755 index eb3ceb159fc..00000000000 --- a/samples/tensorflow/downloadTensorflow.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/usr/bin/env bash - -DIR=$(dirname "$0") -PATH=../../dist/bin:../../bin:$PATH - -TF_TARGET_DIRECTORY="$HOME/.konan/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 - -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 -fi diff --git a/samples/tensorflow/src/c_interop/tensorflow.def b/samples/tensorflow/tensorflow.def similarity index 100% rename from samples/tensorflow/src/c_interop/tensorflow.def rename to samples/tensorflow/tensorflow.def diff --git a/samples/tetris/src/resources/Info.plist b/samples/tetris/Info.plist similarity index 100% rename from samples/tetris/src/resources/Info.plist rename to samples/tetris/Info.plist diff --git a/samples/tetris/README.md b/samples/tetris/README.md index 03b3191fd2e..334c4730850 100644 --- a/samples/tetris/README.md +++ b/samples/tetris/README.md @@ -13,23 +13,18 @@ use `apt-get install libsdl2-dev`. To build Tetris application for your host platform use - `../gradlew build` - -This task builds the sample for your host platform. Note that SDL2 must be installed on the host. + ./build.sh + +You also may use gradle to build this sample: `../gradlew build`. This task builds the sample for all platforms +supported by the host. Note that SDL2 must be installed on the host. -To run it on the host use `../gradlew run` +For cross-compilation to iOS (on Mac host) use -Alternatively you can run artifact directly - - ./build/konan/bin/Tetris${target}/Tetris${target}.kexe - -For cross-compilation to iOS (on Mac host) use gradle property - - konan.build.targets=all + TARGET=iphone ./build.sh For cross-compilation to Raspberry Pi (on Linux host) use - konan.build.targets=all + TARGET=raspberrypi ./build.sh During build process compilation script creates interoperability bindings to SDL2, using SDL C headers, and then compiles an application with the produced bindings. diff --git a/samples/tetris/src/kotlin-native/Tetris.kt b/samples/tetris/Tetris.kt similarity index 100% rename from samples/tetris/src/kotlin-native/Tetris.kt rename to samples/tetris/Tetris.kt diff --git a/samples/tetris/build.gradle b/samples/tetris/build.gradle index d77ff076b48..30efe387373 100644 --- a/samples/tetris/build.gradle +++ b/samples/tetris/build.gradle @@ -2,8 +2,7 @@ apply plugin: 'konan' konanInterop { sdlMacbook { - defFile 'src/c_interop/sdl.def' - pkg 'sdl' + defFile 'sdl.def' includeDirs '/Library/Frameworks/SDL2.framework/Headers', "${System.getProperty("user.home")}/Library/Frameworks/SDL2.framework/Headers", '/opt/local/include/SDL2', @@ -13,22 +12,19 @@ konanInterop { } sdlLinux { - defFile 'src/c_interop/sdl.def' - pkg 'sdl' + defFile 'sdl.def' includeDirs '/usr/include/SDL2' target 'linux' } sdlIphone { - defFile 'src/c_interop/sdl.def' - pkg 'sdl' + defFile 'sdl.def' includeDirs "${project.property("konan.home")}/dependencies/target-sysroot-2-darwin-ios/System/Library/Frameworks/SDL2.framework/Headers" target 'iphone' } sdlRaspberry { - defFile 'src/c_interop/sdl.def' - pkg 'sdl' + defFile 'sdl.def' includeDirs "${project.property("konan.home")}/dependencies/target-sysroot-1-raspberrypi/usr/include/SDL2" target 'raspberrypi' } @@ -36,6 +32,7 @@ konanInterop { konanArtifacts { TetrisMacbook { + inputFiles project.file('Tetris.kt') useInterop 'sdlMacbook' 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. @@ -44,13 +41,18 @@ konanArtifacts { } TetrisLinux { + inputFiles project.file('Tetris.kt') useInterop 'sdlLinux' + linkerOpts '-L/usr/lib/x86_64-linux-gnu -lSDL2' target 'linux' } TetrisIphone { + + inputFiles project.file('Tetris.kt') useInterop 'sdlIphone' + linkerOpts '-framework SDL2 -framework AVFoundation -framework CoreGraphics -framework CoreMotion ' + '-framework Foundation -framework GameController -framework AudioToolbox -framework OpenGLES ' + '-framework QuartzCore -framework UIKit' @@ -59,22 +61,34 @@ konanArtifacts { } TetrisRaspberry { + inputFiles project.file('Tetris.kt') useInterop 'sdlRaspberry' + linkerOpts '-lSDL2' target 'raspberrypi' } + } build { project.ext { buildTasks = getTaskDependencies().getDependencies().findAll { task -> task.name.startsWith("compileKonan") } + outputFiles = buildTasks.collect { task -> "${projectDir.canonicalPath}/${file(task.artifactPath).name}" } } doLast { buildTasks.forEach() { task -> copy { - from 'src/resources' - into file(task.artifactPath).parentFile + from task.artifactPath + into projectDir.canonicalPath } } } -} \ No newline at end of file +} + +clean { + doLast { + outputFiles.forEach { + delete it + } + } +} diff --git a/samples/tetris/build.sh b/samples/tetris/build.sh old mode 100644 new mode 100755 index 314f08e4efe..cacc31da7e9 --- a/samples/tetris/build.sh +++ b/samples/tetris/build.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash -DIR=$(dirname "$0") PATH=../../dist/bin:../../bin:$PATH +DIR=. DEPS=$(dirname `type -p konanc`)/../dependencies CFLAGS_macbook=-I$HOME/Library/Frameworks/SDL2.framework/Headers @@ -42,17 +42,6 @@ LINKER_ARGS=${!var} var=COMPILER_ARGS_${TARGET} COMPILER_ARGS=${!var} # add -opt for an optimized build. -rm -rf $DIR/build/ -mkdir $DIR/build/ -mkdir $DIR/build/c_interop/ -mkdir $DIR/build/bin/ - -cinterop -def $DIR/src/c_interop/sdl.def -copt "$CFLAGS" -target $TARGET -o $DIR/build/c_interop/sdl.kt.bc || exit 1 - -konanc $COMPILER_ARGS -target $TARGET $DIR/src/kotlin-native/Tetris.kt \ - -library $DIR/build/c_interop/sdl.kt.bc -linkerArgs "$LINKER_ARGS" \ - -o $DIR/build/bin/Tetris.kexe || exit 1 - -cp -R $DIR/src/resources $DIR/build/bin - -echo "Artifact path is ./build/bin/Tetris.kexe" +cinterop -def $DIR/sdl.def -copt "$CFLAGS" -target $TARGET -o sdl.kt.bc || exit 1 +konanc $COMPILER_ARGS -target $TARGET $DIR/Tetris.kt -library sdl.kt.bc -linkerArgs "$LINKER_ARGS" -o Tetris.kexe || exit 1 +#strip Tetris.kexe diff --git a/samples/tetris/src/c_interop/sdl.def b/samples/tetris/sdl.def similarity index 100% rename from samples/tetris/src/c_interop/sdl.def rename to samples/tetris/sdl.def diff --git a/samples/tetris/src/resources/tetris_all.bmp b/samples/tetris/tetris_all.bmp similarity index 100% rename from samples/tetris/src/resources/tetris_all.bmp rename to samples/tetris/tetris_all.bmp diff --git a/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanCompilerDownloadTask.kt b/tools/kotlin-native-gradle-plugin/src/main/kotlin/CompilerDownloadTask.kt similarity index 85% rename from tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanCompilerDownloadTask.kt rename to tools/kotlin-native-gradle-plugin/src/main/kotlin/CompilerDownloadTask.kt index 31d0a8ea0c8..e76989dbb20 100644 --- a/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanCompilerDownloadTask.kt +++ b/tools/kotlin-native-gradle-plugin/src/main/kotlin/CompilerDownloadTask.kt @@ -22,12 +22,12 @@ import org.gradle.api.tasks.TaskAction import org.jetbrains.kotlin.konan.DependencyDownloader import java.io.File -open class KonanCompilerDownloadTask : DefaultTask() { +open class CompilerDownloadTask: DefaultTask() { internal companion object { internal const val DOWNLOAD_URL = "http://download.jetbrains.com/kotlin/native" - internal val KONAN_PARENT_DIR = "${System.getProperty("user.home")}/.konan" + private val KONAN_PARENT_DIR = "${System.getProperty("user.home")}/.konan" internal fun simpleOsName(): String { val osName = System.getProperty("os.name") @@ -47,9 +47,10 @@ open class KonanCompilerDownloadTask : DefaultTask() { return } try { - val konanCompiler = project.konanCompilerName() + val konanCompiler = "kotlin-native-${simpleOsName()}-${project.konanVersion}" logger.info("Downloading Kotlin Native compiler from $DOWNLOAD_URL/$konanCompiler into $KONAN_PARENT_DIR") DependencyDownloader(File(KONAN_PARENT_DIR), DOWNLOAD_URL, listOf(konanCompiler)).run() + project.extensions.extraProperties.set(KonanPlugin.KONAN_HOME_PROPERTY_NAME, "$KONAN_PARENT_DIR/$konanCompiler") } catch (e: RuntimeException) { throw GradleScriptException("Cannot download Kotlin Native compiler", e) } diff --git a/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanCompileTask.kt b/tools/kotlin-native-gradle-plugin/src/main/kotlin/KonanCompilerConfig.kt similarity index 54% rename from tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanCompileTask.kt rename to tools/kotlin-native-gradle-plugin/src/main/kotlin/KonanCompilerConfig.kt index 40991acc599..ae649170900 100644 --- a/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanCompileTask.kt +++ b/tools/kotlin-native-gradle-plugin/src/main/kotlin/KonanCompilerConfig.kt @@ -16,11 +16,9 @@ package org.jetbrains.kotlin.gradle.plugin -import org.gradle.api.DefaultTask import org.gradle.api.Named import org.gradle.api.file.FileCollection import org.gradle.api.internal.project.ProjectInternal -import org.gradle.api.tasks.* import java.io.File /** @@ -63,119 +61,9 @@ import java.io.File * } */ - - -// TODO: form groups for tasks -// TODO: Make the task class nested for config with properties accessible for outer users. -open class KonanCompileTask: DefaultTask() { - - companion object { - const val COMPILER_MAIN = "org.jetbrains.kotlin.cli.bc.K2NativeKt" - } - - val COMPILER_JVM_ARGS: List - get() = listOf("-Dkonan.home=${project.konanHome}", "-Djava.library.path=${project.konanHome}/konan/nativelib") - val COMPILER_CLASSPATH: String - get() = "${project.konanHome}/konan/lib/" - - // Output artifact -------------------------------------------------------- - - protected lateinit var artifactName: String - - @OutputDirectory - lateinit var outputDir: File - internal set - - internal fun init(artifactName: String) { - dependsOn(project.konanCompilerDownloadTask) - this.artifactName = artifactName - outputDir = project.file("${project.konanCompilerOutputDir}/$artifactName") - } - - val artifactPath: String - get() = "${outputDir.absolutePath}/$artifactName.${ if (noLink) "bc" else "kexe" }" - - // Other compilation parameters ------------------------------------------- - - @InputFiles val inputFiles = mutableSetOf() - - @InputFiles val libraries = mutableSetOf() - @InputFiles val nativeLibraries = mutableSetOf() - - @Input var linkerOpts = mutableListOf() - internal set - - @Input var noStdLib = false - internal set - @Input var noLink = false - internal set - @Input var noMain = false - internal set - @Input var enableOptimization = false - internal set - @Input var enableAssertions = false - internal set - - @Optional @Input var target : String? = null - internal set - @Optional @Input var languageVersion : String? = null - internal set - @Optional @Input var apiVersion : String? = null - internal set - - @Input var dumpParameters: Boolean = false - // TODO: Is there a better way to rerun tasks when the compiler version changes? - @Input val konanVersion = project.konanVersion - - // Task action ------------------------------------------------------------ - - protected fun buildArgs() = mutableListOf().apply { - addArg("-output", artifactPath) - - addFileArgs("-library", libraries) - addFileArgs("-nativelibrary", nativeLibraries) - - addListArg("-linkerArgs", linkerOpts) - - addArgIfNotNull("-target", target) - addArgIfNotNull("-language-version", languageVersion) - addArgIfNotNull("-api-version", apiVersion) - - addKey("-nostdlib", noStdLib) - addKey("-nolink", noLink) - addKey("-nomain", noMain) - addKey("-opt", enableOptimization) - addKey("-ea", enableAssertions) - - (if (inputFiles.isEmpty()) { - project.fileTree("${project.projectDir.canonicalPath}/src/kotlin-native") - } else { - inputFiles.flatMap { it.files } - }).filter { it.name.endsWith(".kt") }.mapTo(this) { it.canonicalPath } - } - - @TaskAction - fun compile() { - project.file(outputDir).mkdirs() - - if (dumpParameters) dumpProperties(this@KonanCompileTask) - - // TODO: Use compiler service. - project.javaexec { - with(it) { - main = COMPILER_MAIN - classpath = project.fileTree(COMPILER_CLASSPATH).apply { include("*.jar") } - jvmArgs(COMPILER_JVM_ARGS) - args(buildArgs().apply { logger.info("Compiler args: ${this.joinToString(separator = " ")}") }) - } - } - } - -} - // TODO: check debug outputs // TODO: Use +=/-= syntax for libraries and inputFiles -open class KonanCompileConfig( +open class KonanCompilerConfig( val configName: String, val project: ProjectInternal, taskNamePrefix: String = "compileKonan"): Named { @@ -185,14 +73,14 @@ open class KonanCompileConfig( val compilationTask: KonanCompileTask = project.tasks.create( "$taskNamePrefix${configName.capitalize()}", KonanCompileTask::class.java - ) { it.init(this@KonanCompileConfig.name) } + ) { it.initialize(this@KonanCompilerConfig.name) } protected fun String.toAbsolutePath() = project.file(this).canonicalPath // DSL methods -------------------------------------------------- // TODO: Check if we copied all data or not - fun extendsFrom(anotherConfig: KonanCompileConfig) = with(compilationTask) { + fun extendsFrom(anotherConfig: KonanCompilerConfig) = with(compilationTask) { val anotherTask = anotherConfig.compilationTask outputDir(anotherTask.outputDir.absolutePath) @@ -210,7 +98,7 @@ open class KonanCompileConfig( if (anotherTask.enableAssertions) enableAssertions() } - private fun useInteropFromConfig(interopConfig: KonanInteropConfig) { + fun useInterop(interopConfig: KonanInteropConfig) { val generateStubsTask = interopConfig.generateStubsTask val compileStubsTask = interopConfig.compileStubsTask @@ -227,14 +115,7 @@ open class KonanCompileConfig( include("**/*.bc") }) } - - fun useInterops(interops: ArrayList) { - interops.forEach { useInteropFromConfig(project.konanInteropContainer.getByName(it)) } - } - - fun useInterop(interop: String) { - useInteropFromConfig(project.konanInteropContainer.getByName(interop)) - } + fun useInterop(interop: String) = useInterop(project.konanInteropContainer.getByName(interop)) // DSL. Input/output files @@ -308,8 +189,4 @@ open class KonanCompileConfig( fun enableAssertions() = with(compilationTask) { enableAssertions = true } - - fun dumpParameters(value: Boolean) = with(compilationTask) { - dumpParameters = value - } -} +} \ No newline at end of file diff --git a/tools/kotlin-native-gradle-plugin/src/main/kotlin/KonanCompilerTask.kt b/tools/kotlin-native-gradle-plugin/src/main/kotlin/KonanCompilerTask.kt new file mode 100644 index 00000000000..93cb320c7d4 --- /dev/null +++ b/tools/kotlin-native-gradle-plugin/src/main/kotlin/KonanCompilerTask.kt @@ -0,0 +1,125 @@ +/* + * 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.jetbrains.kotlin.gradle.plugin + +import org.gradle.api.DefaultTask +import org.gradle.api.file.FileCollection +import org.gradle.api.tasks.* +import java.io.File + +// TODO: form groups for tasks +// TODO: Make the task class nested for config with properties accessible for outer users. +open class KonanCompileTask: DefaultTask() { + + companion object { + const val COMPILER_MAIN = "org.jetbrains.kotlin.cli.bc.K2NativeKt" + } + + val COMPILER_JVM_ARGS: List + get() = listOf("-Dkonan.home=${project.konanHome}", "-Djava.library.path=${project.konanHome}/konan/nativelib") + val COMPILER_CLASSPATH: String + get() = "${project.konanHome}/konan/lib/" + + // Output artifact -------------------------------------------------------- + + lateinit var artifactName: String + + @OutputDirectory + lateinit var outputDir: File + internal set + + internal fun initialize(artifactName: String) { + dependsOn(project.konanCompilerDownloadTask) + this.artifactName = artifactName + outputDir = project.file("${project.konanCompilerOutputDir}/$artifactName") + } + + val artifactPath: String + get() = "${outputDir.absolutePath}/$artifactName.${ if (noLink) "bc" else "kexe" }" + + // Other compilation parameters ------------------------------------------- + + @InputFiles val inputFiles = mutableSetOf() + + @InputFiles val libraries = mutableSetOf() + @InputFiles val nativeLibraries = mutableSetOf() + + @Input var linkerOpts = mutableListOf() + internal set + + @Input var noStdLib = false + internal set + @Input var noLink = false + internal set + @Input var noMain = false + internal set + @Input var enableOptimization = false + internal set + @Input var enableAssertions = false + internal set + + @Optional @Input var target : String? = null + internal set + @Optional @Input var languageVersion : String? = null + internal set + @Optional @Input var apiVersion : String? = null + internal set + + // TODO: Is there a better way to rerun tasks when the compiler version changes? + @Input val konanVersion = project.konanVersion + + // Task action ------------------------------------------------------------ + + protected fun buildArgs() = mutableListOf().apply { + addArg("-output", artifactPath) + + addFileArgs("-library", libraries) + addFileArgs("-nativelibrary", nativeLibraries) + + addListArg("-linkerArgs", linkerOpts) + + addArgIfNotNull("-target", target) + addArgIfNotNull("-language-version", languageVersion) + addArgIfNotNull("-api-version", apiVersion) + + addKey("-nostdlib", noStdLib) + addKey("-nolink", noLink) + addKey("-nomain", noMain) + addKey("-opt", enableOptimization) + addKey("-ea", enableAssertions) + + inputFiles.forEach { + it.files.filter { it.name.endsWith(".kt") }.mapTo(this) { it.canonicalPath } + } + } + + @TaskAction + fun compile() { + project.file(outputDir).mkdirs() + + // TODO: Use compiler service. + project.javaexec { + with(it) { + main = COMPILER_MAIN + classpath = project.fileTree(COMPILER_CLASSPATH).apply { include("*.jar") } + jvmArgs(COMPILER_JVM_ARGS) + args(buildArgs().apply { logger.info("Compiler args: ${this.joinToString(separator = " ")}") }) + } + } + } + +} diff --git a/tools/kotlin-native-gradle-plugin/src/main/kotlin/KonanInteropConfig.kt b/tools/kotlin-native-gradle-plugin/src/main/kotlin/KonanInteropConfig.kt new file mode 100644 index 00000000000..3901ace49e0 --- /dev/null +++ b/tools/kotlin-native-gradle-plugin/src/main/kotlin/KonanInteropConfig.kt @@ -0,0 +1,116 @@ +/* + * 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.jetbrains.kotlin.gradle.plugin + +import org.gradle.api.Named +import org.gradle.api.Project +import org.gradle.api.Task +import org.gradle.api.file.FileCollection +import org.gradle.api.internal.project.ProjectInternal + +/** + * What we can: + * + * konanInterop { + * foo { + * defFile + * pkg + * target + * compilerOpts + * linkerOpts + * headers + * includeDirs + * linkFiles + * } + * + * // TODO: add configuration for konan compiler + * } + */ + +open class KonanInteropConfig( + val configName: String, + val project: ProjectInternal +): Named { + + override fun getName() = configName + + // Child tasks ------------------------------------------------------------ + + // Task to process the library and generate stubs + val generateStubsTask: KonanInteropTask = project.tasks.create( + "gen${name.capitalize()}InteropStubs", + KonanInteropTask::class.java + ) + + // Config and task to compile *.kt stubs in a *.bc library + internal val compileStubsConfig = KonanCompilerConfig("${name}InteropStubs", project, "compile").apply { + compilationTask.dependsOn(generateStubsTask) + outputDir("${project.konanInteropCompiledStubsDir}/$name") + noLink() + inputFiles(project.fileTree(generateStubsTask.stubsDir).apply { builtBy(generateStubsTask) }) + } + val compileStubsTask = compileStubsConfig.compilationTask + + // DSL methods ------------------------------------------------------------ + + fun defFile(file: Any) = with(generateStubsTask) { + defFile = project.file(file) + } + + fun pkg(value: String) = with(generateStubsTask) { + pkg = value + } + + fun target(value: String) = with(generateStubsTask) { + generateStubsTask.target = value + compileStubsTask.target = value + } + + fun compilerOpts(vararg values: String) = with(generateStubsTask) { + compilerOpts.addAll(values) + } + + fun header(file: Any) = headers(file) + fun headers(vararg files: Any) = with(generateStubsTask) { + headers.add(project.files(files)) + } + fun headers(files: FileCollection) = with(generateStubsTask) { + headers.add(files) + } + + + fun includeDirs(vararg values: String) = with(generateStubsTask) { + compilerOpts.addAll(values.map { "-I$it" }) + } + + fun linker(value: String) = with(generateStubsTask) { + linker = value + } + + fun linkerOpts(vararg values: String) = linkerOpts(values.toList()) + fun linkerOpts(values: List) = with(generateStubsTask) { + linkerOpts.addAll(values) + } + + fun link(vararg files: Any) = with(generateStubsTask) { + linkFiles.add(project.files(files)) + } + fun link(files: FileCollection) = with(generateStubsTask) { + linkFiles.add(files) + } + +} diff --git a/tools/kotlin-native-gradle-plugin/src/main/kotlin/KonanInteropTask.kt b/tools/kotlin-native-gradle-plugin/src/main/kotlin/KonanInteropTask.kt new file mode 100644 index 00000000000..b40fb9427c4 --- /dev/null +++ b/tools/kotlin-native-gradle-plugin/src/main/kotlin/KonanInteropTask.kt @@ -0,0 +1,113 @@ +/* + * 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.jetbrains.kotlin.gradle.plugin + +import org.gradle.api.DefaultTask +import org.gradle.api.Task +import org.gradle.api.file.FileCollection +import org.gradle.api.tasks.* +import java.io.File + + +open class KonanInteropTask: DefaultTask() { + + internal companion object { + const val INTEROP_MAIN = "org.jetbrains.kotlin.native.interop.gen.jvm.MainKt" + } + + init { + dependsOn(project.konanCompilerDownloadTask) + } + + internal val INTEROP_JVM_ARGS: List + get() = listOf("-Dkonan.home=${project.konanHome}", "-Djava.library.path=${project.konanHome}/konan/nativelib") + internal val INTEROP_CLASSPATH: String + get() = "${project.konanHome}/konan/lib/" + + + // Output directories ----------------------------------------------------- + + /** Directory with autogenerated interop stubs (*.kt) */ + @OutputDirectory + val stubsDir = project.file("${project.konanInteropStubsOutputDir}/$name") + + /** Directory with library bitcodes (*.bc) */ + @OutputDirectory + val libsDir = project.file("${project.konanInteropLibsOutputDir}/$name") + + // Interop stub generator parameters ------------------------------------- + + @Optional @InputFile var defFile: File? = null + internal set + @Optional @Input var target: String? = null + internal set + @Optional @Input var pkg: String? = null + internal set + @Optional @Input var linker: String? = null + internal set + + @Input val compilerOpts = mutableListOf() + @Input val linkerOpts = mutableListOf() + + // TODO: Check if we can use only one FileCollection instead of set. + @InputFiles val headers = mutableSetOf() + @InputFiles val linkFiles = mutableSetOf() + + @Input val konanVersion = project.konanVersion + + @TaskAction + fun exec() { + project.javaexec { + with(it) { + main = INTEROP_MAIN + classpath = project.fileTree(INTEROP_CLASSPATH).apply { include("*.jar") } + jvmArgs(INTEROP_JVM_ARGS) + environment("LIBCLANG_DISABLE_CRASH_RECOVERY", "1") + + args(buildArgs().apply { logger.info("Interop args: ${this.joinToString(separator = " ")}") }) + } + } + } + + protected fun buildArgs() = mutableListOf().apply { + addArg("-properties", "${project.konanHome}/konan/konan.properties") + addArg("-flavor", "native") + + addArg("-generated", stubsDir.canonicalPath) + addArg("-natives", libsDir.canonicalPath) + + addArgIfNotNull("-target", target) + addArgIfNotNull("-def", defFile?.canonicalPath) + addArgIfNotNull("-pkg", pkg) + addArgIfNotNull("-linker", linker) + + addFileArgs("-h", headers) + + compilerOpts.forEach { + addArg("-copt", it) + } + + val linkerOpts = mutableListOf().apply { addAll(linkerOpts) } + linkFiles.forEach { + linkerOpts.addAll(it.files.map { it.canonicalPath }) + } + linkerOpts.forEach { + addArg("-lopt", it) + } + } + +} diff --git a/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanPlugin.kt b/tools/kotlin-native-gradle-plugin/src/main/kotlin/KonanPlugin.kt similarity index 56% rename from tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanPlugin.kt rename to tools/kotlin-native-gradle-plugin/src/main/kotlin/KonanPlugin.kt index c63f36e6696..33f64f8a5c1 100644 --- a/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanPlugin.kt +++ b/tools/kotlin-native-gradle-plugin/src/main/kotlin/KonanPlugin.kt @@ -58,25 +58,26 @@ internal val Project.konanVersion get() = findProperty(KonanPlugin.KONAN_VERSION_PROPERTY_NAME) as String? ?: KonanPlugin.DEFAULT_KONAN_VERSION internal val Project.supportedCompileTasks: TaskCollection - get() { - return project.tasks.withType(KonanCompileTask::class.java).matching { it.target?.isSupported() ?: true } - } + get() = project.tasks.withType(KonanCompileTask::class.java).matching { it.target?.isSupported() ?: true } internal val Project.supportedInteropTasks: TaskCollection get() = project.tasks.withType(KonanInteropTask::class.java).matching { it.target?.isSupported() ?: true } -internal fun Project.konanCompilerName(): String = - "kotlin-native-${KonanCompilerDownloadTask.simpleOsName()}-${this.konanVersion}" +private fun String.isSupported(): Boolean { + val os = CompilerDownloadTask.simpleOsName() + return when (os) { + "macos" -> this == "macbook" || this == "iphone" + "linux" -> this == "linux" || this == "raspberrypi" + else -> false + } +} -internal fun Project.konanCompilerDownloadDir(): String = - KonanCompilerDownloadTask.KONAN_PARENT_DIR + "/" + project.konanCompilerName() - -class KonanArtifactsContainer(val project: ProjectInternal): AbstractNamedDomainObjectContainer( - KonanCompileConfig::class.java, +class KonanArtifactsContainer(val project: ProjectInternal): AbstractNamedDomainObjectContainer( + KonanCompilerConfig::class.java, project.gradle.services.get(Instantiator::class.java)) { - override fun doCreate(name: String): KonanCompileConfig = - KonanCompileConfig(name, project) + override fun doCreate(name: String): KonanCompilerConfig = + KonanCompilerConfig(name, project) } class KonanInteropContainer(val project: ProjectInternal): AbstractNamedDomainObjectContainer( @@ -124,58 +125,6 @@ internal fun MutableList.addListArg(parameter: String, values: List { - println() - println("Compilation task: ${task.name}") - println("outputDir : ${task.outputDir}") - println("artifactPath : ${task.artifactPath}") - println("inputFiles : ${task.inputFiles.joinToString(prefix = "[", separator = ", ", postfix = "]")}") - println("libraries : ${task.libraries}") - println("nativeLibraries : ${task.nativeLibraries}") - println("linkerOpts : ${task.linkerOpts}") - println("noStdLib : ${task.noStdLib}") - println("noLink : ${task.noLink}") - println("noMain : ${task.noMain}") - println("enableOptimization : ${task.enableOptimization}") - println("enableAssertions : ${task.enableAssertions}") - println("target : ${task.target}") - println("languageVersion : ${task.languageVersion}") - println("apiVersion : ${task.apiVersion}") - println() - } - is KonanInteropTask -> { - println() - println("Stub generation task: ${task.name}") - println("stubsDir : ${task.stubsDir}") - println("libsDir : ${task.libsDir}") - println("defFile : ${task.defFile}") - println("target : ${task.target}") - println("pkg : ${task.pkg}") - println("linker : ${task.linker}") - println("compilerOpts : ${task.compilerOpts}") - println("linkerOpts : ${task.linkerOpts}") - println("headers : ${task.headers.joinToString(prefix = "[", separator = ", ", postfix = "]")}") - println("linkFiles : ${task.linkFiles}") - println() - } - else -> { - println("Unsupported task.") - } - } -} - -private fun String.isSupported(): Boolean { - val os = KonanCompilerDownloadTask.simpleOsName() - return when (os) { - "macos" -> this == "macbook" || this == "iphone" - "linux" -> this == "linux" || this == "raspberrypi" - else -> false - } -} - - class KonanPlugin @Inject constructor(private val registry: ToolingModelBuilderRegistry) : Plugin { @@ -186,7 +135,6 @@ class KonanPlugin @Inject constructor(private val registry: ToolingModelBuilderR internal const val KONAN_HOME_PROPERTY_NAME = "konan.home" internal const val KONAN_VERSION_PROPERTY_NAME = "konan.version" - internal const val KONAN_BUILD_TARGETS = "konan.build.targets" internal const val DEFAULT_KONAN_VERSION = "0.2" } @@ -205,57 +153,28 @@ class KonanPlugin @Inject constructor(private val registry: ToolingModelBuilderR } } + private fun String.isSupported(): Boolean { + val os = CompilerDownloadTask.simpleOsName() + return when (os) { + "macos" -> this == "macbook" || this == "iphone" + "linux" -> this == "linux" || this == "raspberrypi" + else -> false + } + } + // TODO: Create default config? what about test sources? override fun apply(project: ProjectInternal?) { if (project == null) { return } registry.register(KonanToolingModelBuilder) - project.tasks.create(KONAN_DOWNLOAD_TASK_NAME, KonanCompilerDownloadTask::class.java) + project.tasks.create(KONAN_DOWNLOAD_TASK_NAME, CompilerDownloadTask::class.java) project.extensions.add(COMPILER_EXTENSION_NAME, KonanArtifactsContainer(project)) project.extensions.add(INTEROP_EXTENSION_NAME, KonanInteropContainer(project)) - if (!project.extensions.extraProperties.has(KonanPlugin.KONAN_HOME_PROPERTY_NAME)) { - project.extensions.extraProperties.set(KonanPlugin.KONAN_HOME_PROPERTY_NAME, project.konanCompilerDownloadDir()) - } - val hostTarget = when (KonanCompilerDownloadTask.simpleOsName()) { - "macos" -> "macbook" - "linux" -> "linux" - else -> throw IllegalStateException("Unsupported platform") - } - if (!project.extensions.extraProperties.has(KonanPlugin.KONAN_BUILD_TARGETS)) { - project.extensions.extraProperties.set(KonanPlugin.KONAN_BUILD_TARGETS, hostTarget) - } getTask(project, "clean").doLast { project.delete(project.konanBuildRoot) } - val targets = project.extensions.extraProperties.get(KonanPlugin.KONAN_BUILD_TARGETS).toString().trim().split(' ') - val predicate: (KonanCompileTask) -> Boolean = { task -> - if (targets.contains("all")) { - task.target?.isSupported() ?: true - } else { - val target = task.target - target == null || targets.contains(target) - } - } - val matchingTasks = project.tasks.withType(KonanCompileTask::class.java).matching(predicate) getTask(project, "build").apply { dependsOn(project.supportedCompileTasks) - } - - getTask(project, "run").apply { - dependsOn(getTask(project, "build")) - doLast { - for (task in project.tasks.withType(KonanCompileTask::class.java).matching { it.target?.equals(hostTarget) ?: true}) { - if (task.artifactPath.endsWith("kexe")) { - project.exec { - with(it) { - commandLine(task.artifactPath) - if (project.extensions.extraProperties.has("runArgs")) { - args(project.extensions.extraProperties.get("runArgs").toString().split(' ')) - } - } - } - } - } - } + dependsOn(project.supportedInteropTasks) } } diff --git a/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanToolingModelBuilder.kt b/tools/kotlin-native-gradle-plugin/src/main/kotlin/KonanToolingModelBuilder.kt similarity index 100% rename from tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanToolingModelBuilder.kt rename to tools/kotlin-native-gradle-plugin/src/main/kotlin/KonanToolingModelBuilder.kt diff --git a/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/model/KonanModel.kt b/tools/kotlin-native-gradle-plugin/src/main/kotlin/model/KonanModel.kt similarity index 100% rename from tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/model/KonanModel.kt rename to tools/kotlin-native-gradle-plugin/src/main/kotlin/model/KonanModel.kt diff --git a/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanInteropTask.kt b/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanInteropTask.kt deleted file mode 100644 index d1c6ecd6e9f..00000000000 --- a/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanInteropTask.kt +++ /dev/null @@ -1,221 +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.jetbrains.kotlin.gradle.plugin - -import org.gradle.api.DefaultTask -import org.gradle.api.Named -import org.gradle.api.file.FileCollection -import org.gradle.api.internal.project.ProjectInternal -import org.gradle.api.tasks.* -import java.io.File - -/** - * What we can: - * - * konanInterop { - * pkgName { - * defFile - * pkg - * target - * compilerOpts - * linkerOpts - * headers - * includeDirs - * linkFiles - * dumpParameters