I have found the answer to all my questions. The final source code is here: GitHub
In this project, I wanted to support only the linux 64 bit target. Here's what I got to know:
There were some source conflicts due to various targets. I removed all of them and just used the linuxX64() source set which is one of the predefined sets.
Most of the issues were due to the usage of non-standard source sets (I'd have to redefine everything in that case).
All the headers and defs are kept in the nativeInterop folder. The cinterop block picks these up and generates the bindings.
However, in my case, nativeInterop doesn't seem to be a default folder(I had to configure some things manually to get it working), but regardless, it works pretty well.
A point to note is that, you need to configure a linker option named "rpath" for the executable to detect the shared library at runtime. This rpath variable is the absolute path of the shared library.
Use the runReleaseExecutableLinuxX64 task to run the final executable.
Here's the kotlin section of build.gradle.kts.
kotlin {
//Defines the folders where the .def and headers are kept
val nativeLinuxResDir = "src/nativeInterop/cinterop"
//Defines the folders where native libraries are kept
val nativeLinuxLibsDir = "$nativeLinuxResDir/libs"
//Add Linux 64 bit target
linuxX64() {
binaries {
//Produces a native linux executable file
executable {
//The entry point of the program
entryPoint = "main"
//Configure Runtime Path of the executable
linkerOpts = mutableListOf(
"-rpath=${project.projectDir}/$nativeLinuxLibsDir",
"-ldemo"
)
}
}
/* All the headers and .def files should be kept in src/nativeInterop/cinterop/
* All shared and static libs should be kept in src/nativeInterop/cinterop/libs/
* This is done to maintain good practices.
*/
//Settings for Main compilation process
compilations.getByName("main") {
cinterops {
//Create a Cinterop process
val demo by creating {
//Sets the .def file
definitionFile.set(project.file("$nativeLinuxResDir/demo.def"))
//Sets the package name where the generated bindings will be kept
packageName("demo")
//Directory to find headers
includeDirs(nativeLinuxResDir)
}
}
}
//Settings for Test compilation process
compilations.getByName("test") {
cinterops {
//Create a Cinterop process
val demo by creating {
//Sets the .def file
definitionFile.set(project.file("$nativeLinuxResDir/demo.def"))
//Sets the package name where the generated bindings will be kept
packageName("demo")
//Directory to find headers
includeDirs(nativeLinuxResDir)
}
}
}
}
sourceSets {
//Dependencies for Linux 64 bit target
linuxX64Main.dependencies {
}
}
}
Hope the answer helps.