davidepianca98/KMQTT

Kotlin native could not find "openssl"

Closed this issue · 8 comments

I am trying to create project using this library with kotlin native on linux 64bit, but i am getting strange error about missing openssl. I have installed openssl and libssl-dev but the error still persists.

e: Could not find "openssl" in [/home/fjerabek/mqttTest, /home/fjerabek/.konan/klib, /home/fjerabek/.konan/kotlin-native-prebuilt-linux-x86_64-1.7.0/klib/common, /home/fjerabek/.konan/kotlin-native-prebuilt-linux-x86_64-1.7.0/klib/platform/linux_x64]

Execution failed for task ':compileKotlinNative'.
> Compilation finished with errors

Am i missing some other library on my system ?

Hello, how did you include the dependency in gradle? Also it looks like you are using Kotlin 1.7.0, I have yet to try to compile with that version but I will check soon.

I am including the dependency by adding this to the build.gradle.kts file into the sourceSets block.

commonMain {
    dependencies {
        implementation("com.github.davidepianca98.KMQTT:kmqtt:0.3.2")
    }
}

The resulting build file looks like this. It is the default template that jetbrains is using for kotlin native projects only with the added dependency.

plugins {
    kotlin("multiplatform") version "1.7.0"
}

group = "org.example"
version = "1.0-SNAPSHOT"

repositories {
    mavenCentral()
    maven(url = "https://jitpack.io")
}

kotlin {
    val hostOs = System.getProperty("os.name")
    val isMingwX64 = hostOs.startsWith("Windows")
    val nativeTarget = when {
        hostOs == "Mac OS X" -> macosX64("native")
        hostOs == "Linux" -> linuxX64("native")
        isMingwX64 -> mingwX64("native")
        else -> throw GradleException("Host OS is not supported in Kotlin/Native.")
    }

    nativeTarget.apply {
        binaries {
            executable {
                entryPoint = "main"
            }
        }
    }
    sourceSets {
        commonMain {
            dependencies {
                implementation("com.github.davidepianca98.KMQTT:kmqtt:0.3.2")
            }
        }
        val nativeMain by getting
        val nativeTest by getting
    }
}

For now i am trying out the library in jvm and kotlin 1.7.0 and it working great so far, but cannot get it to work with native.

Unfortunately Kotlin Native doesn't provide OpenSSL bindings so I usually compile my version using a script. Apparently this doesn't get included in the library files you get from Jitpack. If you want you can download the prebuilt version from here https://github.com/davidepianca98/KMQTT/blob/master/src/nativeInterop/openssl-linux-x64.klib and include it with the following code changing the directory.

val linuxArm64Main by getting {
    dependencies {
        implementation(files("src/nativeInterop/openssl-linux-x64.klib"))
    }
}

If, for whatever reason, you do not trust the prebuilt library you can build it yourself with Docker and the files in this directory: https://github.com/davidepianca98/KMQTT/tree/master/src/linuxX64Main/resources.

I will be looking for an easier way to do this, but for now this is it unfortunately.

I must be missing something 🤔. I added the dependency to the openssl library and looks like it loaded correctly because i can use openssl library methods, but now the problem is not in compileKotlinNative task but in linkDebugExecutableNative.

e: Could not find "openssl" in [/home/fjerabek/mqttTest, /home/fjerabek/.konan/klib, /home/fjerabek/.konan/kotlin-native-prebuilt-linux-x86_64-1.7.0/klib/common, /home/fjerabek/.konan/kotlin-native-prebuilt-linux-x86_64-1.7.0/klib/platform/linux_x64]

Execution failed for task ':linkDebugExecutableNative'.
> Compilation finished with errors

When i add the klib file to one of those locations and change the name to openssl.klib gradle complains about caching

/home/fjerabek/.gradle/caches/modules-2/files-2.1/com.github.davidepianca98.KMQTT/kmqtt-linuxx64/0.3.2/704c50f7b3bf5fd394f044a485dbba73cdc81f59/kmqtt-linuxx64-0.3.2 is going to be cached, but its dependency isn't: /home/fjerabek/mqttTest/openssl

I tried creating a brand new Kotlin Native project, then i added openssl-linux-x64.klib in the src directory and modified the build gradle file in the following way (I commented the choice of the platform because I am on Windows and I wanted to build for Linux).

plugins {
    kotlin("multiplatform") version "1.7.0"
}

group = "me.x"
version = "1.0-SNAPSHOT"

repositories {
    mavenCentral()
    maven(url = "https://jitpack.io")
}

kotlin {
    val hostOs = System.getProperty("os.name")
    val isMingwX64 = hostOs.startsWith("Windows")
    //val nativeTarget = when {
    //    hostOs == "Mac OS X" -> macosX64("native")
    //    hostOs == "Linux" -> linuxX64("native")
    //    isMingwX64 -> mingwX64("native")
    //    else -> throw GradleException("Host OS is not supported in Kotlin/Native.")
    //}
    val nativeTarget = linuxX64("native")

    nativeTarget.apply {
        binaries {
            executable {
                entryPoint = "main"
            }
        }
    }
    sourceSets {
        val commonMain by getting {
            dependencies {
                implementation("com.github.davidepianca98.KMQTT:kmqtt:0.3.2")
            }
        }
        val nativeMain by getting {
            dependencies {
                implementation(files("src/openssl-linux-x64.klib"))
            }
        }
        val nativeTest by getting
    }
}

Then I made this main file:

import mqtt.broker.Broker

fun main() {
    Broker().listen()
}

And finally I ran linkDebugExecutableNative and it's compiling correctly the binary file and it's running correctly.
Please try to check for differences and let me know if changing your setup makes it work.

This is weird. The same build script works on windows (I tried it on my windows machine) but not on linux. I tried cleaning the build cache and still no difference. The gradle versions are the same. I also tried it inside wsl to try other "linux" system and i cannot get it build in wsl too.

You are right, I have no idea what's going on, because linkReleaseExecutableNative works but linkDebugExecutableNative doesn't. I will continue to try to find the issue but it could be something wrong with the Kotlin build system.

Solved in 0.3.3