Importing GoogleWebRTC pod fails: module 'GoogleWebRTC' not found - kotlin-multiplatform

I am currently working on a Kotlin multiplatform and am trying to interface with the GoogleWebRTC pod.
The pod exists, I was able to import it in a separate project (without Kotlin multiplatform). I can see the .framework is created in my build directory, however when doing a gradle sync or building from Xcode, I get the following error:
Exception in thread "main" java.lang.Error: /var/folders/hv/9cx28nxx4gz9hj_m86bp5rx40000gn/T/tmp362966650322311128.m:1:9: fatal error: module 'GoogleWebRTC' not found
at org.jetbrains.kotlin.native.interop.indexer.UtilsKt.ensureNoCompileErrors(Utils.kt:152)
at org.jetbrains.kotlin.native.interop.indexer.ModuleSupportKt.getModulesASTFiles(ModuleSupport.kt:67)
at org.jetbrains.kotlin.native.interop.indexer.ModuleSupportKt.getModulesInfo(ModuleSupport.kt:13)
at org.jetbrains.kotlin.native.interop.gen.jvm.MainKt.buildNativeLibrary(main.kt:499)
at org.jetbrains.kotlin.native.interop.gen.jvm.MainKt.processCLib(main.kt:264)
at org.jetbrains.kotlin.native.interop.gen.jvm.MainKt.interop(main.kt:72)
at org.jetbrains.kotlin.cli.utilities.InteropCompilerKt.invokeInterop(InteropCompiler.kt:45)
at org.jetbrains.kotlin.cli.utilities.MainKt.mainImpl(main.kt:19)
at org.jetbrains.kotlin.cli.utilities.MainKt.main(main.kt:37)
Execution failed for task ':shared:cinteropGoogleWebRTCIosArm64'.
> Process 'command '/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java'' finished with non-zero exit value 1
AFNetworking seems to work fine, but adding the WebRTC pod seems to break the project.
Am I missing a limitation of Kotlin multiplatform or something?
This is my build.gradle.kts:
cocoapods {
// Configure fields required by CocoaPods.
summary = "Some description for a Kotlin/Native module"
homepage = "Link to a Kotlin/Native module homepage"
// You can change the name of the produced framework.
// By default, it is the name of the Gradle project.
frameworkName = "shared"
ios.deploymentTarget = "10.0"
pod("GoogleWebRTC", "~> 1.1")
pod("AFNetworking", "~> 4.0.0")
}

I was able to reproduce this issue but I didn't figure out the reason why.
It seems a there's something wrong with GoogleWebRTC pod and the Kotlin-native/cocoapods integration.
I've opened an issue here.
We have an official help.
It seems that the frameworks name is different from the pod name. So a possible solution could be that:
kotlin {
cocoapods {
[...]
pod("GoogleWebRTC", moduleName = "WebRTC", version = "~> 1.1")
[...]
}
[...]
}
I tried it and it works.

Related

Error adding CocoaPods dependency in Kotlin Multiplatform

I'm trying to setup a KMM module with Couchbase Lite as a platform dependency for both Android and iOS. I'm running into errors getting this to work with CocoaPods for iOS:
Exception in thread "main" java.lang.Error: /var/folders/pv/3_5xn0dd0v5bf6sxbfcsq_wr0000gn/T/7009311365357251921.m:1:22: error: expected ';' after module name
at org.jetbrains.kotlin.native.interop.indexer.UtilsKt.ensureNoCompileErrors(Utils.kt:152)
at org.jetbrains.kotlin.native.interop.indexer.ModuleSupportKt.getModulesASTFiles(ModuleSupport.kt:68)
at org.jetbrains.kotlin.native.interop.indexer.ModuleSupportKt.getModulesInfo(ModuleSupport.kt:14)
at org.jetbrains.kotlin.native.interop.gen.jvm.MainKt.buildNativeLibrary(main.kt:507)
at org.jetbrains.kotlin.native.interop.gen.jvm.MainKt.processCLib(main.kt:265)
at org.jetbrains.kotlin.native.interop.gen.jvm.MainKt.interop(main.kt:73)
at org.jetbrains.kotlin.cli.utilities.InteropCompilerKt.invokeInterop(InteropCompiler.kt:45)
at org.jetbrains.kotlin.cli.utilities.MainKt.mainImpl(main.kt:19)
at org.jetbrains.kotlin.cli.utilities.MainKt.main(main.kt:41)
The generated 7009311365357251921.m file is not present at that path afterwards, which makes this difficult to debug.
build.gradle.kts:
plugins {
kotlin("multiplatform") version "1.4.21"
kotlin("native.cocoapods") version "1.4.21"
id("com.android.library")
}
...
kotlin {
android()
ios()
cocoapods {
summary = "TBD"
homepage = "TBD"
ios.deploymentTarget = "9.0"
pod("CouchbaseLite-Enterprise") {
version = "~> 2.8.1"
}
}
...
}
...
I get a different error if I use the non-enterprise release. Same build.gradle.kts except with pod("CouchbaseLite"). I get the error:
Exception in thread "main" java.lang.IllegalArgumentException: 'CBLQueryMeta' is going to be declared twice
at org.jetbrains.kotlin.native.interop.gen.KotlinFile.<init>(KotlinCodeModel.kt:257)
at org.jetbrains.kotlin.native.interop.gen.StubIrBridgeBuilder$kotlinFile$1.<init>(StubIrBridgeBuilder.kt:44)
at org.jetbrains.kotlin.native.interop.gen.StubIrBridgeBuilder.<init>(StubIrBridgeBuilder.kt:46)
at org.jetbrains.kotlin.native.interop.gen.StubIrDriver.run(StubIrDriver.kt:122)
at org.jetbrains.kotlin.native.interop.gen.jvm.MainKt.processCLib(main.kt:315)
at org.jetbrains.kotlin.native.interop.gen.jvm.MainKt.interop(main.kt:73)
at org.jetbrains.kotlin.cli.utilities.InteropCompilerKt.invokeInterop(InteropCompiler.kt:45)
at org.jetbrains.kotlin.cli.utilities.MainKt.mainImpl(main.kt:19)
at org.jetbrains.kotlin.cli.utilities.MainKt.main(main.kt:41)
Both these pod specs compile without problem in an Xcode project. But Kotlin native seems to run into issues with them.
Update:
The pod("CouchbaseLite") error seems to be caused by having both a CBLQueryMeta and CBLQuery interface defined. There's a YouTrack issue for this. This error will likely still be a problem with CouchbaseLite-Enterprise, if the original error could be resolved.
Update 2:
If I remove the { version = "~> 2.8.1" } or put it in the function call directly pod("CouchbaseLite-Enterprise", "~> 2.8.1") I get a different error:
Exception in thread "main" java.lang.Error: /var/folders/pv/3_5xn0dd0v5bf6sxbfcsq_wr0000gn/T/6649487835163649080.m:1:9: fatal error: module 'CouchbaseLite_Enterprise' not found
at org.jetbrains.kotlin.native.interop.indexer.UtilsKt.ensureNoCompileErrors(Utils.kt:152)
at org.jetbrains.kotlin.native.interop.indexer.ModuleSupportKt.getModulesASTFiles(ModuleSupport.kt:68)
at org.jetbrains.kotlin.native.interop.indexer.ModuleSupportKt.getModulesInfo(ModuleSupport.kt:14)
at org.jetbrains.kotlin.native.interop.gen.jvm.MainKt.buildNativeLibrary(main.kt:507)
at org.jetbrains.kotlin.native.interop.gen.jvm.MainKt.processCLib(main.kt:265)
at org.jetbrains.kotlin.native.interop.gen.jvm.MainKt.interop(main.kt:73)
at org.jetbrains.kotlin.cli.utilities.InteropCompilerKt.invokeInterop(InteropCompiler.kt:45)
at org.jetbrains.kotlin.cli.utilities.MainKt.mainImpl(main.kt:19)
at org.jetbrains.kotlin.cli.utilities.MainKt.main(main.kt:41)
Update 3:
I filed a YouTrack issue for this. It seems this might have something to do with the dash - in the CocoaPod library name. There was an issue that's been closed that had a fix for this by changing the module name to replace the dash - with an underscore _, but the fix doesn't seem to be working.
Depending on which version of the toolchain you're using, seems as if you're using the wrong syntax to specify the version. Try pod("CouchbaseLite-Enterprise", "~> 2.8.1") instead.

Testing rx throws error on scheduler init

Unit test terminates if I write var scheduler = TestScheduler(initialClock: 0)
my imports
import XCTest
import RxTest
with error message
failed to demangle superclass of TestScheduler from mangled name '7RxSwift20VirtualTimeSchedulerCy0A4Test0fecD9ConverterVG'
pod versions
pod 'RxBlocking', '~> 5'
pod 'RxTest', '~> 5'
This is a bug of the Cocoapods + XCode 10.2 platform.
Statement from XCode 10.2 RC notes about known issues:
Linking against a static Swift library might create a binary with missing
type metadata because the object files that define the metadata inside the
static archive are mistakenly considered unused. (47598583)
This can manifest as a Swift runtime error with a message such as:
“failed to demangle superclass of MyClass from mangled name ‘<mangled name>’”.
Workaround: If you can rebuild the static library, try building it with whole module
optimization enabled.
Otherwise, add -all_load to the linker flags in the client binary to
ensure all object files are linked into it.
This thread and this solution should help you get rid of it.

Private Swift Pod with ObjC static libraries

I am trying to create a private pod that ships with two static libraries.
Source of the pod is in swift however it depends upon two third party static libraries on which I have no control.
Linting my podspec, I get the following error just for the second lib (with a modulemap)
- ERROR | [iOS] xcodebuild: Returned an unsuccessful exit code. You can use `--verbose` for more information.
- ERROR | xcodebuild: TestKit/TestKit/SSAIPolicy.swift:11:8: error: no such module 'SecondLib'
And, here is the source part of my podspec file:
spec.source_files = 'TestKit/*', 'Vendor/**/*.{h,modulemap}'
spec.vendored_libraries = 'Vendor/FirstLib/libService.a', 'Vendor/SecondLib/libManagement.a'
spec.pod_target_xcconfig = { 'OTHER_LDFLAGS' => '-ObjC' }
Note: I am able to use this framework just fine by compiling and dropping it manually in the main app
In case anyone needs to know, I got it working by changing 'Target Membership'
of header files in my library from 'Project' to 'Public'

CocoaPods project depend on a local static C library

I have locally built C library (.h and .a files) that I want to include in a Swift-based CocoaPods pod. How do I configure the podspec to depend on the .a files and the module.map? With a normal non-CocoaPods Xcode project, I simply drag in the directory that contains include and lib and then add a module.map. With CocoaPods I can't do this because pod install will overwrite the Xcode project file. s.library won't work because the the static library isn't hosted anywhere. I tried s.vendored_libraries but module.map still remains unknown to Xcode, the end result being that import foo from my Swift files is an error.
Edit: I tried using preserve_paths, vendored_libraries and xcconfig as answered here. The issue is still how to import the module from Swift.
Edit 2: I also tried using module_map to point to my module.map file as documented here, but sadly CocoaPods 1.1.1 crashes ([!] Oh no, an error occurred.).
I got it working. In my case I'm depending the libtiff C library which is prebuilt for iOS (x86 and arm) using https://github.com/ashtons/libtiff-ios.
I used a subspec as outline here. Here's the podspec subspec snippet, assuming the static library lives at libtiff off the root of the pod module.
s.subspec 'libtiff' do |libtiff|
libtiff.source_files = 'libtiff/include/*.h'
libtiff.public_header_files = 'libtiff/include/*.h'
libtiff.preserve_paths = 'libtiff/include/*.h'
libtiff.vendored_libraries = 'libtiff/lib/libjpeg.a', 'libtiff/lib/libpng.a', 'libtiff/lib/libtiff.a', 'libtiff/lib/libtiffxx.a'
libtiff.xcconfig = { 'HEADER_SEARCH_PATHS' => "${PODS_ROOT}/#{s.name}/libtiff/include/**" }
# you can't specify "libz" here, must specify "z", see https://github.com/CocoaPods/CocoaPods/issues/3232
libtiff.library = 'z'
end

pod spec lint error: "unexpected '#' in program"

I am creating a podspec file for an open-source project I created, and I am utilizing Apple's UIImage+ImageEffects.h/.m for a blur effect, and inside there, they use the new #import Accelerate; syntax versus #import <Accelerate/Accelerate.h>. When I run pod spec lint SFSCollectionMenu.podspec, I receive the error:
ERROR | [xcodebuild] SFSCollectionMenu/UIImage+ImageEffects.h:96:1: error: unexpected '#' in program
Does the CocoaPods platform not like the new modules syntax? I'm relatively new to CocoaPods so there very well could be something I'm missing. I followed Nils Hayat's blog for creating a simple pod (which fit my scenario perfectly -- nothing outlandish), http://nilsou.com/blog/2013/07/21/how-to-open-source-objective-c-code/, and receive this error in his section about verifying the pod via lint.
Here's relevant lines from podspec file:
s.source_files = 'SFSCollectionMenuController.*{h,m}', 'SFSCircleLayout.*{h,m}', 'SFSMenuCell.*{h,m}', 'UIImage+ImageEffects.*{h,m}'
s.frameworks = 'Accelerate', 'QuartzCore', 'AVFoundation'
Thank you for any help!
I don't think Modules are turned on by default in Xcode, can you test whether adding spec.compiler_flags = "-fmodules" to turn on modules in your generated library fixes this?

Resources