繁体   English   中英

minGW64 在 C 程序中使用静态 libcurl.a

[英]using static libcurl.a in C program by minGW64

(我看到了与此相关的每个 StOF 问题的答案 - 没有一个完全有帮助。经过 3 天的努力,我感到非常沮丧。)


  • libcurl.a与以下内容静态链接:
    • OpenSSL 1.1.1k [64 位/32 位]
    • brotli 1.0.9 [64 位/32 位]
    • libgsasl 1.10.0 [64 位/32 位]
    • libidn2 2.3.1 [64 位/32 位]
    • libssh2 1.9.0 [64 位/32 位]
    • nghttp2 1.43.0 [64 位/32 位]
    • zlib 1.2.11 [64 位/32 位]
    • zstd 1.5.0 [64 位/32 位]

案例 1 - 好像 curl 不是静态链接的

x86_64-w64-mingw32-gcc-10.2.0.exe -o main.exe main.c "C:\\curl-7.77.0-win64-mingw\\lib\\libcurl.a" -DCURL_STATICLIB

抛出无休止的错误行,就好像 libcurl 没有与其依赖项静态链接*:

...\lib\libcurl.a(http2.o):(.text+0x7f): undefined reference to `nghttp2_version'
...\lib\libcurl.a(http2.o):(.text+0x297): undefined reference to `nghttp2_submit_rst_stream' 

... (then the errors include many more undefined reference to symbols from nghttp2, ssl, crypt, ssh, gsasl)

使用 libcurl 的最佳方法是通过 pkg-config 获取必要的标志。 在 MSYS2 中,这很有效。 否则,您可能需要将环境变量PKG_CONFIG_PATH指向libcurl.pc的位置。

在我的系统上

pkg-config --define-prefix --static --libs libcurl

返回:

-LD:/Prog/winlibs64-11.1.0/custombuilt/lib -lcurl -lidn2 -lrtmp -lssh2 -lnettle
-lgnutls -ladvapi32 -lcrypt32 -lgss -lwldap32 -lzstd -lz -lws2_32 -lrtmp

请注意,对于 MinGW,库的顺序也很重要。 提供符号的库应该在链接器命令行上引用该符号的对象之后提及。

最后,您需要确保您包含的每个库实际上都是静态构建和使用的。 我的意思是在构建它时不能使用像__declspec(dllexport)这样的东西,并且在编译依赖于它的任何东西时不能使用__declspec(dllimport) 对于某些库,这可能需要在包含库头文件之前进行特定定义。

特别是对于 libcurl 和 nghttp2,我发现在构建 libcurl 时在lib/http2.clib/http.c的顶部添加以下内容会有所帮助:

#if defined(BUILDING_LIBCURL) && !defined(DLL_EXPORT)
#define NGHTTP2_STATICLIB
#endif

这将在构建静态 libcurl 时定义NGHTTP2_STATICLIB

我已将此报告为错误: https : //github.com/curl/curl/issues/7353

看到有多少人一直在努力并且仍在努力将libcurl静态链接到他们的程序,真是令人非常难过。 以至于一位非常活跃的 Curl 维护者说:“构建静态是一个过山车,留给用户自己处理,因为它是我们试图支持的永无止境的竞赛。”


由于linker说的是undefined references ,那么libcurl.a必须是:

  • 不是静态链接的
  • 或者,您的库序列未安排好。 Linker对序列敏感。 例如:如果libbrotlidec-static.a需要一个函数/符号是内部libbrotlienc-static.a ,然后libbrotlienc-static.a必须前面提到libbrotlidec-static.a

静态库是对象.obj文件的存档.a 而且它们本身并不是静态链接的。 这就是为什么,链接some-static-library.a一个程序,你需要收集和手动提every.a single.a static.a library.a这是依赖some-static-library.a


在我的Chat@Terminal:~$项目中,我应该有一个make.bat文件,它显示了如何使用gccmingwlibcurl静态链接到程序。 最后静态编译整个程序,并且在没有任何运行时依赖的情况下发布!


附带说明一下, curl 的预编译二进制网站说: Curl_x.xx 是静态链接的: [list of libraries you provided] 打破你的误解,网站上的声明意味着: Curl.exe与库静态链接,而不是libcurl

暂无
暂无

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM