Skip to content

Repository files navigation

Ferrus Nexus KMP

Ferrus Nexus KMP is a Kotlin Multiplatform library for bridging Kotlin code with native libraries (focusing on library authors). It provides a shared API for calling native functions, creating foreign instances, and working with Wire message types across JVM and native targets.

Features

  • Kotlin Multiplatform support for JVM and native platforms
  • Helpers for calling native functions and methods
  • Support for input and output protobuf-style messages via Wire
  • Native pointer and foreign instance lifecycle management
  • Ready to publish as a Maven artifact

Supported targets

  • JVM (thought to be used along jextract)
  • Linux x64
  • Linux arm64
  • Windows x64

Getting started

Gradle

Add the dependency to your project:

implementation("io.github.ignaciodelatorrearias:ferrus-nexus:0.0.1")

Example JVM

import io.github.ignaciodelatorrearias.ferrusnexus.FerrusNexus

val nexus = FerrusNexus(
    library = "my_native_library",
    errorAdapter = YourErrorMessage.ADAPTER,
    errorManagerFunction = { status: int, error: YourErrorMessage  ->
        // handle errors
    },
    freeBufferFunction = my_native_library_h::free_buffer
)

nexus.function(my_native_library_h::some_function)

Example native target

import io.github.ignaciodelatorrearias.ferrusnexus.executablePath
import io.github.ignaciodelatorrearias.ferrusnexus.FerrusNexus

val name = when (Platform.osFamily) {
    OsFamily.UNKNOWN -> throw Error("Unknown Platform")
    OsFamily.MACOSX -> throw Error("Unsupported Platform")
    OsFamily.IOS -> throw Error("Unsupported Platform")
    OsFamily.LINUX -> "libmy_native_library.so"
    OsFamily.WINDOWS -> "my_native_library.dll"
    OsFamily.ANDROID -> throw Error("Unsupported Platform")
    OsFamily.WASM -> throw Error("Unsupported Platform")
    OsFamily.TVOS -> throw Error("Unsupported Platform")
    OsFamily.WATCHOS -> throw Error("Unsupported Platform")
}
val nexus = FerrusNexus(
    executablePath / name,
    errorAdapter = YourErrorMessage.ADAPTER,
    errorManagerFunction = { status: int, error: YourErrorMessage  ->
        // handle errors
    },
    "free_buffer"
)
nexus.function("some_function")
// Optionally if you consider using implicit dynamic linking and cinterops functionality.
val nexus = FerrusNexus(
    errorAdapter = YourErrorMessage.ADAPTER,
    errorManagerFunction = { status: int, error: YourErrorMessage  ->
        // handle errors
    },
    ::free_buffer
)
nexus.function(::some_function)

Considerations

Kotlin/native doesn't implement a way to use dynamic libraries, but it does implement a way to use static ones.

We could use some trickery to pass the native library files to the linker, forcing implicit linking.

linkerOpts.mingw_x64 = -Lnatives/x86_64-windows/ -lmy_native_library.dll
linkerOpts.linux_x64 = -Lnatives/x86_64-linux-gnu/ -lmy_native_library -rpath "$ORIGIN:."

However for library authors this creates a problem, because users need to be aware of how cinterops works and what files would they need configure to pass to the linker.

Ferrus Nexus offers a way to use explicit linking and do some non-configuration-intensive trickery.

A typical .def file:

headers = my_native_library.h
package = com.example.my_native_library

compilerOpts = -Imy_native_library/

staticLibraries.mingw_x64 = my_native_library.dll
libraryPaths.mingw_x64 = natives/x86_64-windows/

staticLibraries.linux = libmy_native_library.so
libraryPaths.linux_x64 = natives/x86_64-linux-gnu/
libraryPaths.linux_arm64 = natives/aarch64-linux-gnu/

This only helps to include the .dll/.so inside the .klib.

The client of the library only needs to add:

plugins {
    ...
    id("io.github.ignaciodelatorrearias.ferrus-nexus-extract") version "0.0.1"
}

This plugin only extracts the dynamic libraries from the .klib and places it alongside the executable for the corresponding platform.

License

This project is licensed under the Apache License 2.0.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages