Hi, who could help with slow compilation targeting...
# kotlin-native
w
Hi, who could help with slow compilation targeting iOS? Is Kotlin Native just slow when it reached a certain project size? We increased memory and applied all suggestions from the official https://kotlinlang.org/docs/native-improving-compilation-time.html suggestions. But no luck -> zero improvements. We’re now hitting over 50 minutes compile time and that’s a killer for our project. We see most time spend linking iosArm64 and iosX86. While linking CPU limits to only one core with memory consumption of 8GB and clang with peaks at 9 GB. We’re using Kotlin Native as part of a Kotlin Multiplatform project for 1,5 years now. It wasn’t great before but recently upgraded to Kotlin 1.5, Xcode 12.5.1 and Android Studio Arctic Fox and now it’s just painfully slow.
😮 1
c
For me, the solution was splitting my project into different submodules. As I observed, it would rebuild everything from scratch (?) if any part of a module was changed. Separating them lead to simply having to rebuild a certain module instead of all of them
k
The problem with that solution is that symbols from the subprojects do not get exposed in generated frameworks of the parent project which is often a deal breaker for introducing modules.
c
Really? In gtk-kt they did propagate
m
You can call
export
in the framework lambda to export symbols from children modules.
Copy code
ios {
        binaries {
            framework {
                transitiveExport = false
                baseName = "SharedCode"
                export(project(":module1"))
            }
        }
🙏 1
t
You can expose the subprojects symbols, but it does cause a bit of thinking about how to structure because you might end up with times where
public
is intended to mean "usable by another module in the project" vs
public
meaning "useable by someone consuming the library/framework"
k
Thanks, didn’t know about the export(project(...)) syntax, that actually helps a lot! I understand that public will be perhaps too public at times but it is still a big improvement over one large monolithic project.
t
If you need a similar thing for multiplatform, by importing modules as
api
instead of
implementation
it will also expose their public items through
that works for iOS as well IIRC but the exposed values get prefixed with the module name, the explicit export that was posted will make all exposed values looks from the same source
Also to the initial question from @wmontwe, your project might be a lot larger than mine, but another thing I did recently was to enable/disable platforms depending on if we are doing local dev vs releases. Debug builds are much faster and then if you know you're only going to run on the simulator doing just a debug build for iosX86 substantially cut down time
w
Yeah, we started to modularize the project and have one module to glue them back together. Like @mkrussel mentioned
export(project(":module1"))
but the
transitiveExport
is something we never used so far.
m
I don't remember why I put that there.
w
The project is not massive, but it was growing over 1,5 years in complexity. What I noticed is an overall speed loss following XCode versions. My guess is that with every new Swift feature there is a compatibility layer added for objC which is resulting in slower compile time.
Disabling platforms on demand is also an option, we used to do that but switched to SwiftPackages XcFrameworks for easier iOS integration. At the moment we publishing xcframeworks in a central place for reuse to avoid compilation when there was no change in the project. But that doesn’t solve the issue if you’re actively developing a shared feature.