Skip to content

Commit

Permalink
Merge pull request #1 from korlibs/soywiz/fix.knative
Browse files Browse the repository at this point in the history
Try to fix K/N compilation for new FFI
  • Loading branch information
soywiz authored Jul 30, 2024
2 parents de64f48 + 620df87 commit b3e5080
Show file tree
Hide file tree
Showing 7 changed files with 52 additions and 6 deletions.
14 changes: 9 additions & 5 deletions korlibs-ffi-ksp/src@jvm/korlibs/ffi/ksp/FFIBuilderProcessor.kt
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,12 @@ private class FFIBuilderProcessor(val environment: SymbolProcessorEnvironment) :
override fun process(resolver: Resolver): List<KSAnnotated> {
val isCommon = environment.platforms.size >= 2
val mainPlatform = if (isCommon) MetadataPlatformInfo else environment.platforms.first()
val isJvm = if (!isCommon && mainPlatform is JvmPlatformInfo) true else false
val isNative = if (!isCommon && mainPlatform is NativePlatformInfo) true else false
val isJs = if (!isCommon && mainPlatform is JsPlatformInfo) true else false
val isAndroid = resolver.getClassDeclarationByName(resolver.getKSNameFromString("android.view.View")) != null
val isJvm = !isCommon && mainPlatform is JvmPlatformInfo && !isAndroid
val isNative = !isCommon && mainPlatform is NativePlatformInfo
val isJs = !isCommon && mainPlatform is JsPlatformInfo

//logger.error("NATIVE: ${environment.options}, ${environment.platforms.map { it.platformName }}, isAndroidProject=$isAndroidProject")

val casts = when {
isJvm -> jnaCasts
Expand Down Expand Up @@ -86,6 +89,7 @@ private class FFIBuilderProcessor(val environment: SymbolProcessorEnvironment) :

val ffiAnnotation = sym.annotations.firstOrNull { it.shortName.getShortName() == "FFI" } ?: error("ERROR: FFI annotation not found")
val libs = ffiAnnotation.arguments.associate { it.sname to it.value.toString().takeIf { it.isNotBlank() } }
val libraryCommonLib = libs["commonLib"] ?: "libc"
val libraryNameWin = libs["windowsLib"] ?: libs["commonLib"] ?: "msvcrt"
val libraryNameMac = libs["macosLib"] ?: libs["commonLib"] ?: "/usr/lib/libSystem.dylib"
val libraryNameLinux = libs["linuxLib"] ?: libs["commonLib"] ?: "libc"
Expand Down Expand Up @@ -122,10 +126,10 @@ private class FFIBuilderProcessor(val environment: SymbolProcessorEnvironment) :
it.appendLine("fun FFIPointer.toPointer(): COpaquePointer? = address.toCPointer()")

it.appendLine("private object __$classNameImpl {")
it.appendLine(" val __LIB__ = platform.windows.LoadLibraryW(\"$libraryNameWin\")")
it.appendLine(" val __LIB__ = korlibs.ffi.api.FFIDLOpenPlatform(common = \"$libraryCommonLib\", linux = \"$libraryNameLinux\", macos = \"$libraryNameMac\", windows = \"$libraryNameWin\")")

for (func in sym.getDeclaredFunctions()) {
it.appendLine(" val ${func.sname} by lazy { val funcName = \"${func.sname}\"; platform.windows.GetProcAddress(__LIB__, funcName)?.reinterpret<CFunction<(${func.parameters.asTypeString(casts)}) -> ${func.returnType.asString(casts)}>>() ?: error(\"Can't find ${'$'}funcName\") }")
it.appendLine(" val ${func.sname} by lazy { val funcName = \"${func.sname}\"; korlibs.ffi.api.FFIDLSym(__LIB__, funcName)?.reinterpret<CFunction<(${func.parameters.asTypeString(casts)}) -> ${func.returnType.asString(casts)}>>() ?: error(\"Can't find ${'$'}funcName\") }")
}
it.appendLine("}")
}
Expand Down
1 change: 1 addition & 0 deletions korlibs-ffi/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ tasks.withType(KspTask::class) {
this.dependsOn("kspCommonMainKotlinMetadata")
}
}
tasks.getByName("sourcesJar").dependsOn("kspCommonMainKotlinMetadata")
//tasks.all {
// if (this.name.contains("ksp")) {
// println("task=$this :: ${this::class}")
Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion korlibs-ffi/src/korlibs/ffi/api/TestMathFFI.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package korlibs.ffi.api

@FFI(commonLib = "libc.so.6", macosLib = "/usr/lib/libSystem.dylib", windowsLib = "msvcrt")
@FFI(commonLib = "libm.so.6", macosLib = "/usr/lib/libSystem.dylib", windowsLib = "msvcrt")
internal interface TestMathFFI : AutoCloseable {
fun cosf(v: Float): Float
fun malloc(size: Int): FFIPointer
Expand Down
10 changes: 10 additions & 0 deletions korlibs-ffi/src@mingw/korlibs/ffi/api/FFI.mingw.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
@file:OptIn(ExperimentalForeignApi::class)

package korlibs.ffi.api

import kotlinx.cinterop.*
import platform.windows.*

actual fun FFIDLOpen(name: String): COpaquePointer? = LoadLibraryW(name)?.reinterpret()
actual fun FFIDLClose(lib: COpaquePointer?): Unit { FreeLibrary(lib?.reinterpret()) }
actual fun FFIDLSym(lib: COpaquePointer?, name: String): COpaquePointer? = GetProcAddress(lib?.reinterpret(), name)?.reinterpret()
21 changes: 21 additions & 0 deletions korlibs-ffi/src@native/korlibs/ffi/api/FFI.native.kt
Original file line number Diff line number Diff line change
@@ -1,3 +1,24 @@
@file:OptIn(ExperimentalForeignApi::class)

package korlibs.ffi.api

import kotlinx.cinterop.*
import kotlin.experimental.*

actual val isSupportedFFI: Boolean = true

expect fun FFIDLOpen(name: String): COpaquePointer?
expect fun FFIDLClose(lib: COpaquePointer?): Unit
expect fun FFIDLSym(lib: COpaquePointer?, name: String): COpaquePointer?
@OptIn(ExperimentalNativeApi::class)
fun FFIDLOpenPlatform(
common: String? = null,
linux: String? = null,
macos: String? = null,
windows: String? = null,
): COpaquePointer? = FFIDLOpen(when (Platform.osFamily) {
OsFamily.MACOSX, OsFamily.IOS, OsFamily.TVOS, OsFamily.WATCHOS -> macos ?: common
OsFamily.LINUX -> linux ?: common
OsFamily.WINDOWS -> windows ?: common
OsFamily.WASM, OsFamily.UNKNOWN, OsFamily.ANDROID -> common
} ?: error("Can't find library name"))
10 changes: 10 additions & 0 deletions korlibs-ffi/src@posix/korlibs/ffi/api/FFI.posix.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
@file:OptIn(ExperimentalForeignApi::class)

package korlibs.ffi.api

import kotlinx.cinterop.*
import platform.posix.*

actual fun FFIDLOpen(name: String): COpaquePointer? = platform.posix.dlopen(name, platform.posix.RTLD_LAZY or 1)
actual fun FFIDLClose(lib: COpaquePointer?): Unit { platform.posix.dlclose(lib) }
actual fun FFIDLSym(lib: COpaquePointer?, name: String): COpaquePointer? = platform.posix.dlsym(lib, name)

0 comments on commit b3e5080

Please sign in to comment.