简体   繁体   English

如何在 Windows 上构建 libcurl Kotlin 本机应用程序?

[英]How can I build a libcurl Kotlin Native application on Windows?

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:我对 Kotlin Native 比较陌生,为了了解更多信息,我正在研究这两个教程,一个来自 JetBrains 官方文档,另一个来自jonnyzzz博客,它们都专注于使用 C Interop 和 libcurl 创建应用程序:

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

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

I'm trying to build the above application on Windows 11.我正在尝试在 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.费了一番功夫,终于在我的Kotlin Native项目中导入了libcurl库,可以调用C相关函数了。 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:主要.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: libcurl.def:

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

build.gradle.kts: 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.非常感谢您的宝贵时间。

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.在 Ktor 项目中有一个关于如何链接 Curl 的更完整的演示——尽管它可能包含的配置比您需要的多得多。 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 ."这表示“该程序需要库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.-L提供的任何路径上,您还必须将-L/dir/that/contains/libraries添加到您的.def文件中。

Alternatively, you could statically link Curl, and then the Kotlin/Native compiler would automatically link the library.或者,您可以静态链接 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

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 ).请注意,如果libcurl.a是为错误的平台编译的,或者如果它是使用不兼容版本的 gcc 或 libc 编译的(因为 Kotlin/Native 使用旧版本的 gcc 和 libc ),也可能会出现链接错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Windows 上的 Kotlin Native libcurl 示例 - Kotlin Native libcurl example on Windows 如何使用 Kotlin/Native 应用程序将字符串写入剪贴板(Windows 操作系统)? - How to write a string to clipboard (Windows OS) with a Kotlin/Native application? 我可以从 kotlin 源代码构建一个 windows 可执行文件吗? - Can I build a windows executable from kotlin source code? 如何在 Kotlin/Native iOS 开发中通过 HTTP 连接? - How can I connect through HTTP in Kotlin/Native iOS development? 使用 Kotlin Native 构建 Windows exe,我可以将库 ( dll ) 捆绑到 exe 中吗? - With Kotlin Native, building a windows exe, can I bundle libraries ( dlls ) into the exe? 在带有gradle的Kotlin应用程序构建中的Jar中找不到Main类 - Can't find Main class in Jar in Kotlin application build with gradle 在Kotlin中,如何使用本机Java参数实例化泛型类? - In Kotlin, how can I instantiate a generic class using a native java parameter? 我怎样才能在 Kotlin 中做到这一点? - How can I do this in Kotlin? 如何避免每次在 build.gradle 中添加插件“kotlin-android-extensions” - How can I avoid adding the plugins 'kotlin-android-extensions' everytime in the build.gradle 如何在 Gradle 构建中使用来自 Kotlin 的孵化载体 API? - How can I use the incubating Vector API from Kotlin in a Gradle build?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM