1

I'm relatively new to Kotlin Native, and to learn more about it, I am studying these two tutorials, one from the official JetBrains documentation and the other from the jonnyzzz blog, both focused on creating an application using C Interop and libcurl:

  1. https://kotlinlang.org/docs/native-app-with-c-and-libcurl.html

  2. https://jonnyzzz.com/blog/2018/10/29/kn-libcurl-windows/

I'm trying to build the above application on Windows 11.

After struggling a little, I finally managed to import the libcurl library in my Kotlin Native project, making it possible to call the relative C functions. So far, so good, but when I try to build the entire project, these are the errors I receive:

e: C:\Users\Nicola\.konan\dependencies\llvm-11.1.0-windows-x64-essentials/bin/clang++ invocation reported errors
The C:\Users\Nicola\.konan\dependencies\llvm-11.1.0-windows-x64-essentials/bin/clang++ command returned non-zero exit code: 1.
output:
lld-link: error: undefined symbol: __declspec(dllimport) curl_easy_strerror
>>> referenced by C:\Users\Nicola\IdeaProjects\SimpleHttpClient\src\nativeMain\kotlin\Main.kt:15
>>> C:\Users\Nicola\AppData\Local\Temp\konan_temp9458678904101419787\result.o:(libcurl_curl_easy_strerror_wrapper33)
lld-link: error: undefined symbol: __declspec(dllimport) curl_easy_init
>>> referenced by C:\Users\Nicola\IdeaProjects\SimpleHttpClient\src\nativeMain\kotlin\Main.kt:15
>>> C:\Users\Nicola\AppData\Local\Temp\konan_temp9458678904101419787\result.o:(libcurl_curl_easy_init_wrapper36)
lld-link: error: undefined symbol: __declspec(dllimport) curl_easy_perform
>>> referenced by C:\Users\Nicola\IdeaProjects\SimpleHttpClient\src\nativeMain\kotlin\Main.kt:15
>>> C:\Users\Nicola\AppData\Local\Temp\konan_temp9458678904101419787\result.o:(libcurl_curl_easy_perform_wrapper37)
lld-link: error: undefined symbol: __declspec(dllimport) curl_easy_cleanup
>>> referenced by C:\Users\Nicola\IdeaProjects\SimpleHttpClient\src\nativeMain\kotlin\Main.kt:15
>>> C:\Users\Nicola\AppData\Local\Temp\konan_temp9458678904101419787\result.o:(libcurl_curl_easy_cleanup_wrapper38)
lld-link: error: undefined symbol: curl_easy_setopt
>>> referenced by C:\Users\Nicola\AppData\Local\Temp\konan_temp9458678904101419787\result.o:(knifunptr_libcurl39_curl_easy_setopt)
clang++: error: linker command failed with exit code 1 (use -v to see invocation)
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':linkDebugExecutableNative'.
> Compilation finished with errors
* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.
* Get more help at https://help.gradle.org
BUILD FAILED in 8s

And this is the code I wrote:

Main.kt:

import libcurl.*
import kotlinx.cinterop.*
fun main(args: Array<String>) {
 val curl = curl_easy_init()
 if (curl != null) {
 curl_easy_setopt(curl, CURLOPT_URL, "http://jonnyzzz.com")
 curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L)
 val res = curl_easy_perform(curl)
 if (res != CURLE_OK) {
 println("curl_easy_perform() failed ${curl_easy_strerror(res)?.toKString()}")
 }
 curl_easy_cleanup(curl)
 }
}

libcurl.def:

headers = curl/curl.h
headerFilter = curl/*

build.gradle.kts:

plugins {
 kotlin("multiplatform") version "1.7.10"
}
group = "me.nicola"
version = "1.0-SNAPSHOT"
repositories {
 mavenCentral()
}
kotlin {
 val hostOs = System.getProperty("os.name")
 val isMingwX64 = hostOs.startsWith("Windows")
 val nativeTarget = when {
 hostOs == "Mac OS X" -> macosX64("native")
 hostOs == "Linux" -> linuxX64("native")
 isMingwX64 -> mingwX64("native")
 else -> throw GradleException("Host OS is not supported in Kotlin/Native.")
 }
 nativeTarget.apply {
 compilations.getByName("main") {
 cinterops {
 val libcurl by creating {
 val includePath = "C:\\Users\\Nicola\\Documents\\curl-7.87.0\\curl-7.87.0\\include"
 defFile(project.file("src/nativeInterop/cinterop/libcurl.def"))
 packageName("libcurl")
 compilerOpts("-I/$includePath")
 includeDirs.allHeaders(includePath)
 }
 }
 }
 binaries {
 executable {
 val buildPath = "C:\\Users\\Nicola\\Documents\\curl-7.87.0\\curl-7.87.0\\builds\\libcurl-vc-x86-release-dll-ipv6-sspi-schannel\\lib\\libcurl.lib"
 entryPoint = "main"
 linkerOpts(buildPath)
 }
 }
 }
 sourceSets {
 val nativeMain by getting
 val nativeTest by getting
 }
}

What am I missing?

Thanks a lot for your precious time.

asked Jan 31, 2023 at 8:52

1 Answer 1

1

There's a more complete demonstration of how to link Curl in the Ktor project - although it probably contains a lot more configuration than you need. The important part is

# libcurl.def 
linkerOpts.mingw_x64 = -lcurl \
 -L/usr/lib64 \
 -L/usr/lib/x86_64-linux-gnu \
 -L/opt/local/lib \
 -L/usr/local/opt/curl/lib \
 -L/opt/homebrew/opt/curl/lib \
 -LC:/msys64/mingw64/lib \
 -LC:/Tools/msys64/mingw64/lib \
 -LC:/Tools/msys2/mingw64/lib

This says "this program needs the library libcurl.a." Where will it look for that file? On any path that is provided by -L, so you'll also have to add -L/dir/that/contains/libraries to your .def file.

Alternatively, you could statically link Curl, and then the Kotlin/Native compiler would automatically link the library.

# libcurl.def 
staticLibraries = libcurl.a
# -lcurl is not needed
linkerOpts.mingw_x64 = -L/usr/lib64 \
 -L/usr/lib/x86_64-linux-gnu \
 -L/opt/local/lib \
 -L/usr/local/opt/curl/lib \
 -L/opt/homebrew/opt/curl/lib \
 -LC:/msys64/mingw64/lib \
 -LC:/Tools/msys64/mingw64/lib \
 -LC:/Tools/msys2/mingw64/lib

Note that it's also possible to get link errors if libcurl.a is compiled for the wrong platform, or if it's compiled using an incompatible version of gcc or libc (because Kotlin/Native uses old versions of gcc and libc).

answered Jan 31, 2023 at 9:23
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks a lot! It solved my problem. I also needed to download the Windows libcurl library to make everything work.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.