[英]How can I build a libcurl Kotlin Native application on Windows?
我對 Kotlin Native 比較陌生,為了了解更多信息,我正在研究這兩個教程,一個來自 JetBrains 官方文檔,另一個來自jonnyzzz博客,它們都專注於使用 C Interop 和 libcurl 創建應用程序:
我正在嘗試在 Windows 11 上構建上述應用程序。
費了一番功夫,終於在我的Kotlin Native項目中導入了libcurl庫,可以調用C相關函數了。 到目前為止一切順利,但是當我嘗試構建整個項目時,我收到以下錯誤:
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
這是我寫的代碼:
主要.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
}
}
我錯過了什么?
非常感謝您的寶貴時間。
在 Ktor 項目中有一個關於如何鏈接 Curl 的更完整的演示——盡管它可能包含的配置比您需要的多得多。 重要的部分是
# 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
這表示“該程序需要庫libcurl.a
”。 它會在哪里尋找那個文件? 在-L
提供的任何路徑上,您還必須將-L/dir/that/contains/libraries
添加到您的.def
文件中。
或者,您可以靜態鏈接 Curl,然后 Kotlin/Native 編譯器會自動鏈接該庫。
# 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
請注意,如果libcurl.a
是為錯誤的平台編譯的,或者如果它是使用不兼容版本的 gcc 或 libc 編譯的(因為 Kotlin/Native 使用舊版本的 gcc 和 libc ),也可能會出現鏈接錯誤。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.