简体   繁体   English

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

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

(I saw answers of every single StOF questions regarding this - none fully helped. I'm very frustrated after trying so hard for 3 days & nights.) (我看到了与此相关的每个 StOF 问题的答案 - 没有一个完全有帮助。经过 3 天的努力,我感到非常沮丧。)


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

Case 1 - as if curl isn't statically linked案例 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

Throws unending lines of error, as if libcurl isn't statically linked with its dependencies *:抛出无休止的错误行,就好像 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)

The best way to use libcurl is to get the necessary flags via pkg-config.使用 libcurl 的最佳方法是通过 pkg-config 获取必要的标志。 In MSYS2 this works quite well.在 MSYS2 中,这很有效。 Otherwise you may need to point the environment variable PKG_CONFIG_PATH to the location of libcurl.pc .否则,您可能需要将环境变量PKG_CONFIG_PATH指向libcurl.pc的位置。

On my system在我的系统上

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

returns:返回:

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

Note that with MinGW the order of the libraries is also important.请注意,对于 MinGW,库的顺序也很重要。 The library providing a symbol should be mention on the linker command line after the object that refers to that symbol.提供符号的库应该在链接器命令行上引用该符号的对象之后提及。

Finally you need to make sure that each library you include was in fact built and used statically.最后,您需要确保您包含的每个库实际上都是静态构建和使用的。 With that I mean no stuff like __declspec(dllexport) may be used when building it, and no __declspec(dllimport) may be used when compiling anything that depends on it.我的意思是在构建它时不能使用像__declspec(dllexport)这样的东西,并且在编译依赖于它的任何东西时不能使用__declspec(dllimport) For some libraries this may require specific defines before including the library's header(s).对于某些库,这可能需要在包含库头文件之前进行特定定义。

Specifically for libcurl and nghttp2 I find that it helps to add the following at the top of lib/http2.c and lib/http.c when building libcurl:特别是对于 libcurl 和 nghttp2,我发现在构建 libcurl 时在lib/http2.clib/http.c的顶部添加以下内容会有所帮助:

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

This will define NGHTTP2_STATICLIB when building static libcurl.这将在构建静态 libcurl 时定义NGHTTP2_STATICLIB

I have reported this as a bug at: https://github.com/curl/curl/issues/7353我已将此报告为错误: https : //github.com/curl/curl/issues/7353

It is so enormously saddening to see how many people have struggled and are still struggling to statically link libcurl to their program.看到有多少人一直在努力并且仍在努力将libcurl静态链接到他们的程序,真是令人非常难过。 So much so that a very active Curl maintainer said: "building static is a roller coaster left for the users to deal with on their own as its such a never-ending race for us to try to support."以至于一位非常活跃的 Curl 维护者说:“构建静态是一个过山车,留给用户自己处理,因为它是我们试图支持的永无止境的竞赛。”


Since linker is saying undefined references , then libcurl.a must be:由于linker说的是undefined references ,那么libcurl.a必须是:

  • not statically linked不是静态链接的
  • Or, you've got the sequence of libraries unarranged.或者,您的库序列未安排好。 Linker is sensitive to sequence. Linker对序列敏感。 Example: If libbrotlidec-static.a needs a function/symbol which is inside libbrotlienc-static.a , then libbrotlienc-static.a must be mentioned before libbrotlidec-static.a例如:如果libbrotlidec-static.a需要一个函数/符号是内部libbrotlienc-static.a ,然后libbrotlienc-static.a必须前面提到libbrotlidec-static.a

A static library is an archive .a of object .obj files.静态库是对象.obj文件的存档.a And they're not statically linked in themselves.而且它们本身并不是静态链接的。 That's why, to link some-static-library.a to a program, you need to collect and manually mention every.a single.a static.a library.a that are dependencies of some-static-library.a .这就是为什么,链接some-static-library.a一个程序,你需要收集和手动提every.a single.a static.a library.a这是依赖some-static-library.a


In my Chat@Terminal:~$ project, I should have a make.bat file which shows how to statically link libcurl to a program using gcc or mingw .在我的Chat@Terminal:~$项目中,我应该有一个make.bat文件,它显示了如何使用gccmingwlibcurl静态链接到程序。 And finally static-compile the whole program, and ship without any runtime dependency!最后静态编译整个程序,并且在没有任何运行时依赖的情况下发布!


On a side-note, curl's precompiled-binary website says: Curl_x.xx is statically linked with: [list of libraries you provided] .附带说明一下, curl 的预编译二进制网站说: Curl_x.xx 是静态链接的: [list of libraries you provided] Break your misconception that, the statement made at the website means: Curl.exe is statically linked with the libs, not libcurl .打破你的误解,网站上的声明意味着: Curl.exe与库静态链接,而不是libcurl

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

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