is there a gradle plugin to publish kotlin multipl...
# multiplatform
b
is there a gradle plugin to publish kotlin multiplatform ios framework to CocoaPods?
b
I'm not sure if there is one for production pods yet
but the steps are roughly: 1. generate the framework 2. create a podspec and use the vendored_framework podspec dsl to in your podspec to publish it (https://guides.cocoapods.org/syntax/podspec.html#vendored_frameworks)
a
If I have a KMPP with module A, and module B that depends on module A, what would a Cocoapod publishing setup look like? Would I be better off combining them into project and publishing it as a mega-pod somehow? Or is it possible to publish multiple discrete frameworks with their podspecs pointing to one another as needed?
b
You can publish separately, and then in module B add A’s spec as a dependency
k
I’m assuming this doesn’t “publish”, but there may be some config help here: https://github.com/AlecStrong/kotlin-native-cocoapods
b
Thanks!
o
Support for such publishing should appear in the next eap of 1.3.30
👍 2
s
You can publish separately, and then in module B add A’s spec as a dependency
Having two K/N frameworks in one project is still not possible. So the approach is to compile all Kotlin modules to single framework.
👌 1
o
although note that what will be supported is not just naive .klib -> pod translation, due to the problem Svyatoslav mentioned, instead we can combine multiple kotlin libraries as single pod and use it as a local dependency
🎉 1
b
Oh right. Yep it's a bit more complex. You'll need a wrapper framework in module B that interacts with module A using Obj-C/Swift
a
@svyatoslav.scherbina @olonho thanks for the info! looking forward to the next EAP 😊
Also just curious -- is there a ticket I can follow for further updates/discussion on this?
@olonho Did this make it into https://github.com/JetBrains/kotlin/releases/tag/v1.3.30-eap-45 ? Not sure if I just can't find the right ticket in the release notes
o
a
Interesting! Is there any example using this task? We don't consume any pods from K/N, but still we want to publish our multiple, interdependent K/N modules as a single framework file + podspec to a directory and consume it as a pod. Will this handle the multi-module/single-framework case?
i
Currently there is no example for this task but we are going to port the calculator sample to such an approach soon. Sample: https://github.com/JetBrains/kotlin-native/tree/master/samples/calculator. As for creating a single framework from several K/N modules, yes, such a case is supported. But due to current limitations of the compiler and the gradle plugin you cannot build a framework from klibs only. You still need to have some sources in the Gradle module you build the framework from. We are going to get rid of this limitation eventually.
a
Awesome, I’ll keep an eye out for when this goes stable — just wanted to make sure my use case was something you all knew was in demand 😊 Are lipo/fat frameworks also something that is planned for 1.3.30 stable, or will that have to be manually done like it currently does? Is there an issue that I could follow/voice my support on for that?
s
At least this one: https://youtrack.jetbrains.com/issue/KT-24184 Btw, what platforms do you need fat framework to be built for?
a
Thanks for the link! We currently have a custom task to use
lipo
to make a fat framework from
iosArm32
,
iosArm64
, and
iosX64
(for the simulator) One of the important things we realized in our own custom gradle tasks is that after using
lipo
to merge the framework binaries, we also needed to specifically use the
Info.plist
from the
iosArm32
build. If we didn't, Apple's app thinning could result in having the 32bit framework stripped out (and then crashing on some 32-bit devices).
s
Interesting. Does 64bit framework get stripped out when using
Info.plist
from
iosArm32
?
a
From what I can tell, it doesn’t get stripped out, but I’m not really sure how to confirm.. The Info.plist from the iosArm32 build has arm7 in its UIRequiredDeviceCapabilities, which doesn’t exclude arm64 devices. The iOsArm64 Info.plist has arm64, which does exclude arm7 devices. https://developer.apple.com/library/archive/documentation/DeviceInformation/Reference/iOSDeviceCompatibility/DeviceCompatibilityMatrix/DeviceCompatibilityMatrix.html
(Also more info https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/iPhoneOSKeys.html#//apple_ref/doc/uid/TP40009252-SW3)
armv7
Include this key if your app is compiled only for the armv7 instruction set, or if it’s a 32/64-bit universal app.
Looks like Apple should properly handle the case where we have a universal framework declared with arm7 in the plist!
b
You can use
/usr/libexec/PlistBuddy
to modify the plist in your gradle task, if there are changes you need to make there
a
Yeah, it’s definitely simple to do manually. I just wanted to make sure this was on the Kotlin team’s radar. If they start publicizing built-in fat framework generation but don’t handle this themselves, it’s likely to pose a problem if folks aren’t aware. And it’s one of those horrible problems that doesn’t rear its head until you have an App Store release crashing on real devices, since app thinning doesn’t happen until that far into the cycle.
s
Thank you for sharing your knowledge! Here is what we do to merge `Info.plist`: https://github.com/JetBrains/kotlin/blob/7f08ecee3919f4648a0a1f9254932a269809c680/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/FatFrameworkTask.kt#L270 (so
UIRequiredDeviceCapabilities
key is removed)
a
Nice — it looks like that should be perfectly fine! Modifying plists in our buildscript was more than we were able to take on and we didn’t see a downside to including the armv7 tag, but it’s nice to know that the official solution will take care of it for us 😊
i
We've added a separate sample showing how to use the CocoaPods integration in K/N: https://github.com/JetBrains/kotlin-native/tree/master/samples/cocoapods. Also there is the corresponding doc: https://github.com/JetBrains/kotlin-native/blob/master/COCOAPODS.md
a
Nice! I’ll take a peek at it this week. Is it supported to have multiple interdependent KN modules and build either a single pod that contains them all, or multiple smaller pods that properly depend on each other?
i
Currently it doesn't support building a set of small pods from several K/N modules. But it's possible to build a single framework including several K/N modules (as I mentioned in https://kotlinlang.slack.com/archives/C3PQML5NU/p1552973533287100?thread_ts=1551823451.101400&cid=C3PQML5NU). It will look like this (Kotlin DSL):
Copy code
plugins {
    id("org.jetbrains.kotlin.multiplatform")
    id("org.jetbrains.kotlin.native.cocoapods")
}


kotlin {
    sourceSets["commonMain"].dependencies {
        api(project(":another-module-1"))
        api(project(":another-module-2"))
        // ...
    }

    // Use configure(listOf(<targets>)) if you want to configure some specific targets.
    targets.withType(KotlinNativeTarget::class).all {
        // The CocoaPods plugin has already created both debug and release frameworks.
        val debugFramework = binaries.getFramework("DEBUG")
        val releaseFramework = binaries.getFramework("RELEASE")
        // Export the dependencies in the frameworks.
        configure(listOf(debugFramework, releaseFramework)) {
            export(project(":another-module-1"))
            export(project(":another-module-2"))
            // ...
        }
    }
}