Building Windows and Linux Kotlin/Native executables in Mac

03 Sep 2018

One of the issues with Native compilation is that you cannot generate universal executables/libraries.

It is true that Kotlin/Native could just bundle source-code libraries, and just compile them locally when going to generate an executable. That would reduce the number of artifacts / files per artifact. It could locally keep a cache of source to libraries to not generate native code each time.

But right now, when you are building Kotlin/Native libraries, you have to deal with different targets. And you have to build them beforehand, pack them, and maybe upload to bintray, your own artifactory or whatever.

The problem is that it required to either have several machines, or to setup virtual machines and configure everything.

No more.

I have created a docker image that bundles openjdk for linux, and wine with openjdk:

https://github.com/soywiz/docker-wine-openjdk-gradle-kotlin-native

And I have created a several scripts you can include along your gradlew and gradlew.bat files.

gradlew_linux

To run gradlew inside docker using openjdk.

#!/bin/bash
docker run \
	"-v$PWD:/work" \
	"-v$HOME/.gradle-linux:/root/.gradle" \
	"-v$HOME/.m2:/root/.m2" \
	"-v$HOME/.konan:/root/.konan" \
	soywiz/kotlin-native-win \
	./gradlew $*

gradlew_win

To run gradlew.bat inside docker using wine and openjdk.

#!/bin/bash
HOME=`echo ~`

docker run \
	"-v$PWD:/work" \
	"-v$HOME/.gradle-win:/root/.wine/drive_c/users/root/.gradle" \
	"-v$HOME/.m2:/root/.wine/drive_c/users/root/.m2" \
	"-v$HOME/.konan:/root/.wine/drive_c/users/root/.konan" \
	soywiz/kotlin-native-win \
	winecmd gradlew.bat $*

gradlew_wine

In the case you have wine installed and OracleJDK or OpenJDK for windows installed and in path, you can use this script too:

#!/bin/bash
WINEDEBUG=-all wine cmd /c gradlew.bat $*

And to run your executables:

wine

#!/bin/bash
docker run -it "-v$PWD:/work" soywiz/kotlin-native-win wine $*

linux

#!/bin/bash
docker run -it "-v$PWD:/work" soywiz/kotlin-native-win $*

And that’s it. This should simplify things a lot. (At least for me).