How do I compile multi-platform projects from the command line?


#1

I have a full-stack project with Javascript, JVM and native components, with a lot of shared code. I’d like to be able to build this using the command line compiler, but I can’t find any documentation on this. How do I do it?

The only documentation I’ve found on building multi-platform projects assumes I’m using gradle. The only documentation on the command-line compiler doesn’t mention multiplatform at all. I have found the -Xmulti-platform option, but it’s not clear what this actually does (all I can tell is that on its own, nothing useful).

I’ve even resorted to trying to read the gradle plugin source, and that really didn’t help — if it weren’t for the fact that I can see the common module build artifacts produced by gradle, I’d doubt that any such thing existed! I have identified a thing called the metadata compiler, which is what I suspect produces the common module jars full of metadata, but this doesn’t appear to be exposed on the command line.

Any ideas?


#2

https://kotlinlang.org/docs/reference/multiplatform.html#setting-up-a-multiplatform-project

As of Kotlin 1.2, multiplatform projects have to be built with Gradle; other build systems are not supported.

As to how the gradle plugin does it, no idea. Is there any reason why you can’t use gradle?


#3

I realise that gradle’s the only supported build system, but I don’t want to use a build system at all. Hence why I want to know how to run the raw compiler.

And yes, I do have reasons why gradle’s not an option for my use case, but I don’t want to get into them right now.


#4

Compiling Java/Kotlin project and furthermore multiplatform project without build system is very strange and problem. I would spend a tremendous amount of time for nothing. I think one should not try it without exhausting every other option. For example, if you have a limitation on installing the software, gradle could be run without actually installing anything, via wrapper (just from the command line without anything else). If you really want to spend part of your life on building bash monstrosity and have qualification for it, then I think you should have not trouble reading plugin sources. The code is not documented but is written quite clearly. Doing the same with bash is much harder.


#5

Given that I’ve said I can’t use Gradle, telling me to use Gradle isn’t really helping!

In fact, I’ve made it work, mostly. Turns out that the reason why you can only build common/platform modules with Gradle is that, AFAICT, they don’t actually exist outside Gradle’s imagination: there’s no common module build artifact, and all Gradle does is keep track of which source files were in the common module so that they can be compiled alongside the platform module. (This is based on observing kotlin native, which Gradle invokes by calling the executable via a shell. JVM and JS might work differently.)

It appears that expect/actual only work if the compiler can see both source files at the same time. Trying to build a library containing just expects doesn’t work.

So I’ve restructured my app to use DI and interfaces rather than expect/actual and it’s all happy; and I used my new-found knowledge to bodge up some rather shoddy Bazel macros for building JVM, JS and native: https://github.com/davidgiven/stellation/blob/stellation6/kotlin.bzl Performance isn’t the best because shelling out to the compiler’s quite a lot slower than Gradle’s persistent compiler process, and all the paths are harcoded, but it all mostly works.

The mostly is because I think that Konan’s library support is a bit flaky, and I’m using lots, and it’s sometimes behaving very weirdly. (Currently it’s refusing to admit that a library exists, even though I can see the compiler’s opened and read it.) I’m still investigating that.