From ebced0aa2d51c3897a1aa04d9ca593401f1b0845 Mon Sep 17 00:00:00 2001 From: Svyatoslav Scherbina Date: Thu, 30 Mar 2017 10:13:01 +0300 Subject: [PATCH] Make interop tool generate one self-contained `.kt.bc` --- INTEROP.md | 12 ++++++------ .../kotlin/native/interop/gen/jvm/main.kt | 10 +++++++++- cmd/interop | 19 +++++++++++++++++++ samples/csvparser/build.sh | 4 ++-- samples/gitchurn/build.sh | 4 ++-- samples/opengl/build.sh | 5 ++--- samples/socket/build.sh | 4 ++-- samples/tetris/build.sh | 4 ++-- 8 files changed, 44 insertions(+), 18 deletions(-) diff --git a/INTEROP.md b/INTEROP.md index 81bf4669584..eafc7e26dc4 100644 --- a/INTEROP.md +++ b/INTEROP.md @@ -10,7 +10,7 @@ everything needed to interact with an external library. Following workflow is expected when interacting with the native library. * create `.def` file describing what to include into bindings - * use `interop` tool to produce `stubs.bc` and Kotlin bindings + * use `interop` tool to produce Kotlin bindings * run _Kotlin N_ compiler on an application to produce the final executable Interoperability tool analyses C headers and produces "natural" mapping of @@ -24,11 +24,11 @@ Build the dependencies and the compiler (see `README.md`). Prepare stubs for the system sockets library: cd samples/socket - ../../dist/bin/interop -def:sockets.def + ../../dist/bin/interop -def:sockets.def -o:sockets.kt.bc Compile the echo server: - ../../dist/bin/kotlinc EchoServer.kt sockets -nativelibrary socketsstubs.bc \ + ../../dist/bin/kotlinc EchoServer.kt -library sockets.kt.bc \ -o EchoServer.kexe This whole process is automated in `build.sh` script, which also support cross-compilation @@ -60,10 +60,10 @@ Structurally it's a simple property file, looking like this: Then run interop tool with something like (note that for host libraries not included in sysroot search paths for headers may be needed): - interop -def:zlib.def -copt:-I/opt/local/include + interop -def:zlib.def -copt:-I/opt/local/include -o:zlib.kt.bc -This command will produce directory named `zlib` containing file `zlib.kt` -and file `zlibstubs.bc` containing implementation specific glue bitcode. +This command will produce `zlib.kt.bc` compiled library and +`zlib.kt.bc-build/kotlin` directory containing Kotlin source code for the library. If behavior for certain platform shall be modified, one may use format like `compilerOpts.osx` or `compilerOpts.linux` to provide platform-specific values diff --git a/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/jvm/main.kt b/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/jvm/main.kt index 0eaed2c26d5..9ab4def525f 100644 --- a/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/jvm/main.kt +++ b/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/jvm/main.kt @@ -112,6 +112,14 @@ private fun Properties.getSpaceSeparated(name: String): List { return this.getProperty(name)?.split(' ')?.filter { it.isNotEmpty() } ?: emptyList() } +private fun Collection.atMostOne(): T? { + return when (this.size) { + 0 -> null + 1 -> this.iterator().next() + else -> throw IllegalArgumentException("Collection has more than one element.") + } +} + private fun Properties.getOsSpecific(name: String, host: String = detectHost()): String? { @@ -323,7 +331,7 @@ private fun processLib(konanHome: String, val outKtFileRelative = (fqParts + outKtFileName).joinToString("/") val outKtFile = File(ktGenRoot, outKtFileRelative) - val libName = fqParts.joinToString("") + "stubs" + val libName = args["-cstubsname"]?.atMostOne() ?: fqParts.joinToString("") + "stubs" val library = NativeLibrary(headerFiles, compilerOpts, language, excludeSystemLibs) val configuration = InteropConfiguration( diff --git a/cmd/interop b/cmd/interop index 91c23982eec..39e935a71a0 100644 --- a/cmd/interop +++ b/cmd/interop @@ -10,6 +10,8 @@ fi declare -a java_args declare -a interop_args +OUTPUT_FILE_NAME=nativelib.kt.bc + while [ $# -gt 0 ]; do case "$1" in -D*) @@ -20,6 +22,10 @@ while [ $# -gt 0 ]; do java_args=("${java_args[@]}" "${1:2}") shift ;; + -o:*) + OUTPUT_FILE_NAME="${1:3}" + shift + ;; *) interop_args=("${interop_args[@]}" "$1") shift @@ -54,11 +60,24 @@ INTEROP_TOOL=org.jetbrains.kotlin.native.interop.gen.jvm.MainKt FLAVOR_ARG=-flavor:native +GENERATED_DIR="$OUTPUT_FILE_NAME-build/kotlin" +GENERATED_ARG="-generated:$GENERATED_DIR" +NATIVES_DIR="$OUTPUT_FILE_NAME-build/natives" +NATIVES_ARG="-natives:$NATIVES_DIR" +CSTUBSNAME=cstubs +CSTUBSNAME_ARG="-cstubsname:$CSTUBSNAME" + LIBCLANG_DISABLE_CRASH_RECOVERY=1 \ LD_LIBRARY_PATH=${NATIVE_LIB} \ $JAVACMD $JAVA_OPTS ${java_args[@]} \ -cp $INTEROP_CLASSPATH \ $INTEROP_TOOL \ + "$GENERATED_ARG" "$NATIVES_ARG" "$CSTUBSNAME_ARG" \ $FLAVOR_ARG "${interop_args[@]}" \ + || exit 1 +# Stubs may be rather big, so we may need more heap space. +XMX_ARG=-J-Xmx3G +$KONAN_HOME/bin/konanc $XMX_ARG "$GENERATED_DIR" -nolink -nativelibrary "$NATIVES_DIR/$CSTUBSNAME.bc" \ + -o "$OUTPUT_FILE_NAME" diff --git a/samples/csvparser/build.sh b/samples/csvparser/build.sh index 0a3a19af578..3f247f0f308 100755 --- a/samples/csvparser/build.sh +++ b/samples/csvparser/build.sh @@ -18,5 +18,5 @@ LINKER_ARGS=${!var} var=COMPILER_ARGS_${TARGET} COMPILER_ARGS=${!var} # add -opt for an optimized build. -interop -def:$DIR/stdio.def -copt:"$CFLAGS" -target:$TARGET || exit 1 -konanc $COMPILER_ARGS -target $TARGET $DIR/CsvParser.kt stdio -nativelibrary stdiostubs.bc -o CsvParser.kexe || exit 1 +interop -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/gitchurn/build.sh b/samples/gitchurn/build.sh index 0cad2a86ae7..fdb7e383831 100755 --- a/samples/gitchurn/build.sh +++ b/samples/gitchurn/build.sh @@ -23,5 +23,5 @@ LINKER_ARGS=${!var} var=COMPILER_ARGS_${TARGET} COMPILER_ARGS=${!var} # add -opt for an optimized build. -interop -copt:$CFLAGS -def:$DIR/libgit2.def -target:$TARGET || exit 1 -konanc -target $TARGET src libgit2 -nativelibrary libgit2stubs.bc -linkerArgs "$LINKER_ARGS" -o GitChurn.kexe || exit 1 +interop -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/opengl/build.sh b/samples/opengl/build.sh index 67b48a68891..258196c01fb 100755 --- a/samples/opengl/build.sh +++ b/samples/opengl/build.sh @@ -21,6 +21,5 @@ LINKER_ARGS=${!var} var=COMPILER_ARGS_${TARGET} COMPILER_ARGS=${!var} # add -opt for an optimized build. -interop -def:$DIR/opengl.def -target:$TARGET || exit 1 -# OpenGL stubs are rather big, so we need more heap space. -konanc -J-Xmx3G -target $TARGET opengl $DIR/OpenGlTeapot.kt -nativelibrary openglstubs.bc -linkerArgs "$LINKER_ARGS" -o OpenGlTeapot.kexe || exit 1 +interop -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/socket/build.sh b/samples/socket/build.sh index e550368146a..0e601915fa3 100755 --- a/samples/socket/build.sh +++ b/samples/socket/build.sh @@ -18,5 +18,5 @@ LINKER_ARGS=${!var} var=COMPILER_ARGS_${TARGET} COMPILER_ARGS=${!var} # add -opt for an optimized build. -interop -def:$DIR/sockets.def -copt:"$CFLAGS" -target:$TARGET || exit 1 -konanc $COMPILER_ARGS -target $TARGET $DIR/EchoServer.kt sockets -nativelibrary socketsstubs.bc -o EchoServer.kexe || exit 1 +interop -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/tetris/build.sh b/samples/tetris/build.sh index be26c718ee7..d1e28521be4 100755 --- a/samples/tetris/build.sh +++ b/samples/tetris/build.sh @@ -39,6 +39,6 @@ LINKER_ARGS=${!var} var=COMPILER_ARGS_${TARGET} COMPILER_ARGS=${!var} # add -opt for an optimized build. -interop -def:$DIR/sdl.def -copt:"$CFLAGS" -target:$TARGET || exit 1 -konanc $COMPILER_ARGS -target $TARGET sdl $DIR/Tetris.kt -nativelibrary sdlstubs.bc -linkerArgs "$LINKER_ARGS" -o Tetris.kexe || exit 1 +interop -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