Hey there, im asking myself if there is a possibil...
# kotlin-native
j
Hey there, im asking myself if there is a possibility to compile kotlin to objectiv c on linux instead of on macos? So far i did not find any documentation about changing the compiler from c/cpp to objc on the linux target. Is this even possible?
b
No, apple stuff can only be compiled on apple hardware, unfortunately. Might I suggest using gh actions macos runner for that if you don't gave access to apple hardware?
j
The idea is not to cross compile on linux for apple, the idea is to use objective as framework and compile on linux a lib for linux
b
Even so, you need apple hardware. I know that it's possible to cross compile objc and swift, but sadly kotlin native does not support that.
j
thats what i was trying to get to know. thanks
So there is also no option to force to build the objc files?
b
Not that I'm aware of, but I'm not an expert in K/N. @kpgalligan might know one if it exists afterall.
Out of curiosity, why are you so set on using objc for Linux?
j
im searching for a way to use native libs on linux, mac and windows and use suspend fun on each platform
wasm is not an option to compile to as the libs i have as depenencies do not support that. JS is no a good option. native to c / cpp does not support suspend funcs
thats why i try to see if there is an option to use objc on all platforms
b
One option could be to expose non-suspend functions to c that invoke suspensions on its behalf
j
yes indeed. i could wrap all the funcs into runBlocking and throw a naming convention on them, that would at least export them in the lib / header files
b
Not saying it would be pretty nor pleasant šŸ˜€
j
but im afraid / unsure of the performance impact if i remove all the threading and multiprocessing and do all the io bound stuff sync
b
You can avoid runBlocking by having a dedicated custom coroutine scope for these functions to use
j
basically im tryng to get all the options onto the table to make a profound decision on which route to go. The objc option is still open
not sure if that would work, as no suspend function is exported in the native shared or static lib
b
I'm not sure how concurrency works in c, but since coroutines are just a callback loop, you might be able to wrap c concurrency primitives into coroutines via suspendingFunction{}
not sure if that would work, as no suspend function is exported in the native shared or static lib
You write non_suspend kotlin functions that enter suspend scope via that custom scope and invoke appropriate fun on c behalf
j
to use the function at all they are not allowed to be suspend func
yes. isnt that what runBlocking essentially does?
b
You then return a wrapper to whatever c uses for async/deferred values
No, run blocking blocks until the value is ready. I'm suggesting to return some deferred c value if it has something like that (not familiar with c concurrency so I'm just guessing here)
Basically c equivalent to Promise in js
j
i guess if that would be possible kotlin lang would have done it šŸ˜›
b
Surely c must have something for concurrency
k
im searching for a way to use native libs on linux, mac and windows and use suspend fun on each platform
We don’t use the suspend functions on Objc. In fact, I’m going to push for a way to suppress generating them. They aren’t really ā€œsuspendā€ functions. They also wrap the suspend calls with a callback mechanism, but it’s done by the compiler rather than you. If they work with Swift async/await, its because they conform to a specific convention, but they aren’t, strictly speaking, ā€œsuspend functionsā€. We generate our own interface, or suggest https://github.com/rickclephas/KMP-NativeCoroutines. That won’t work in your case, as I assume https://github.com/rickclephas/KMP-NativeCoroutines doesn’t support linux C output (correct me if I’m wrong @Rick Clephas)
We don’t use the suspend for objc because you can’t control the lifecycle, and there are other restrictions (need to call on the main thread, can’t do Flow regardless). Once you get past the boilerplate, controlling your own interface is better (IMO)
Having said all that, you can compile objc on linux (I believe), but the Kotlin compiler only offers objc for Framework output, and that’s very much tied to Apple/Darwin platforms unfortunately. I was hacking around trying to build a static lib, then see if we could use objc headers, but you simply can’t.
So, summary, since the objc is just callbacks, you should just do the same with the C that’s output for Linux. As there’s less Linux support for these kinds of libraries, you’ll need to do that yourself, but It’s not super complicated. I was going to post an example, but our sample app seems to have grown more layers, so I’d need to find a simpler one…
j
that would be great. i;d love to see a small sample to get a grasp on it
thanks for all the deep insights which would take some days for me to get my head around
r
Correct currently KMP-NativeCoroutines won’t do anything on a linux target (only on Apple targets). However the code generation is all Kotlin, so it could easily be enabled for other targets as well. The only thing needed for that would be another way to map `Exception`s (which are currently mapped to `NSError`s).
In fact, I’m going to push for a way to suppress generating them.
I have actually been working on that (for ObjC/Swift): https://github.com/JetBrains/kotlin/pull/4818
šŸ¤” 1
j
interesting will take a look
k
That PR definitely looks interesting. Will dive in. Reading it is giving me flashbacks: https://github.com/JetBrains/kotlin-native/pull/2850
The concept is interesting. I’d also like to be able to pass a compiler arg that basically suppresses all suspend call generation, but an annotation will work as well, and will allow us to be more precise. We’re currently going deep on Swift code generation and renaming/removing methods from the interface was on the roadmap if possible.
r
Compiler arg would also be nice indeed! For now I focused on the annotation as it will help with more use cases/limitations (and I kind of want the annotation for KMP-NativeCoroutines šŸ™ˆ).
k
Not exactly related, but I want to get the name map out of the compiler and/or be able to control names rather than the auto-mangling that happens for name collisions. Anyway, pretty interesting. Swift private with
__
is new to me, but that’s great.
I’m giving a talk about this soon. Just gave one that was less detailed. Essentially efforts to shape the api surface. Not being able to selectively remove methods has been a real pain point.
r
Cool! Any more details about that talk? Like where and when 😁
k
That’s cool! We started talking about some of this stuff a few years ago, but adding annotations to Kotlin seemed like it would be rather rare. Controlling the name is great.
For Swift gen, we really need a way to pull the names out too, but that’s a whole different discussion.
r
Ah you mean a predictable way to know the Swift name of a Kotlin declaration from a compiler plugin or something?
About the mangling. I guess there should be a compiler arg to make any mangling an error (as soon as you can controle the names of course).
šŸ¤” 1
k
Yeah, so if we generate swift code, what’s the Swift name of the Kotlin thing. Obviously its usually the same, but not for dependencies (unless you export them, which is a whole different discussion), and not if you have name collisions. Being able to override specific classes is good, as you can work around the naming collisions.
šŸ‘šŸ» 1
For now, our plan is to just provide a way to config those names if they don’t align. We’re still sort of in the ā€œexploreā€ phase on Swift code gen. I can see where it might be useful, but I want to get feedback from folks doing it before we jump in with both feet. Trying to poke a hole into the compiler to pull that map, or have the compiler write that map, etc, is a bigger change, so for now it’s more of a hard-coded workaround.
Mangling as an error definitely makes sense to me.
r
Got it! Yeah let me know if you have any thought on those PRs.
k
We’re all poking around them now…
On the talk, the short version I gave was more complaining about the problem, longer version will be Droidcon Berlin (if it’s accepted). I was about to tweet about the difficulty of writing talks on topics that are actively changing, and your PRs are an example šŸ™‚ Part of my recent talk was about compromises in Kermit to support a better Swift api, but after the talk I basically rewrote it (https://github.com/touchlab/Kermit/tree/kpg/api_reformat2), and if we can figure out the Swift gen (with klibs in the middle), then everything from that talk will be old news, and I only gave it a few weeks ago.
I have to find something to talk about now that the memory model has changed…
šŸ˜‚ 1