3

I am new to Kotlin/Native as I assume many others are and wish to use a C library from Kotlin. There is documentation out there and a couple tutotials that get you 85% and just miss the mark. And YES, I tried to read about everything before I asked the question.

The flow to utilize a C library in Kotlin is easy to find.

1) create a .def file ---Ok!

2) use the tool cinterop on the .def file to create a .klib file -- OK

----NOW HOW DO YOU USE IT??---

Specifically, now that we have a .klib file, call it "XXX.klib", how do we import the symbols?

Is one supposed to use gradle and add a dependency of the klib file? Is there a default folder structure to put the .Klib in? Is one supposed to some how associate the Klib with a package?

The issue I am having with gradle at the time is I really don't understand what is relevant to the thing I am doing vs what you find on the internet. Somebody just saying..."Here's my gradle file" really hurts more than than it helps some times because it does not make you smarter just copying it.

I have looked at the link https://medium.com/androidiots/the-magic-of-kotlin-native-part-2-49097c2dea1a

I have also looked at a very near answer to my question Adding a `.klib` library to kotlin multiplatform

But the answers fell short.

westocl
  • 73
  • 6
  • 1
    If you want to use the command-line compiler, you got to link the klib by `-l` flag, just as described in the article. – Artyom Degtyarev Oct 09 '19 at 15:33
  • @westocl did you ever solve this? I'm at a point where I've got Gradle to build my library and the `shared-cinterop-mylib.klib` and `build` folders are in the `classes/kotlin/androidNativeArm64/main/shared-cinterop-mylib.klib-build` but my `androidApp` can't see the package and just shows red lines on the `import` line. I added `implementation(files("/home/me/AndroidStudioProjects/MyApplication/shared/build/classes/kotlin/androidNativeArm64/main/shared-cinterop-mylib.klib"))` to my `androidApp` Gradle but still no luck. –  Mar 28 '21 at 19:37

1 Answers1

1

Here is the part of the official reference, that covers the concept of the Kotlin Library. It also explains, how to use it in the command line.
About the Gradle. In the case of Kotlin/Native, one can write a task to generate C wrappers automatically. To make self more familiar with Gradle scripts applied to Kotlin/Native I strongly recommend one to have a look at samples from the compiler's repository.

Artyom Degtyarev
  • 2,704
  • 8
  • 23
  • Thanks for the links. I was using the IntelliJ IDE code that wants to consume the library. One would hope once you use the cinterop tool and now have stubs in kotlin similar to the “.h” file and a klib file you could continue using the IntelliJ idea to develope with the library. – westocl Oct 10 '19 at 11:32
  • Please provide some details. When you have the `.klib`, you can add a dependency on this library, and consume it in the code. An example of this approach can be found in `samples/curl`. – Artyom Degtyarev Oct 10 '19 at 12:36
  • 1
    I think may be mixing the command line 'flow' with the a flow purely driven by build.gradle.kts, so i may be confusing myself. I use the command line cinterop to get the .klib. In the samples/curl I don't see any EXPLICIT reference or command that tells the project to link with the KLIB. I apologize fully if I'm missing it. The way I think of it, is that once I have a klib and a interop.kt type stub file, I should be able to use it like one would use a .h and a .so by somehow providing the IDE with the equivalent of -Include and -library flags. – westocl Oct 10 '19 at 13:14
  • [This](https://github.com/JetBrains/kotlin-native/blob/303f6638f45aaf521b4ab67d09bba66932904950/samples/curl/build.gradle.kts#L43) is the line, where the library was linked. Then in the actual code, we are [importing](https://github.com/JetBrains/kotlin-native/blob/303f6638f45aaf521b4ab67d09bba66932904950/samples/curl/src/curlMain/kotlin/main.kt#L8) the library by its name. Do I understand correctly, that you actually have the script in the project? If so, I can't see any reasons to make a manual `cinterop` call. – Artyom Degtyarev Oct 10 '19 at 13:33
  • Are you saying the build time dependency on the .klib is resolved by the configuration commands in gradle: souceSets{...implementation("...libcurl:1.0")} then add tasks.withType(...){dependsOn(...)} ? Where in the example "libcurl" full name is "libcurl.klib". Then somewhere at runtime the program will look for libcurl.so in OS dependent directories? – westocl Oct 10 '19 at 14:26
  • `libcurl.klib` is not presented in the repository. It would be generated while processing task, written in `/samples/libcurl`. This is the reason for the `tasks.withType(...){dependsOn(...)}` existence. So, in your case, you got to write the dependency in the SourceSet, and add the path to your `.klib` as local Maven repo(see build.gradle.kts of the `curl` sample) – Artyom Degtyarev Oct 10 '19 at 14:36
  • I started over from scratch and tried to follow https://play.kotlinlang.org/hands-on/Introduction%20to%20Kotlin%20Native/04_AddingInteropToBuild. I can build artifacts. The "Stub Kt" file seems to be built under the build directory "classes" and the klib ib built under the "libs" directory. Both names are prefixed -cinterop. in nested directories kotlin->linux-> main and I'm stuck again. Final question. What exact directory does the sub Kt file go and the Klib file with the KLIb-buld directory? Not sure how to share a screenshot? – westocl Oct 10 '19 at 19:23
  • I am sorry, but I do not understand. What step of the hands-on tutorial made the problem? If something was unclear, maybe it would be helpful to look at [the code](https://github.com/kotlin-hands-on/intro-kotlin-native). Also, if one wants to communicate more informal, it would be better to do in the Kotlin (Slack)[http://slack.kotlinlang.org/?_ga=2.104820932.515658589.1570431434-1089074657.1560174812] rather than SO answer comment section ;-) – Artyom Degtyarev Oct 11 '19 at 08:03