How is Kotlin code compiled into native code?
Asked Answered
S

1

14

The official Kotlin/Native documentation states that Kotlin/Native

.. is an LLVM based backend for the Kotlin compiler.

As far as I understand:

  • The Kotlin compiler (kotlinc) produces .class files (with Java bytecode) from your Kotlin source files.
  • Generic LLVM backends (that are not related to Kotlin) take LLVM IR and turn it into binary code.

Therefore, is Kotlin/Native converting Java bytecode into LLVM IR? If so, is it correct to state that Kotlin/Native is a LLVM backend? Does Kotlin code get compiled into LLVM IR? If not, what is the input and output of each compilation step? (e.g.: Kotlin -(kotlinc)-> Java bytecode -(LLVM backend-> native binary)

This blog post states that the Kotlin frontend compiler (I think it is referring to kotlinc) produces Kotlin IR, which I have never read of.

Kotlin compiler has a single front-end but multiple back-end depending upon the the plugin you are using to build the code. Kotlin/Native plugin converts the Kotlin Intermediate Representation (IR) to native code (i.e code that is machine executable).

Is this quote correct?

It tells you that the compilation process is the same for Java bytecode, native code and JavaScript. You compile your Kotlin code and then you have 3 backend compilers that deliver the expected output format (Java bytecode, JavaScript, binary code).

Does the final platform specific binary include the native Kotlin standard library or is it linked dynamically?

Smack answered 10/9, 2019 at 13:44 Comment(1)
The question is already answered, but I just wanted to add that indeed Kotlin was not always compiled via an IR, and that Kotlin IR was originally introduced specifically for Kotlin/Native, and then gradually took over Kotlin/JVM and Kotlin/JS as well. Some details are explained on the Kotlin Blog.Hypoderma
O
13

Kotlin compiler has a single front-end but multiple back-end depending upon the the plugin you are using to build the code. Kotlin/Native plugin converts the Kotlin Intermediate Representation (IR) to native code (i.e code that is machine executable).

Is this quote correct?

Yes, it's quite correct. The intermediate representation (IR) is a form that universally represents a Kotlin program, regardless of the platform. Then a platform-specific back-end translates the IR to the final binary form – the JVM class files for Kotlin/JVM, LLVM bitcode and other metadata packed into a *.klib for Kotlin/Native.

So, Kotlin/Native doesn't deal with the JVM bytecode in any way.

The intermediate representation is an implementation detail of the Kotlin compiler, and it's not used by any other consumer than the Kotlin compiler itself, so it's not a thing that a developer should care about. For the JVM, it's even kept in memory and never written to binaries. For Kotlin/Native, it's actually serialized and written into the *.klib to be reused.

It tells you that the compilation process is the same for Java bytecode, native code and JavaScript. You compile your Kotlin code and then you have 3 backend compilers that deliver the expected output format (Java bytecode, JavaScript, binary code).

Actually, a part of the compilation process is the same, namely, the front-end language analysis, which includes parsing, call resolution, type inference, diagnostics and other steps that don't require any code transformations that are platform-specific. Even so, the front-end part is tuned for each of the platforms, as those allow different sets of language features and provide different sets of diagnostics.

And the last question does the final platform specific binary include the native Kotlin standard library? Or is it linked dynamically?

Currently, the standard library is statically linked into the resulting Kotlin/Native binaries.

Oporto answered 10/9, 2019 at 14:47 Comment(2)
So basically if I understood correctly, even if the frontend compiler is quite similar in the 3 compilation targets (JVM, JS and native), there is not just one tool that converts Kotlin into IR, right? Each compilation target has its own frontend compiler but the output from their specific frontend process would result in the same IR if the code is the same? Then the IR located in the klib is LLVM IR or Kotlin-specific IR?Smack
For JVM the compilation process is pretty clear: kotlinc does everything and I guess the same in regards of Kotlin/JS kotlin2js does everthing. But what does kotlinc do inside? What are its steps? And which would be the front-end and back-end compilers for Kotlin /Native?Smack

© 2022 - 2024 — McMap. All rights reserved.