Closed brettwillis closed 6 years ago
Currently the main priority is native support in the new multiplatform plugin (see https://youtrack.jetbrains.com/issue/KT-23930. Samples and some documentation: https://github.com/h0tk3y/k-new-mpp-samples) and the cinterop DSL will be introduced there first soon.
Yes, you can add an interop klib as a file dependency:
dependencies {
implementation files('path/to/the/klib')
}
Please consider possibility in new DSL that cinterop can be combined with custom Kotlin code - sometimes it is convenient to add additional wrappers.
For now I have to create two .klib
s, and assign two names - for example libui.klib
for cinterop, and libui-ktx.klib
for my wrappers.
Yes, you can add an interop klib as a file dependency:
dependencies { implementation files('path/to/the/klib') }
Hi @ilmat192, thank you for the info. In my case I'm creating interop for Firebase libraries using konan
interop(...)
. I successfully generate the interop klib, called Firebase.klib
, which of course has multiple variants (ios_x64
, ios_arm32
, ios_arm64
).
The .def file is as below:
depends = Foundation SystemConfiguration Security MobileCoreServices
headers = FirebaseCore/FirebaseCore.h FirebaseAuth/FirebaseAuth.h FirebaseFirestore/FirebaseFirestore.h FirebaseRemoteConfig/FirebaseRemoteConfig.h FirebaseMessaging/FirebaseMessaging.h
headerFilter = FirebaseCore/** FirebaseAuth/** FirebaseFirestore/** FirebaseRemoteConfig/** FirebaseMessaging/**
language = Objective-C
linkerOpts = -framework FirebaseCore -framework FirebaseAuth -framework FirebaseInstanceID -framework FirebaseAnalytics -framework FirebaseNanoPB -framework FirebaseCoreDiagnostics -framework FirebaseABTesting -framework ProtoRPC -framework grpc -framework openssl -framework leveldb -framework Protobuf -framework GoogleToolboxForMac -framework nanopb -framework GRPCClient -framework GTMSessionFetcher -framework UIKit
compilerOpts = -framework FirebaseCore -framework FirebaseAuth -framework FirebaseFirestore -framework FirebaseRemoteConfig -framework FirebaseMessaging
Specifying the implementation files('path/to/Firebase.klib')
dependency results in a build error like exception: java.lang.IllegalStateException: Could not find "Firebase" in <search paths...>
.
Firebase.klib
variants for different kotlin-platform-native
build variants (ios_x64
, ios_arm32
, ios_arm64
)?-i
flag and provide a link to the build log? It contains info about a compiler command line along with all libraries passed to it.
import org.jetbrains.kotlin.gradle.plugin.experimental.*
components.withType(KotlinNativeBinary) { dependencies { def target = konanTarget.name implementation files("path/to/${target}.klib") } }
Here `konanTarget.name` returns a string containing a platform name (e.g. `macos_x64` or `linux_x64`).
My apologies, the Could not find "Firebase"
error was because the path/to/klib
was wrong. I thought I double checked, but nevertheless I missed it!!
That is extremely helpful, that part seems to work well, thank you.
Now I get an error ld: framework not found FirebaseCore
. This is obviously because the Firebase frameworks that were linked into Firebase.klib
are not on the search path of the kotlin-platform-native
build. I've had a few attempts at providing a search path using the extraOpts
property on the main component, but I can't get it right. Do you know how to provide framework search paths to konanc
using the kotlin-platform-native
plugin?
linkerOpts
from konan
is not available on a kotlin-platform-native
component as far as I can tell?
Neither of below work
extraOpts "-F/path/to/frrameworks"
- Error: invalid argumentextraOpts "-linkerOpts -F/path/to/frameworks"
- Error: invalid argumentlinkerOpts from konan is not available on a kotlin-platform-native component as far as I can tell?
Yes, it's right.
Try to separate the args: extraOpts "-linkerOpts", "-F/path/to/frameworks"
. The extraOpts
option accepts a sequence of strings and passes each of them to the compiler as a separate command line option.
Hi @ilmat192 sorry for the delay, that worked, but now I have another error. I ended up needing to link all sorts of dependencies as below before the linker could progress. Gosh! I hope there will be a better way in the future!
def frameworksDir = new File("interop/Frameworks").absolutePath
sourceSets {
main {
component {
target 'ios_arm32', 'ios_arm64', 'ios_x64'
outputKinds = [FRAMEWORK]
extraOpts "-linkerOpts", "-F${frameworksDir}"
extraOpts "-linkerOpts", "-framework FirebaseFirestore"
extraOpts "-linkerOpts", "-framework FirebaseRemoteConfig"
extraOpts "-linkerOpts", "-framework FirebaseMessaging"
extraOpts "-linkerOpts", "-framework FirebaseInstanceID"
extraOpts "-linkerOpts", "-framework FirebaseAuth"
extraOpts "-linkerOpts", "-framework FirebaseAnalytics"
extraOpts "-linkerOpts", "-framework FirebaseNanoPB"
extraOpts "-linkerOpts", "-framework FirebaseCoreDiagnostics"
extraOpts "-linkerOpts", "-framework FirebaseABTesting"
extraOpts "-linkerOpts", "-framework FirebaseCore"
extraOpts "-linkerOpts", "-framework CoreGraphics"
extraOpts "-linkerOpts", "-framework Security"
extraOpts "-linkerOpts", "-framework SystemConfiguration"
extraOpts "-linkerOpts", "-framework MobileCoreServices"
extraOpts "-linkerOpts", "-framework SafariServices"
extraOpts "-linkerOpts", "-framework StoreKit"
extraOpts "-linkerOpts", "-framework grpc"
extraOpts "-linkerOpts", "-framework GRPCClient"
extraOpts "-linkerOpts", "-framework GTMSessionFetcher"
extraOpts "-linkerOpts", "-framework nanopb"
extraOpts "-linkerOpts", "-framework GoogleToolboxForMac"
extraOpts "-linkerOpts", "-framework Protobuf"
extraOpts "-linkerOpts", "-framework leveldb"
extraOpts "-linkerOpts", "-framework openssl"
extraOpts "-linkerOpts", "-framework ProtoRPC"
extraOpts "-linkerOpts", "-framework RxLibrary"
extraOpts "-linkerOpts", "-lsqlite3"
}
}
}
dependencies {
expectedBy project(':common:common')
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core-native:$coroutines_version"
}
import org.jetbrains.kotlin.gradle.plugin.experimental.*
components.withType(KotlinNativeBinary) {
def target = konanTarget.name
dependencies {
implementation files("interop/build/konan/libs/${target}/Firebase.klib")
}
}
That's great, HOWEVER, now I get the next error error: compilation failed: /targets/ios_x64/kotlin
, with the -info
output as below:
> Task :ios:common:checkKonanCompiler
Task ':ios:common:checkKonanCompiler' is not up-to-date because:
Task has not declared any outputs despite executing actions.
Downloading Kotlin/Native compiler from https://download.jetbrains.com/kotlin/native/builds/dev/0.9-dev-2922/macos/kotlin-native-macos-0.9-dev-2922 into /Users/brettwillis/.konan
:ios:common:checkKonanCompiler (Thread[Task worker for ':' Thread 6,5,main]) completed. Took 0.056 secs.
:ios:common:compileDebugIos_x64KotlinNative (Thread[Task worker for ':' Thread 6,5,main]) started.
> Task :ios:common:compileDebugIos_x64KotlinNative
Task ':ios:common:compileDebugIos_x64KotlinNative' is not up-to-date because:
Task has failed previously.
Run tool: konanc with args: -o /Users/brettwillis/code/project-name/ios/common/build/lib/main/debug/ios_x64/common.framework -g -ea -target ios_x64 -p framework -Xmulti-platform -linkerOpts -F/Users/brettwillis/code/project-name/ios/common/interop/Frameworks -linkerOpts -framework CoreGraphics -linkerOpts -framework Security -linkerOpts -framework SystemConfiguration -linkerOpts -framework MobileCoreServices -linkerOpts -framework SafariServices -linkerOpts -framework FirebaseFirestore -linkerOpts -framework grpc -linkerOpts -framework GRPCClient -linkerOpts -framework GTMSessionFetcher -linkerOpts -framework nanopb -linkerOpts -framework GoogleToolboxForMac -linkerOpts -framework Protobuf -linkerOpts -framework leveldb -linkerOpts -framework openssl -linkerOpts -framework ProtoRPC -linkerOpts -framework RxLibrary -linkerOpts -framework FirebaseRemoteConfig -linkerOpts -framework FirebaseMessaging -linkerOpts -framework FirebaseInstanceID -linkerOpts -framework FirebaseAuth -linkerOpts -framework FirebaseAnalytics -linkerOpts -framework FirebaseNanoPB -linkerOpts -framework FirebaseCoreDiagnostics -linkerOpts -framework FirebaseABTesting -linkerOpts -framework FirebaseCore -linkerOpts -lsqlite3 -linkerOpts -framework StoreKit -r /Users/brettwillis/code/project-name/ios/common/interop/build/konan/libs/ios_arm32 -l Firebase -r /Users/brettwillis/code/project-name/ios/common/interop/build/konan/libs/ios_arm64 -l Firebase -r /Users/brettwillis/code/project-name/ios/common/interop/build/konan/libs/ios_x64 -l Firebase -r /Users/brettwillis/code/project-name/ios/common/interop/build/konan/libs/macos_x64 -l Firebase -r /Users/brettwillis/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlinx/kotlinx-coroutines-core-native_debug_ios_x64/0.24.0/73ce04d13c47dfafa6857a1f523073d2d6bbc3ce -l kotlinx-coroutines-core-native -r /Users/brettwillis/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlinx/atomicfu-native_debug_ios_x64/0.11.0/f3e521a0ec75e6a2035c639b763177dfcbf15652 -l atomicfu-native ...
Starting process 'command '/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java''. Working directory: /Users/brettwillis/code/project-name/ios/common Command: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java -DCVS_PASSFILE=~/.cvspass -D__idea.mac.env.lock=unlocked -Dapple.laf.useScreenMenuBar=true -Dawt.toolkit=sun.lwawt.macosx.LWCToolkit -Dcom.apple.mrj.application.live-resize=false -Dfile.encoding.pkg=sun.io -Dfile.separator=/ -Dftp.nonProxyHosts=local|*.local|169.254/16|*.169.254/16 -DgopherProxySet=false -Dhttp.nonProxyHosts=local|*.local|169.254/16|*.169.254/16 -Dide.new.welcome.screen.force=true -Didea.cycle.buffer.size=1024 -Didea.dynamic.classpath=false -Didea.executable=studio -Didea.fatal.error.notification=disabled -Didea.home.path=/Applications/Android Studio.app/Contents -Didea.java.redist=Bundled -Didea.jre.check=true -Didea.max.content.load.filesize=20000 -Didea.max.intellisense.filesize=2500 -Didea.no.launcher=false -Didea.paths.selector=AndroidStudio3.1 -Didea.platform.prefix=AndroidStudio -Didea.popup.weight=heavy -Didea.smooth.progress=false -Didea.xdebug.key=-Xdebug -Dio.netty.machineId=28:f0:76:ff:fe:16:65:0e -Dio.netty.processId=47830 -Dio.netty.serviceThreadPrefix=Netty -Djava.awt.graphicsenv=sun.awt.CGraphicsEnvironment -Djava.awt.headless=true -Djava.awt.printerjob=sun.lwawt.macosx.CPrinterJob -Djava.class.path=/Users/brettwillis/.gradle/wrapper/dists/gradle-4.7-all/4cret0dgl5o3b21weaoncl7ys/gradle-4.7/lib/gradle-launcher-4.7.jar -Djava.class.version=52.0 -Djava.endorsed.dirs=/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/jre/lib/endorsed -Djava.ext.dirs=/Users/brettwillis/Library/Java/Extensions:/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/jre/lib/ext:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java -Djava.home=/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/jre -Djava.library.path=/Users/brettwillis/.konan/kotlin-native-macos-0.9-dev-2922/konan/nativelib -Djava.net.preferIPv4Stack=true -Djava.rmi.server.disableHttp=true -Djava.rmi.server.hostname=localhost -Djava.runtime.name=OpenJDK Runtime Environment -Djava.runtime.version=1.8.0_152-release-1024-b01 -Djava.specification.name=Java Platform API Specification -Djava.specification.vendor=Oracle Corporation -Djava.specification.version=1.8 -Djava.util.concurrent.ForkJoinPool.common.threadFactory=com.intellij.concurrency.IdeaForkJoinWorkerThreadFactory -Djava.vendor=JetBrains s.r.o -Djava.vendor.url=https://www.jetbrains.com/ -Djava.vendor.url.bug=https://youtrack.jetbrains.com -Djava.version=1.8.0_152-release -Djava.vm.info=mixed mode -Djava.vm.name=OpenJDK 64-Bit Server VM -Djava.vm.specification.name=Java Virtual Machine Specification -Djava.vm.specification.vendor=Oracle Corporation -Djava.vm.specification.version=1.8 -Djava.vm.vendor=JetBrains s.r.o -Djava.vm.version=25.152-b01 -Djavax.swing.rebaseCssSizeMap=true -Djb.vmOptionsFile=/Applications/Android Studio.app/Contents/bin/studio.vmoptions -Djna.boot.library.path -Djna.encoding=UTF8 -Djna.loaded=true -Djna.nosys=true -Djna.platform.library.path=/usr/lib:/usr/lib -Djna.tmpdir=/Users/brettwillis/Library/Caches/AndroidStudio3.1/tmp -Djnidispatch.path=/Users/brettwillis/Library/Caches/AndroidStudio3.1/tmp/jna8612810209034690672.tmp -Dkonan.home=/Users/brettwillis/.konan/kotlin-native-macos-0.9-dev-2922 -Dkotlin.environment.keepalive=true -Dlibrary.jansi.path=/Users/brettwillis/.gradle/native/jansi/1.14/osx -Dline.separator=
-Dlog4j.defaultInitOverride=true -Dos.arch=x86_64 -Dos.name=Mac OS X -Dos.version=10.13.6 -Dpath.separator=: -DsocksNonProxyHosts=local|*.local|169.254/16|*.169.254/16 -Dstudio.record.file=/Users/brettwillis/Library/Caches/AndroidStudio3.1/tmp/AndroidStudio.865c1433-99fa-43ba-833d-c417064228dd -Dsun.arch.data.model=64 -Dsun.boot.class.path=/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/jre/lib/resources.jar:/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/jre/lib/rt.jar:/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/jre/lib/sunrsasign.jar:/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/jre/lib/jsse.jar:/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/jre/lib/jce.jar:/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/jre/lib/charsets.jar:/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/jre/lib/jfr.jar:/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/jre/classes -Dsun.boot.library.path=/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/jre/lib -Dsun.cpu.endian=little -Dsun.cpu.isalist -Dsun.io.unicode.encoding=UnicodeBig -Dsun.java.command=org.gradle.launcher.daemon.bootstrap.GradleDaemon 4.7 -Dsun.java.launcher=SUN_STANDARD -Dsun.jnu.encoding=UTF-8 -Dsun.management.compiler=HotSpot 64-Bit Tiered Compilers -Dsun.os.patch.level=unknown -Dswing.bufferPerWindow=true -Duser.dir=/Users/brettwillis/code/project-name/ios/common -Duser.home=/Users/brettwillis -Duser.name=brettwillis -Duser.timezone=Pacific/Auckland -Xmx3G -Dfile.encoding=UTF-8 -Djava.io.tmpdir=/var/folders/lj/jb9r_w_n6hq60g8yjf1h62b40000gn/T/ -Duser.country=NZ -Duser.language=en -Duser.variant -ea -cp /Users/brettwillis/.konan/kotlin-native-macos-0.9-dev-2922/konan/lib/kotlin-stdlib.jar:/Users/brettwillis/.konan/kotlin-native-macos-0.9-dev-2922/konan/lib/klib.jar:/Users/brettwillis/.konan/kotlin-native-macos-0.9-dev-2922/konan/lib/Runtime.jar:/Users/brettwillis/.konan/kotlin-native-macos-0.9-dev-2922/konan/lib/protobuf-java-2.6.1.jar:/Users/brettwillis/.konan/kotlin-native-macos-0.9-dev-2922/konan/lib/shared.jar:/Users/brettwillis/.konan/kotlin-native-macos-0.9-dev-2922/konan/lib/kotlin-script-runtime.jar:/Users/brettwillis/.konan/kotlin-native-macos-0.9-dev-2922/konan/lib/kotlin-compiler.jar:/Users/brettwillis/.konan/kotlin-native-macos-0.9-dev-2922/konan/lib/kotlin-reflect.jar:/Users/brettwillis/.konan/kotlin-native-macos-0.9-dev-2922/konan/lib/utilities.jar:/Users/brettwillis/.konan/kotlin-native-macos-0.9-dev-2922/konan/lib/backend.native.jar:/Users/brettwillis/.konan/kotlin-native-macos-0.9-dev-2922/konan/lib/StubGenerator.jar:/Users/brettwillis/.konan/kotlin-native-macos-0.9-dev-2922/konan/lib/Indexer.jar org.jetbrains.kotlin.cli.utilities.MainKt konanc -o /Users/brettwillis/code/project-name/ios/common/build/lib/main/debug/ios_x64/common.framework -g -ea -target ios_x64 -p framework -Xmulti-platform -linkerOpts -F/Users/brettwillis/code/project-name/ios/common/interop/Frameworks -linkerOpts -framework CoreGraphics -linkerOpts -framework Security -linkerOpts -framework SystemConfiguration -linkerOpts -framework MobileCoreServices -linkerOpts -framework SafariServices -linkerOpts -framework FirebaseFirestore -linkerOpts -framework grpc -linkerOpts -framework GRPCClient -linkerOpts -framework GTMSessionFetcher -linkerOpts -framework nanopb -linkerOpts -framework GoogleToolboxForMac -linkerOpts -framework Protobuf -linkerOpts -framework leveldb -linkerOpts -framework openssl -linkerOpts -framework ProtoRPC -linkerOpts -framework RxLibrary -linkerOpts -framework FirebaseRemoteConfig -linkerOpts -framework FirebaseMessaging -linkerOpts -framework FirebaseInstanceID -linkerOpts -framework FirebaseAuth -linkerOpts -framework FirebaseAnalytics -linkerOpts -framework FirebaseNanoPB -linkerOpts -framework FirebaseCoreDiagnostics -linkerOpts -framework FirebaseABTesting -linkerOpts -framework FirebaseCore -linkerOpts -lsqlite3 -linkerOpts -framework StoreKit -r /Users/brettwillis/code/project-name/ios/common/interop/build/konan/libs/ios_arm32 -l Firebase -r /Users/brettwillis/code/project-name/ios/common/interop/build/konan/libs/ios_arm64 -l Firebase -r /Users/brettwillis/code/project-name/ios/common/interop/build/konan/libs/ios_x64 -l Firebase -r /Users/brettwillis/code/project-name/ios/common/interop/build/konan/libs/macos_x64 -l Firebase -r /Users/brettwillis/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlinx/kotlinx-coroutines-core-native_debug_ios_x64/0.24.0/73ce04d13c47dfafa6857a1f523073d2d6bbc3ce -l kotlinx-coroutines-core-native -r /Users/brettwillis/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlinx/atomicfu-native_debug_ios_x64/0.11.0/f3e521a0ec75e6a2035c639b763177dfcbf15652 -l atomicfu-native ...
Successfully started process 'command '/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java''
warning: library included more than once: /Users/brettwillis/code/project-name/ios/common/interop/build/konan/libs/ios_arm32/Firebase.klib
error: compilation failed: /targets/ios_x64/kotlin
* Source files: ...
* Compiler version info: Konan: 0.9-dev-2922 / Kotlin: 1.2.70
* Output kind: FRAMEWORK
exception: java.nio.file.NoSuchFileException: /targets/ios_x64/kotlin
at com.sun.nio.zipfs.ZipPath.getAttributes(ZipPath.java:666)
at com.sun.nio.zipfs.ZipFileSystemProvider.readAttributes(ZipFileSystemProvider.java:294)
at java.nio.file.Files.readAttributes(Files.java:1737)
at java.nio.file.FileTreeWalker.getAttributes(FileTreeWalker.java:219)
at java.nio.file.FileTreeWalker.visit(FileTreeWalker.java:276)
at java.nio.file.FileTreeWalker.walk(FileTreeWalker.java:322)
at java.nio.file.FileTreeIterator.<init>(FileTreeIterator.java:72)
at java.nio.file.Files.walk(Files.java:3574)
at java.nio.file.Files.walk(Files.java:3625)
at org.jetbrains.kotlin.konan.file.FileKt.recursiveCopyTo(File.kt:210)
at org.jetbrains.kotlin.konan.file.File.recursiveCopyTo(File.kt:67)
at org.jetbrains.kotlin.backend.konan.library.impl.FileExtractor.extractDir(KonanLibrary.kt:91)
at org.jetbrains.kotlin.backend.konan.library.impl.FileExtractor$kotlinDir$2.invoke(KonanLibrary.kt:71)
at org.jetbrains.kotlin.backend.konan.library.impl.FileExtractor$kotlinDir$2.invoke(KonanLibrary.kt:56)
at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)
at org.jetbrains.kotlin.backend.konan.library.impl.FileExtractor.getKotlinDir(KonanLibrary.kt)
at org.jetbrains.kotlin.backend.konan.library.impl.LibraryReaderImpl.getBitcodePaths(KonanLibraryReaderImpl.kt:67)
at org.jetbrains.kotlin.backend.konan.LinkStage.linkStage(LinkStage.kt:221)
at org.jetbrains.kotlin.backend.konan.KonanDriverKt$runTopLevelPhases$5.invoke(KonanDriver.kt:109)
at org.jetbrains.kotlin.backend.konan.KonanDriverKt$runTopLevelPhases$5.invoke(KonanDriver.kt)
at org.jetbrains.kotlin.backend.konan.PhaseManager$phase$$inlined$with$lambda$1.invoke(KonanPhases.kt:139)
at org.jetbrains.kotlin.backend.konan.PhaseManager$phase$$inlined$with$lambda$1.invoke(KonanPhases.kt:118)
at org.jetbrains.kotlin.konan.util.UtilKt.profileIf(Util.kt:34)
at org.jetbrains.kotlin.backend.konan.PhaseManager.phase$backend_native_compiler(KonanPhases.kt:138)
at org.jetbrains.kotlin.backend.konan.KonanDriverKt.runTopLevelPhases(KonanDriver.kt:108)
at org.jetbrains.kotlin.cli.bc.K2Native.doExecute(K2Native.kt:73)
at org.jetbrains.kotlin.cli.bc.K2Native.doExecute(K2Native.kt:40)
at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.java:94)
at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.java:50)
at org.jetbrains.kotlin.cli.common.CLITool.exec(CLITool.kt:88)
at org.jetbrains.kotlin.cli.common.CLITool.exec(CLITool.kt:66)
at org.jetbrains.kotlin.cli.common.CLITool.exec(CLITool.kt:34)
at org.jetbrains.kotlin.cli.common.CLITool$Companion.doMainNoExit(CLITool.kt:180)
at org.jetbrains.kotlin.cli.common.CLITool$Companion.doMain(CLITool.kt:171)
at org.jetbrains.kotlin.cli.bc.K2Native$Companion$main$1.invoke(K2Native.kt:197)
at org.jetbrains.kotlin.cli.bc.K2Native$Companion$main$1.invoke(K2Native.kt:188)
at org.jetbrains.kotlin.konan.util.UtilKt.profileIf(Util.kt:34)
at org.jetbrains.kotlin.konan.util.UtilKt.profile(Util.kt:29)
at org.jetbrains.kotlin.cli.bc.K2Native$Companion.main(K2Native.kt:190)
at org.jetbrains.kotlin.cli.bc.K2NativeKt.main(K2Native.kt:202)
at org.jetbrains.kotlin.cli.utilities.MainKt.main(main.kt:27)
> Task :ios:common:compileDebugIos_x64KotlinNative FAILED
:ios:common:compileDebugIos_x64KotlinNative (Thread[Task worker for ':' Thread 6,5,main]) completed. Took 29.401 secs.
FAILURE: Build failed with an exception.
I feel like we're nearly there, do you know how to solve this one?
It's worth mentioning that this did build successfully without errors, then the next day this new error started, and I can't figure out what changed.
Sorry, It looks like I provided a wrong code for adding dependency on an interop klib. In my snippet the top-level dependencies block was called so we added dependencies on all interop klibs to each binary. The compiler tried to link a library with a wrong target and failed to do this.
The correct adding a dependency will look like this:
import org.jetbrains.kotlin.gradle.plugin.experimental.*
components.withType(KotlinNativeBinary) {
def target = konanTarget.name
// Here, the binary's dependencies are accessed instead of the top-level block.
dependencies.implementation files("interop/build/konan/libs/${target}/Firebase.klib")
}
Thank you I'll give that a try shortly.
Another side-effect of moving from konan
to the kotlin-platform-native
plugin, is that it seems the plugin doesn't respect the konan plugin properties passed in from Xcode on the command line.
The konan build phase script in Xcode is something like this:
"$SRCROOT/../gradlew" -p "$SRCROOT" "$KONAN_TASK"
-Pkonan.configuration.build.dir="$CONFIGURATION_BUILD_DIR"
-Pkonan.debugging.symbols="$DEBUGGING_SYMBOLS"
-Pkonan.optimizations.enable="$KONAN_ENABLE_OPTIMIZATIONS"
The kotlin-platform-native
build doesn't respect the build output directory, and therefore probably not the other properties either. Is there a new way of providing these gradle properties to the kotlin-platform-native
plugin?
No, these properties are not used by the new plugin but you can copy the framework built in the right location as shown here.
Ok that worked great, thank you.
Now that the project can build and run, it seems like the Firebase iOS libraries just fall apart when linked into Kotlin/Native:
[FIRInstanceIDCheckinPreferences preferencesFromKeychainContents:]: unrecognized selector sent to class
inside FIRApp.configure()
or inside FIRMessaging.messaging()
depending whether the duplicate symbols are linked or notFIRFirebase.firebase()
factory returns nil
(this should always return an instance or throw an exception)I realise this is very specific to Firebase, but I confirmed the framework versions I'm linking work fine outside of Kotlin/Native. Once I use it from Kotlin/Native using interop, it all just falls apart.
Is this a loosing battle? Or do you have some ideas?
I can't share the project code, but if it will be helpful, I can put together a stripped down project to reproduce the problems.
I can put together a stripped down project to reproduce the problems.
Yes, it would be very helpful :)
Hi @ilmat192, now that C Interop is implemented in the multi platform plugin, the above experiment may be a moot point. So I'm trying this again, but having a few issues:
Def files in src/nativeInterop/cinterop
, for example FirebaseCore.def
:
headers = FirebaseCore/FirebaseCore.h
compilerOpts = -framework FirebaseCore
excludeDependentModules = true
package = com.google.firebase.core
And build.gradle
(I've excluded the Android parts for brevity):
apply plugin: 'kotlin-multiplatform' // 1.3.0
apply plugin: 'kotlinx-atomicfu'
kotlin {
sourceSets {
commonMain {
dependencies {
implementation 'org.jetbrains.kotlin:kotlin-stdlib'
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core-common:$coroutines_version"
implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime-common:$serialization_version"
implementation "org.jetbrains.kotlinx:atomicfu-common:$atomicfu_version"
}
}
iosMain {
dependencies {
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core-native:$coroutines_version"
implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime-native:$serialization_version"
implementation "org.jetbrains.kotlinx:atomicfu-native:$atomicfu_version"
}
}
}
targets {
fromPreset(presets.android, 'android')
def buildForDevice = project.findProperty("device")?.toBoolean() ?: false
def iosPreset = (buildForDevice) ? presets.iosArm64 : presets.iosX64
println("iOS preset: ${iosPreset.getName()}")
fromPreset(iosPreset, 'ios') {
compilations.main {
outputKinds('FRAMEWORK')
cinterops {
FirebaseCore
FirebaseAuth
FirebaseFirestore
FirebaseMessaging
}
}
}
}
}
I'm stuck at the first step because it's trying to include the Kotlin dependencies in the cinterop task (?):
* What went wrong:
Could not resolve all files for configuration ':common:iosFirebaseCoreCInterop'.
> Could not resolve org.jetbrains.kotlinx:kotlinx-coroutines-core-native:1.0.0.
Required by:
project :common
> Unable to find a matching configuration of org.jetbrains.kotlinx:kotlinx-coroutines-core-native:1.0.0:
...
- Configuration 'debugIos_x64Link':
- Found org.gradle.native.debuggable 'true' but wasn't required.
- Found org.gradle.native.optimized 'false' but wasn't required.
- Found org.gradle.status 'release' but wasn't required.
- Required org.gradle.usage 'java-api' and found incompatible value 'kotlin-api'.
- Required org.jetbrains.kotlin.native.target 'ios_x64' and found compatible value 'ios_x64'.
- Required org.jetbrains.kotlin.platform.type 'native' and found compatible value 'native'.
etc...
What am I doing wrong here?
Hi! It's a known problem with dependencies. The fix is ready and will be included in 1.3.10. As a workaround you can modify the wrong attribute manually by adding the following code in your build script:
kotlin.targets.matching { it.platformType.name == 'native' }.all {
compilations.all {
cinterops.all {
configurations[dependencyConfigurationName].attributes.attribute(
Usage.USAGE_ATTRIBUTE,
objects.named(Usage, 'kotlin-api')
)
}
}
}
Thanks @ilmat192, that works well for now.
The new experimental
kotlin-platform-native
plugin DSL introduced in v0.8 does not currently support generating interop bindings, like thekonan
plugin does, according to this.When will interop support be added?
In the meantime, is there a way to add a klib file as a dependency? I.e. use the
konan
plugin to generate the interop klib, then add that klib to thekotlin-platform-native
build task?