Is it possible to specify dependency resolution wi...
# kotlin-native
n
Is it possible to specify dependency resolution with C libs at the Gradle build file level (eg have the glinegraph def file depend on the gtk3 def file)?
If not then would including the stuff in headers, headerFilter, compilerOpts.linux, and linkerOpts.linux from the gtk3.def file into the glinegraph.def file work?
d
I have found that this is done automatically but only across modules. You can add
depends=gtk3
to your glinegraph def file. Although you have to repeat all the other attributes too. I'm assuming you intend to re-use the kotlin gtk definitions.
👌 1
n
Repeating the other attributes is a bit of a pain, although it is a little bit better than the other option. Hopefully the Kotlin Native team will improve the C library dependency situation so it is less tedious/error prone 🙏 .
Getting a bit stuck with resolving this error:
glg_cairo.h:31:1: error: unknown type name 'G_BEGIN_DECLS'
Tried appending glib/gmacros.h to the headers property in the glinegraph.def and gtk3.def files however the error still persists (the macro can't be found).
The missing macro is in the /usr/include/glib-2.0/glib/gmacros.h file.
Definition file for the GTK 3 GUI toolkit (a set of related libraries).
Definition file for the GLineGraph Cairo library ( https://skoona.github.io/glinegraph-cairo ). This library provides a GTK Line Graph widget.
s
@Dominaezzz
I have found that this is done automatically but only across modules. You can add
depends=gtk3
to your glinegraph def file.
Are you sure that adding
depends
has any effect? IIRC, it shouldn’t work this way.
🚫 1
n
@svyatoslav.scherbina - What method would you suggest for easily managing C library dependencies in a Kotlin Native app?
d
That was a separate suggestion. I've only used it to depend on platform libraries. Like
windows
. It did have an effect on that case.
s
I’ve only used it to depend on platform libraries. Like
windows
. It did have an effect on that case.
AFAIK, cinterop library always depends on platform libraries, so
depends
shouldn’t have any effect event in this case.
What method would you suggest for easily managing C library dependencies in a Kotlin Native app?
There is no build-in method for this. You can extract attributes configuration to a function in build script. Also there should be a way to make one cinterop library import declarations from other one instead of including a duplicate definition.
n
Would that mean only a single def file has to be created?
Is there a API available for extracting attribute configuration from a def file?
You can extract attributes configuration to a function in build script. Also there should be a way to make one cinterop library import declarations from other one instead of including a duplicate definition.
Sounds like these things are not yet designed/implemented (aka a possible issue to create in the Kotlin Native issue tracker).
s
Would that mean only a single def file has to be created?
It doesn’t limit you to this.
Is there a API available for extracting attribute configuration from a def file?
No. This is not required for the approach I suggested above.
Also there should be a way to make one cinterop library import declarations from other one instead of including a duplicate definition.
To achieve that, first cinterop library should be attached to a compilation that (transitively) depends on the second one.
n
Is there a sample project that uses this technique?
d
Also while we're on this topic. I was trying to utilise this feature but in my case, I didn't have 2 header files. I had a header file with a custom definition which included more functions when present. KN assumes the output is the same since the headers are the same but it doesn't consider that
-DINCLUDE_MORE_FUNCTIONS
changes the header. So my second cinterop klib comes out empty. 😞.
s
Is there a sample project that uses this technique?
I’m not aware of such a project.
KN assumes the output is the same since the headers are the same
Exactly. Feel free to open a ticket for this, especially if you can’t workaround it by splitting your header.
👍🏼 1
n
To achieve that, first cinterop library should be attached to a compilation that (transitively) depends on the second one.
Trying to visualise what this technique would look like. A pseudo example (preferably in Gradle Kotlin DSL form) would be helpful here. Can you please elaborate more on the technique in detail.
Starting to get close to having a working program. Have this error to resolve:
/home/napperley/idea_projects/glinegraph-demo/build/bin/linux/releaseExecutable/glinegraph-demo.kexe: error while loading shared libraries: libglg_cairo.so: cannot open shared object file: No such file or directory
Updated def file for GLineGraph library (so many dependencies 🤢). Is there a way to have only the APIs in the glg_cairo.h file indexed?
Contents of the glinegraph lib.
The libglg_cairo.so file does exist, and is a Shared Object file:
Copy code
~/glinegraph_cairo$ readelf -h libglg_cairo.so 
ELF Header:
  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 
  Class:                             ELF64
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              DYN (Shared object file)
  Machine:                           Advanced Micro Devices X86-64
  Version:                           0x1
  Entry point address:               0x2e00
  Start of program headers:          64 (bytes into file)
  Start of section headers:          64536 (bytes into file)
  Flags:                             0x0
  Size of this header:               64 (bytes)
  Size of program headers:           56 (bytes)
  Number of program headers:         7
  Size of section headers:           64 (bytes)
  Number of section headers:         28
  Section header string table index: 27
Is there a way to setup the LD_LIBRARY_PATH environment variable in Gradle when running a kexe? End up having to manually set the environment variable, and run the program outside Gradle.
s
Is there a way to have only the APIs in the glg_cairo.h file indexed?
headers
and
headerFilter
pretend to do exactly this. Only explicitly required declarations from other headers would be included. To avoid this, you can wrap these other headers into an interop library and depend on it.
Is there a way to setup the LD_LIBRARY_PATH environment variable in Gradle when running a kexe? End up having to manually set the environment variable, and run the program outside Gradle.
Yes. The task for running
kexe
should be a stadard
Exec
task. Please refer to Gradle documentation for more details on setting environment for
Exec
tasks.
n
Is there an article that covers developing a Kotlin Native interop lib (one that "wraps" a C lib)?
One area where there is a gap in the Kotlin Native documentation is on managing C library dependencies (especially with how it is done with Kotlin Native to get good tooling support - code completion, dependency checking etc).
Screenshot of the GlgLineGraph widget in action 🎉. A big thank you goes out to Dominic and Svyatoslav for their assistance.
👍 1