JetBrains / kotlin-native

Kotlin/Native infrastructure
Apache License 2.0
7.02k stars 566 forks source link

New plugin DSL doesn't support generating interop bindings #1828

Closed brettwillis closed 6 years ago

brettwillis commented 6 years ago

The new experimental kotlin-platform-native plugin DSL introduced in v0.8 does not currently support generating interop bindings, like the konan 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 the kotlin-platform-native build task?

ilmat192 commented 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')
}
msink commented 6 years ago

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 .klibs, and assign two names - for example libui.klib for cinterop, and libui-ktx.klib for my wrappers.

brettwillis commented 6 years ago

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...>.

  1. Its seems that I can't get your suggestion to work, do you have any ideas?
  2. What is the correct way to specify different Firebase.klib variants for different kotlin-platform-native build variants (ios_x64, ios_arm32, ios_arm64)?
ilmat192 commented 6 years ago
  1. Could you please run the build with the -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.
  2. You can specify dependencies per-binary:
    
    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`).
brettwillis commented 6 years ago

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?

olonho commented 6 years ago

Use linkerOpts, as specified in https://github.com/JetBrains/kotlin-native/blob/master/GRADLE_PLUGIN.md#properties-available-for-a-compiler-task-executable-library-or-bitcode-building-task.

brettwillis commented 6 years ago

linkerOpts from konan is not available on a kotlin-platform-native component as far as I can tell?

Neither of below work

  1. extraOpts "-F/path/to/frrameworks" - Error: invalid argument
  2. extraOpts "-linkerOpts -F/path/to/frameworks" - Error: invalid argument
ilmat192 commented 6 years ago

linkerOpts 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.

brettwillis commented 6 years ago

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.

ilmat192 commented 6 years ago

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")
}
brettwillis commented 6 years ago

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?

ilmat192 commented 6 years ago

No, these properties are not used by the new plugin but you can copy the framework built in the right location as shown here.

brettwillis commented 6 years ago

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:

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.

ilmat192 commented 6 years ago

I can put together a stripped down project to reproduce the problems.

Yes, it would be very helpful :)

brettwillis commented 6 years ago

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?

ilmat192 commented 6 years ago

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')
            )
        }
    }
}  
brettwillis commented 6 years ago

Thanks @ilmat192, that works well for now.