Is there a guide on building a linux x64 native li...
# gradle
s
Is there a guide on building a linux x64 native lib via kts? I want this to be inherited by another external project. My searching has not been helping much. I'm getting the following error. I've tried spinning up a source set nativeMain, but getting that doesn't exist. - Required org.jetbrains.kotlin.platform.type 'native' and found incompatible value 'common'.
n
Have a look at the Building Multiplatform Projects with Gradle article (covers Gradle Kotlin DSL - https://kotlinlang.org/docs/reference/building-mpp-with-gradle.html ). Although the article isn't Linux specific it should point you in the right direction. I recommend reading through the Setting up Targets section ( https://kotlinlang.org/docs/reference/building-mpp-with-gradle.html#setting-up-targets ).
Here is a build file which shows how to publish a Kotlin Native library which targets linuxX64: https://gitlab.com/gui-vista/guivista-core/blob/master/build.gradle.kts
The linuxX64 target is the easiest Kotlin Native target to get started with. Reasonably straightforward to setup a Linux program/library quickly.
s
Thanks for the links I have a linux Target
Copy code
linuxX64 {
        val main by compilations.getting
        binaries {}
        compilations.getByName("main") {
            cinterops.create("zfLog") {
                defFile = File("$projectDir/src/linuxX64Main/nativeInterop/cinterop/zLog.def")
                includeDirs("$projectDir/src/linuxX64Main/nativeInterop/zLog")
            }
        }
    }
Then a source set
Copy code
val linuxX64Main by getting {
            dependsOn(commonMain)
        }
But I'm still getting The Kotlin source set linux was configured but not added to any Kotlin compilation
n
The linuxX64 block automatically includes the dependency on the Common module.
s
That's what I was thinking. I'm getting the two errors. * source set configured but not added * was expecting native but found common
n
Is the linuxX64 source set called native?
If that is the case then change
linuxX64 {
to
linuxX64("native")
.
s
I've been bouncing it around based on different kts samles I've seen. But initially it was
named("linuxX64Main")
named("linuxX64")
, then the by getting
This should be pretty straight forward. I have a single cinterop and no other dependencies. Just trying to output the linux x64 lib
n
This block ( https://gitlab.com/AnimusDesign/kotlin-logging/blob/dev/linux_x64_native/build.gradle.kts#L125 ) is redundant since the linuxX64 block automatically includes a dependency on common. Apart from that there doesn't seem to be any other issues with the build file.
s
I did that as a last resort. I have this working in .gradle. But can't get it working in kts.
n
Have you tried only including the minimum amount of build logic required to publish a library for the linuxX64 target?
s
like just linux x64 target + c interop?
👌 1
n
In a new Git branch have a top level build.gradle.kts file that only includes the linuxX64 target, and the required C interop.
s
Just tried commenting out js/jvm target and source set. Wiping local m2 repo, and cleaning. Same error. Same error source set linux was configured but not added to compilation
n
Try moving the sourceSets block above the linuxX64 block.
s
source set above linuxX64 target ressult in
KotlinSourceSet with name 'linuxX64Main' not found.
It seems to be the cinterop. Knocking back everything to just a base hello world function works and builds
👍 1
n
In that case can you gradually add cinterop for each C library, is that possible?
What does ``named("linuxX64Main") {}`` do?
s
I'm trying to add linux support to an existing lib, so I hadn't heard of it before. From the docs it gets a source set, and creates if not present
I only have on c lib, and I thought it was a pretty small build. But yeah I need to go through the cinterop docs. I thought I had followed the kts. But it builds and works fine. Like I can do a run application from that same block and it's fine. But it's not getting packaged up into a library
Well it is the klib files are in the ~/.m2/repository directory, and matches what's expected. But back to the initial errors I posted
n
File structure of a Kotlin Native library in the local Maven repository.
Does your published library have a similar structure to the one above? ☝️
s
Thanks again for the help
simple smile 1
I cast the cinterop to a static lib. That fixed the issue. But now I have a hacky build sh script. I need to look at how to have gradle automatically kick off that static lib building
n
Did you check the library path (on linux this can be manipulated via the LD_LIBRARY_PATH environment variable) for all dynamic C libraries that are used in the library?
s
Well this isn't a standard library that will be on most systems. I used the LD_PATH for another project. But this includes a small c file that needs to be compiled in conjuction. I'm working more from a container/backend native lib/app. So those will either need to be via a custom container image or statically included.
n
Are you referring to Docker for the container part? Have a issue when running a Kotlin Native program via Docker (in Debian) that the C library isn't found/loaded, yet if the program is running via Linux (eg on bare metal through Linux Mint) the C library is found/loaded. Seems that Docker handles C libraries differently compared to how they are handled on Linux.
s
It depends on the which libc is being used. I'm just starting with native. But encountered a similar problem with nodejs target. When trying to compile the js part. The downloaded nodejs could not be launched. I had to build a custom container image to build it. I will delve into this more once I build tests into my ci/cd pipeline
🆗 1
Also while I thought this was related to the static lib. I found out you need to specifiy a nativeMain source set. If being pulled into a multi platform / common project. It worked on another linuxX64 project but not multi platform
Copy code
val nativeMain by sourceSets.creating {
        dependencies {
            api("org.jetbrains.kotlin:kotlin-stdlib-common")
        }

    }
    val linuxX64 by sourceSets.creating {
        dependsOn(nativeMain)
    }
    targets.withType(KotlinNativeTarget::class.java) {
        compilations["main"].defaultSourceSet.dependsOn(nativeMain)
        when (hostPresetName) {
            "macosX64" -> TODO()
            "linuxX64" -> compilations["main"].defaultSourceSet.dependsOn(linuxX64)
            "mingwX64" -> TODO()
            else -> error("Unsupported host platform")
        }
    }
119 Views