Hello, I'm trying to compile a c++ static lib and ...
# multiplatform
k
Hello, I'm trying to compile a c++ static lib and link it to my cinterops compilation. I've managed to compile the c++ lib using cpp-library, but I can't think of how to link the output to the inputs of cinterops. Anyone have any ideas on how to do this, or if I'm doing something completely wrong?
For my cpp-library, here it the build.gradle file:
Copy code
plugins {
    id "cpp-library"
}

library {
    linkage = Linkage.STATIC
}
This builds with and outputs libmylibrary.a
I can include this library in my def file by setting
staticLibraries
and
libraryPaths
accordingly
But, how do I set up my multiplatform gradle to compile my cpp-library before running the cinterops?
Or.. is there a better way to do this?
b
Kotlin/Native does not support cpp interop yet. There's an open issue for it, but it's postponed in favour of KMM
Wait, did you actually get it to work?
For gradle stuff you can add cppCompile task as a dependency to cinterops task
k
No, I wish I got cpp interop working 😛 I'm using cinterop with c headers
b
Makes sense. Thought I've missed cpp interop announcement 😀
k
Haha, sorry
b
Here's another gradle setup example for jni case petuska.dev/fake-kamera Native binary is compiled via kotlin native (so an equivalent to your cpp module) and added to jvm consumer (so your kotlin native module) Ignore the source code.
k
Thanks, I'll take a look and let you know how I get on ..
b
Btw, all of this is just to help with your gradle setup. This will not magically make cpp interop work with kotlin 😀
k
Yeah, I appreciate that. Nothing about any of this project has been simple so far. One step at a time!
l
Depending on how often your cpp code changes, you could write a separate gradle task that compiles it and moves the binary somewhere it can be shared. I do this on a project at work to avoid the cost of compiling the native code.
k
I've been considering that as this code is due to be replaced with Kotlin later anyway. How are you compiling and copying? Do you have a sharable example of that?
Ah, you said you're using a gradle task. I don't suppose you could share that?
l
Copy code
tasks {
    //We want to create a task that can copy our resulting Android library into the analyzer-android module.
    val prepareAndroidNdkSo by creating {
        dependsOn(build)
        val debugArm32SoFolder = File(buildDir, "bin/androidNativeArm32/debugShared")
        val jniArm32Folder = File(projectDir, "../a-folder/src/androidMain/jniLibs/armeabi-v7a")
        val debugArm64SoFolder = File(buildDir, "bin/androidNativeArm64/debugShared")
        val jniArm64Folder = File(projectDir, "../a-folder/src/androidMain/jniLibs/arm64-v8a")

        val debugX86SoFolder = File(buildDir, "bin/androidNativeX86/debugShared")
        val jniX86Folder = File(projectDir, "../a-folder/src/androidMain/jniLibs/x86")
        val debugX64SoFolder = File(buildDir, "bin/androidNativeX64/debugShared")
        val jniX64Folder = File(projectDir, "../a-folder/src/androidMain/jniLibs/x86_64")

        doLast {
            copy {
                from(debugArm32SoFolder)
                into(jniArm32Folder)
                include("*.so")
            }
            copy {
                from(debugArm64SoFolder)
                into(jniArm64Folder)
                include("*.so")
            }
            copy {
                from(debugX86SoFolder)
                into(jniX86Folder)
                include("*.so")
            }
            copy {
                from(debugX64SoFolder)
                into(jniX64Folder)
                include("*.so")
            }
        }
    }
}
k
Amazing, thank you 😄
l
I just realized I’ve been copying debug builds over.
There are other improvements you could make, like setting dependsOn to just the tasks you want, not a full build
k
Nice. Good to review old code every now and again
Yeah, I was just thinking about the dependsOn part. Looks quite useful
l
You can do some more gradle magic to make this happen at various parts of the build process, but I have it set up where I would have to run this manually.
k
That was my thought. I'm not sure how practical it is though. It's a tiny lib so there might not be much overhead
Hello again. Just to close this one out I got it to work with the following: • Stopped using cpp-library • Created a CMakeLists.txt to compile the project instead • Created a task in my gradle that runs 2 exec steps a. The first uses cmake to generate an Xcode project:
cmake -GXcode . -bbuild
b. The second then uses
xcodebuild
to build it • I call this task from my script in Xcode which builds my KMM module • I can then use the build lib in cinterops It's not the most efficient, but it works and I can improve on it in the future.
Thanks for all the pointers!