For the first time, I'm using Android Studio to build a multiplatform project. I have created an Android app module that uses the multiplatform lib on Android.
I have also used XCode to build an iOS app that uses the multiplatform lib on iOS.
Everything works fine and I'm able to use the expect fun
that is implemented by different actual fun
for Android and iOS.
I have also created a library in C++ that exposes a C interface.
#ifndef PINGLIB_LIBRARY_H
#define PINGLIB_LIBRARY_H
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
long long elapsed;
} PingInfo;
typedef void (*PingCallback)(PingInfo pingInfo);
typedef struct
{
PingCallback pingUpdate;
} PingObserver;
void* ping(const char * url, const PingCallback *pingCallback);
void subscribe(void* pingOperation);
void unsubscribe(void* pingOperation);
#ifdef __cplusplus
}
#endif
#endif //PINGLIB_LIBRARY_H
I use CLion to build the C++ code.
I have created a .def
file that I use to build the library using cinterop
.
package = com.exercise.pinglib
headers = PingLibrary.h
linkerOpts.linux = -L/usr/lib/x86_64-linux-gnu
compilerOpts = -std=c99 -I/Users/username/myproject/ping/ping/header
staticLibraries = libping.a
libraryPaths = /opt/local/lib /Users/username/myproject/ping/cmake-build-debug
libping.a
is the library created building the C++ code. It is created in the folder /Users/username/myproject/ping/cmake-build-debug
When I run the command cinterop -def ping.def -o ping
, it creates the klib file and a folder containing a manifest.properties
file a natives
subfolder containing a cstubs.bc
file and a kotlin
subfolder with a .kt
file.
ping.klib
-ping-build
manifest.properties
-natives
cstubs.bc
-kotlin
-com
-exercise
-pinglib
pinglib.kt
How can I use the library created by cinterop
in my kotlin-multiplatform project?
I have found different ways to import it but I did not find any complete description of how to do it. Here they say that I can use something like:
implementation files("ping.klib")
I did it for the iOS project but I still don't know how to access the kotlin classes neither on Android nor on iOS.
This is my build.gradle
apply plugin: 'com.android.library'
apply plugin: 'kotlin-multiplatform'
android {
compileSdkVersion 28
defaultConfig {
minSdkVersion 15
}
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
kotlin {
targets {
final def iOSTarget = System.getenv('SDK_NAME')?.startsWith('iphoneos') ? presets.iosArm64 : presets.iosX64
fromPreset(iOSTarget, 'ios') {
binaries {
framework('shared')
}
}
fromPreset(presets.android, 'android')
}
sourceSets {
// for common code
commonMain.dependencies {
api 'org.jetbrains.kotlin:kotlin-stdlib-common'
}
androidMain.dependencies {
api 'org.jetbrains.kotlin:kotlin-stdlib'
}
iosMain.dependencies {
implementation files("ping.klib")
}
}
}
configurations {
compileClasspath
}
task packForXCode(type: Sync) {
final File frameworkDir = new File(buildDir, "xcode-frameworks")
final String mode = project.findProperty("XCODE_CONFIGURATION")?.toUpperCase() ?: 'DEBUG'
final def framework = kotlin.targets.ios.binaries.getFramework("shared", mode)
inputs.property "mode", mode
dependsOn framework.linkTask
from { framework.outputFile.parentFile }
into frameworkDir
doLast {
new File(frameworkDir, 'gradlew').with {
text = "#!/bin/bash\nexport 'JAVA_HOME=${System.getProperty("java.home")}'\ncd '${rootProject.rootDir}'\n./gradlew \$@\n"
setExecutable(true)
}
}
}
tasks.build.dependsOn packForXCode
EDIT
I have changed the question because, initially, I thought that cinterop
was not creating the klib library but it was just a mistake: I was looking in the ping-build
folder but the file is outside that folder. So I resolved half of the question.
EDIT2
I have added the build.script
cinterop
call? At first sight, it seems like you have set the-Xnopack=true
here, so you got aping-build
, but noping.klib
. – Flasket