https://kotlinlang.org logo
#kotlin-native
Title
# kotlin-native
n

napperley

07/12/2021, 11:22 PM
In a Kotlin Multiplatform project that is targeting linuxArm32Hfp if Kotlin 1.5.0 or later is used then a boatload of undefined reference errors appear (at the linking stage), eg:
Copy code
/home/napperley/.konan/dependencies/arm-unknown-linux-gnueabihf-gcc-8.3.0-glibc-2.19-kernel-4.9-2/arm-unknown-linux-gnueabihf/bin/ld.bfd: /mnt/pi_image/usr/lib/arm-linux-gnueabihf/libgdk-3.so: undefined reference to `wl_display_dispatch_pending'
However if Kotlin 1.4.31 is used then none of the errors appear, and the build is successful. In the build output there are a boatload of warnings about missing libraries (at the linking stage) if Kotlin 1.5.0 or later is used, eg:
Copy code
/home/napperley/.konan/dependencies/arm-unknown-linux-gnueabihf-gcc-8.3.0-glibc-2.19-kernel-4.9-2/arm-unknown-linux-gnueabihf/bin/ld.bfd: warning: libpcre.so.3, needed by /mnt/pi_image/usr/lib/arm-linux-gnueabihf/libglib-2.0.so, not found (try using -rpath or -rpath-link)
Are there some additional linking options that need to be passed to the linker to resolve the errors, and if so which ones?
Found an elegant solution (works with Kotlin 1.5.20) which involved adding the
--allow-shlib-undefined
flag to linkerOpts for the linuxArm32Hfp target (not the linuxX64 target) in the gtk3.def files, eg:
Copy code
linkerOpts = -lgtk-3 -lgdk-3 -latk-1.0 -lpangocairo-1.0 -lgdk_pixbuf-2.0 -lcairo-gobject -lpango-1.0 -lcairo
linkerOpts.linux_x64 = -L/usr/lib/x86_64-linux-gnu
linkerOpts.linux_arm32_hfp = --allow-shlib-undefined -L/mnt/pi_image/usr/lib/arm-linux-gnueabihf
The Kotlin team will probably recoil in horror, however the solution is straightforward, and doesn't require using a custom built version of Kotlin Native, which wouldn't be straightforward and would involve too much effort with very little gain.
I'm not sure which version of gold (the linker) is used by the Kotlin Native linuxArm32Hfp toolchain. Found the flag in the Ubuntu 20.04 documentation for the gold linker: https://manpages.ubuntu.com/manpages/focal/man1/ld.gold.1.html
With the right combination of flags the new linker might behave just like the old linker 😀 , in which case it will be like Kotlin has always used the same linker even though the linker has changed 😆 .
I wonder if something similar can be done to resolve this issue: https://youtrack.jetbrains.com/issue/KT-43501 🤔
My gut feeling is that the Kotlin Native program will run just fine after applying the
--allow-shlib-undefined
linker option. Essential for cross compilation with the Linux ARM targets.
Looks like the library path for libcurl isn't correct. The library path should look similar to the following: /usr/lib/x86_64-linux-gnu What has linkeropts been set to in the def file?
a

andylamax

07/14/2021, 9:41 PM
there is no def file at all. Just some common code compiling to linuxX64 target. Also, using ktor-client-curl as a dependency, might the be the issue?
n

napperley

07/14/2021, 9:49 PM
If you use a def file in the project then you can override the linker settings that are provided by the ktor-client-curl library.
The standard path for def files in a project is src/nativeInterop/cinterop .Below is an example of a def file:
Copy code
headers = curl.h
linkerOpts = -L/usr/lib/x86_64-linux-gnu -lcurl
To get Kotlin's Multiplatform plugin to pick up the def file you need to create the cinterop, eg:
Copy code
// ...
kotlin {
  linuxX64 {
    // ...
    cinterops.create("curl") {
      includeDirs("/usr/include/x86_64-linux-gnu/curl")
    }
  }
}
// ...
With the example above the cinterop is being created for the curl.def file.
a

andylamax

07/14/2021, 9:55 PM
Thanks will try that. Do I have to add this, on every project that I use with ktor-client-curl?
🚫 1
then why do I have to add the cinteropes?
n

napperley

07/14/2021, 9:57 PM
Usually the linker settings specified in ktor-client-curl are correct. The library should just work on Linux distributions like Linux Mint 20, and Ubuntu 20.04 for example.
In cases where the linking fails a def file will be needed.
a

andylamax

07/14/2021, 10:00 PM
you have been of great help to me. Let me try that when I am on laptop, will give feedback on how it goes. Much much thanks for taking your time on this
n

napperley

07/14/2021, 10:00 PM
Linking settings do differ between Linux distributions. What works for Debian, Ubuntu, and Linux Mint won't work with Red Hat and Fedora for example.
Currently I am assuming that you are using Linux as the host.
a

andylamax

07/15/2021, 6:39 AM
Yes linux as the host. Using Linux Zorin OS, a debian based distro
🆗 1
Apparently, installing curl alone didn't install libcurl
apt-get install libcurl4-openssl-dev
did the trick. Thanks alot for your help. My linux tests are passing now
👍 1
n

napperley

07/15/2021, 10:48 PM
If you remove the def file, and the Gradle build logic for creating the cinterop then the linking should still work without any issues.
a

andylamax

07/16/2021, 2:22 AM
yes it does, thanks once again
😄 1
51 Views