Would it be possible for K/N to have a pure bitcod...
# kotlin-native
l
Would it be possible for K/N to have a pure bitcode target? From my very limited understanding of LLVM, it sounds like the main platform-specific parts of bitcode are in the form of linking external symbols, which may not be available on all platforms. It seems like it should be possible to compile and publish a library as raw bitcode, which would be helpful as new targets get added in the future.
👀 1
It seems like something like this would be crucial to the eventual goal of custom cross-compilation. If we were able to customize the compilation, there likely won't be any published libraries that are compatible.
When I did some experimenting with the cli compiler a while back, I saw that there's a flag that produces raw bitcode, which we presumably could pass to a compatible LLVM, then link against a custom built K/N runtime, but I never tested this theory.
a
I am no expert, but aren't you talking about klib??
l
I believe the klib format packages bitcode, but it currently is tied to a specific target, such as iosArm64, linuxX64, etc. As far as I'm aware, there's not a way to build a klib that's just bitcode with no specific target and publish it. The idea being that any K/N target could consume this klib.
e
LLVM IR is not meant to be cross-platform. all sorts of platform-specific ABI such as integer sizes and calling conventions leak into it.
a
I get your point now. But while it is something I desire, having an abstract bitcode (one that will work for all targets) might be just too much abstraction as some platforms are really very different (i.e. JS and ios). How would you have bitcode that works same for both???
l
JS would not be covered by LLVM bitcode. I'm more so wondering if there's a good way to make sure libraries are compatible with future K/N targets. Right now, when a new target is added (like the new watch target in 1.8.0), libraries have to be updated to support them.
e
https://youtrack.jetbrains.com/issue/KT-52666 is perhaps what you are looking for
l
Since bitcode requires knowledge of calling conventions, pure bitcode may not be the solution
e
I believe the long-term plan is to ship the Kotlin compiler's IR
there is no existing IR that is suitable
l
I remember talk about a longer term goal of allowing custom cross compilation (I may be thinking of KT-43974). If this is added, I don't see how you'd be able to use existing libraries without some form of IR publishing.
t
The documentation gives you some answers here: https://kotlinlang.org/docs/native-libraries.html#library-format From the above, klibs contain both platform specific bitcode and platform independent Kotlin IR. The IR is generated from Kotlin source, while the bitcode is from any interop sources.
n
Hypothetically if Kotlin Native had some Bare Metal targets (eg RP2040 - https://www.raspberrypi.com/documentation/microcontrollers/rp2040.html ), how would the bit code library stuff work on these targets? There is a reason the bit code is target specific.
e
not sure what the the issue with bare metal is. the common stdlib doesn't have I/O or other OS interaction. you need a memory allocator, but you can't run Kotlin without one, regardless of stdlib or not
l
I'd assume any type of 'target independent' IR would not allow you to depend on a library that defines just a set of targets (likely no okio or compose for the reasons mentioned above). It would mainly have value for libraries such as unit conversion, text processing, math, and other more abstract concepts. It would be nice to have these libraries without having to build them with new targets yourself.
n
Isn't the K/N memory allocator separate from the Kotlin Std lib?
l
The memory allocator is part of the K/N runtime
n
I thought that would be the case.
On the K/N side what is part of the Kotlin Std lib (as a summary)? Presumably there isn't anything in the Std lib that would prevent it being used with a Bare Metal target (as a show stopper). Would be good if a member of the Kotlin team can confirm this.
l
https://github.com/JetBrains/kotlin/tree/master/libraries/stdlib I believe most of the stdlib is multiplatform now. K/N hasn't had its own stdlib in a little while.
n
Is K/N's version of the Std lib the Common module version?
t
Not entirely. There are parts of the standard library that is only available in K/N, like <https:kotlin.native|kotlin.native>, kotlin.native.concurrent, and kotlin.native.ref. Most of these exist because the programming model has to be slightly different for native targets, but otherwise only expose functionality that is otherwise available in a slightly different form for other targets.
l
Is the kotlin.native package part of the stdlib? I'd assumed it was a separate endorsed library.
e
there are several platform-specific parts of stdlib. it's all in the docs.
for example, you can see that https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.system/ is available on JVM and native, but not JS
the colors tell you what's available where
n
Are the K/N parts of the Std lib (kotlin.native, kotlin.native.concurrent, and kotlin.native.ref) OS agnostic (i.e. don't depend on an OS)?
t
They should behave the same on all K/N platforms, if that's what you're asking.
n
Not exactly the answer I was after. Was wanting to know if any parts of the Kotlin Std lib depend on using an OS.
e
that is not relevant to the original topic anyway. if it's in stdlib, it's an external call from the klib regardless of how it's implemented
but just look at the APIs
l
If you're looking to run bare metal, it's going to be far from easy. The OS provides libunwind, libpthread, and several other hard to write libraries.
e
they presume an environment where dynamic memory allocation, atomics, and threads are possible
l
Kotlin 1.6 really only needed libunwind if you used the experimental stms gc, but that's sadly not the case anymore. Until they make a more minimal runtime, you need an OS.
e
do you count whatever supplies that as an OS? eh…
l
It's part of an OS.
e
it's certainly possible to implement those on raw UEFI
whether you count that as an OS or not is a bit arguable
n
Do note that UEFI is only applicable to AMD/Intel based hardware.
l
Ironically it's more than anyone on the OSDev wiki ever does. It's hard to find a reference OS there with libunwind support. They always say to just use a 'real OS' at that point.
e
UEFI is part of ARM BBR as well
n
The libunwind lib is only applicable to CPP.
e
the Kotlin/Native runtime uses C++, and needs some form of tracing over Kotlin frames as well
n
What do you mean about Kotlin frames?
l
The symbols in libunwind are needed for K/N. I tried building a K/N binary for bare metal back in 1.6. I got close, but decided to wait until the new gc was stable.
Frames are part of the ABI. It's basically everything that gets pushed to the stack on a method call.
Return address, params, etc
e
I think it should be possible to replace libunwind with any other backtracer appropriate to the environment. I'm not sure if it can be stubbed out completely…
but that's also not part of the OS (unless you count SEH as part of the OS)
l
Some osdev examples stub out libunwind, but they often use languages where you can disable exceptions. The kotlin team has been very opposed to this idea.
n
In the Kotlin code base there is an option to disable back traces on a per target basis which should get around the libunwind issue.
l
OS is often a hard term to define.
libunwind is also needed for exception support at all, not just getting the trace.
It may be possible to replace libunwind if you rebuild the K/N runtime (or just not use unwinding at all), but the official runtime needs the symbols for it.
Some day when I have time (and can focus on one side project), I'd like to make a more minimal runtime without every feature and try to have the compiler output bitcode, then use llc to compile to binary, but that'd be a lot of work.
n
The libunwind lib appears to be standard across ALL Bare Metal ARM targets in the official ARM GCC toolchain (there are two files: unwind.h & unwind-arm-common.h).
e
libunwind and libgcc unwind are two different things
also there's the one in llvm
n
Some of the K/N targets use a GCC based tool chain (eg the unofficial Zephyr based target - uses the official ARM GCC tool chain ).
By the way the libunwind lib is available for some Bare Metal ARM targets (eg ARMv6-m - https://reviews.llvm.org/D22292?id=63759 ).