Hello, me and my colleague is trying to use `cinte...
# kotlin-native
a
Hello, me and my colleague is trying to use
cinterop
to call functions in the OpenSSL library. We already had it compiled as a
.framework
for iOS (calling fron Obj-C) so we re-used now when we are trying to call from Kotlin. We have managed to build a
.klib
using Gradle. From `build.gradle.kts`:
Copy code
val ios = iosArm64("ios")
    val iosSim = iosX64("iosSim")

    configure(listOf(iosSim, ios)) {
        binaries.framework {
            baseName = frameworkBaseName
        }
        compilations {
            val main by getting {
                cinterops {
                    val openssl by creating {
                        defFile("$projectDir/src/iosMain/cinterop/openssl.def")
                        includeDirs("$projectDir/src/iosMain/cinterop/OpenSSL-Apple/include")
                    }
                }
            }
        }
Def file:
Copy code
headers = openssl/asn1.h openssl/err.h openssl/pkcs12.h openssl/rsa.h openssl/x509.h
staticLibraries = openssl
libraryPaths = <beginning of absolute path>/KotlinMultiplatformTestSDK/shared/src/iosMain/cinterop/OpenSSL-Apple/frameworks/iPhone/openssl.framework
The above configuration works and produces a
klib
and we can then go ahead and import it and try to make a call to OpenSSL from Kotlin:
Copy code
package openssl

import interop.*
import kotlinx.cinterop.*

class TestOpenSSL {

    fun TestOpenSSL_init() {
        ERR_load_crypto_strings()
    }

}
We get code completion and everything seems to work just fine until we build it and we get an error from the linker:
Copy code
> Task :shared:linkDebugFrameworkIos
v: Using Kotlin home directory dist/kotlinc
e: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld invocation reported errors
            The /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld command returned non-zero exit code: 1.
            output:
            Undefined symbols for architecture arm64:
  "_ERR_load_crypto_strings", referenced from:
      _openssl_ERR_load_crypto_strings_wrapper662 in result.o
ld: symbol(s) not found for architecture arm64

> Task :shared:linkDebugFrameworkIos FAILED
Any ideas whats wrong here? How do we get this working? Would really appreciate any help! 🙂
a
Hello! On a first sight, the problem is that you haven’t provided any linker options here - therefore, linker cannot find those symbols anywhere. I’d guess that sumething like this should be added to the script:
Copy code
binaries.framework{
    linkerOpts=mutableListOf("-framework openssl", "-Fsrc/iosMain/cinterop/OpenSSL-Apple/frameworks/iPhone")
*This is just example, cannot say if you need exactly this one. Also maybe you should look at this GH issue, seems to be quite similar with your plan.
a
Thanks! The linked doesn't seem to recognise
-framework
though:
Copy code
> Task :shared:linkDebugFrameworkIos
v: Using Kotlin home directory dist/kotlinc
e: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld invocation reported errors
The /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld command returned non-zero exit code: 1.
output:
ld: unknown option: -framework openssl

> Task :shared:linkDebugFrameworkIos FAILED
Separating
-framework
and
openssl
seems to work. Like this:
Copy code
linkerOpts=mutableListOf("-framework", "openssl", "-F$projectDir/src/...")
Also, what does the "-F$projectDir/src/..." option do? Is it just -F from the ld linker?
a
Yep, my bad. Nice to hear it worked for you. Yes. -F option just specifies framework search path, same way as you go with an -L for a library.
a
Ok, so -F is just the search path for a framework. So looking at the documentation of -F at: https://ftp.gnu.org/old-gnu/Manuals/ld-2.9.1/html_node/ld_3.html is completely wrong then? It is not talking about the same thing?
Also is there any way to get rid of the absolute path for
libraryPaths
in the
.def
-file?
a
About option meaning - I think clang options should be more relevant here. About
libraryPaths
, I’m not sure this option is important at all. According to the doc, it’s about static libraries.
a
Thank you! The clang linker command line documentation makes much more sense! 🙂 And you are right about that we can remove
libraryPaths
but we also had to remove
staticLibraries
from the
.def
-file. Our
.framework
is static so that is why we used those options. Configuring this is very confusing. Any plans on more documentation? But it works now so I'm a happy coder! 😃
a
🎉 About the documentation - AFAIK there were some plans to make it more clear, but not sure about any details. It’s getting better with time, that’s for sure. Also, I would strongly recommend you to go through the Native and Multiplatform Programming sections on the https://kotlinlang.org/docs/reference/.
a
Thanks will do!