minGW64 在 C 程序中使用静态 libcurl.a
using static libcurl.a in C program by minGW64
(我看到了关于这个问题的每一个 StOF 问题的答案 - none 完全有帮助。经过 3 天 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 位]
Case 1 - as if curl isn't statically linked
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
returns:
-LD:/Prog/winlibs64-11.1.0/custombuilt/lib -lcurl -lidn2 -lrtmp -lssh2 -lnettle
-lgnutls -ladvapi32 -lcrypt32 -lgss -lwldap32 -lzstd -lz -lws2_32 -lrtmp
请注意,对于 MinGW,库的顺序也很重要。提供符号的库应该在链接器命令行中提到该符号的 object 之后。
最后,您需要确保您包含的每个库实际上都是静态构建和使用的。我的意思是在构建它时不能使用 __declspec(dllexport)
之类的东西,并且在编译依赖它的任何东西时不能使用 __declspec(dllimport)
。对于某些库,这可能需要在包含库的 header(s).
之前进行特定定义
特别针对 libcurl 和 nghttp2 我发现在构建 libcurl 时在 lib/http2.c
和 lib/http.c
的顶部添加以下内容会有所帮助:
#if defined(BUILDING_LIBCURL) && !defined(DLL_EXPORT)
#define NGHTTP2_STATICLIB
#endif
这将在构建静态 libcurl 时定义 NGHTTP2_STATICLIB
。
我已将此问题报告为:https://github.com/curl/curl/issues/7353
看到有多少人已经和仍在努力静态 link libcurl
他们的程序,真是令人非常难过。如此之多,以至于 a very active Curl maintainer 说:“构建静电就像过山车一样,留给用户自己处理,因为它是我们试图支持的永无止境的竞赛。”
既然linker
是说未定义的引用,那么libcurl.a
必须是:
- 非静态 linked
- 或者,您的库序列未排列。
Linker
对顺序敏感。示例:如果 libbrotlidec-static.a
需要 libbrotlienc-static.a
中的 function/symbol,则必须在 libbrotlidec-static.a
之前提及 libbrotlienc-static.a
A static library is an archive .a
of object .obj
files. 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
.
在我的 Chat@Terminal:~$ 项目中,我应该有一个 make.bat
文件,它显示了如何使用 gcc
或 mingw
。最后静态编译整个程序,并在没有任何运行时依赖的情况下发布!
在旁注中,curl's precompiled-binary website 说:Curl_x.x.x 是静态 linked 的:[您提供的库列表] .打破你的误解,网站上的声明意味着:Curl.exe
是静态地 linked with the libs,而不是 libcurl
.
(我看到了关于这个问题的每一个 StOF 问题的答案 - none 完全有帮助。经过 3 天 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 位]
Case 1 - as if curl isn't statically linked
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
returns:
-LD:/Prog/winlibs64-11.1.0/custombuilt/lib -lcurl -lidn2 -lrtmp -lssh2 -lnettle
-lgnutls -ladvapi32 -lcrypt32 -lgss -lwldap32 -lzstd -lz -lws2_32 -lrtmp
请注意,对于 MinGW,库的顺序也很重要。提供符号的库应该在链接器命令行中提到该符号的 object 之后。
最后,您需要确保您包含的每个库实际上都是静态构建和使用的。我的意思是在构建它时不能使用 __declspec(dllexport)
之类的东西,并且在编译依赖它的任何东西时不能使用 __declspec(dllimport)
。对于某些库,这可能需要在包含库的 header(s).
特别针对 libcurl 和 nghttp2 我发现在构建 libcurl 时在 lib/http2.c
和 lib/http.c
的顶部添加以下内容会有所帮助:
#if defined(BUILDING_LIBCURL) && !defined(DLL_EXPORT)
#define NGHTTP2_STATICLIB
#endif
这将在构建静态 libcurl 时定义 NGHTTP2_STATICLIB
。
我已将此问题报告为:https://github.com/curl/curl/issues/7353
看到有多少人已经和仍在努力静态 link libcurl
他们的程序,真是令人非常难过。如此之多,以至于 a very active Curl maintainer 说:“构建静电就像过山车一样,留给用户自己处理,因为它是我们试图支持的永无止境的竞赛。”
既然linker
是说未定义的引用,那么libcurl.a
必须是:
- 非静态 linked
- 或者,您的库序列未排列。
Linker
对顺序敏感。示例:如果libbrotlidec-static.a
需要libbrotlienc-static.a
中的 function/symbol,则必须在libbrotlidec-static.a
之前提及
libbrotlienc-static.a
A static library is an archive
.a
of object.obj
files. And they're not statically linked in themselves. That's why, to linksome-static-library.a
to a program, you need to collect and manually mentionevery.a
single.a
static.a
library.a
that are dependencies ofsome-static-library.a
.
在我的 Chat@Terminal:~$ 项目中,我应该有一个 make.bat
文件,它显示了如何使用 gcc
或 mingw
。最后静态编译整个程序,并在没有任何运行时依赖的情况下发布!
在旁注中,curl's precompiled-binary website 说:Curl_x.x.x 是静态 linked 的:[您提供的库列表] .打破你的误解,网站上的声明意味着:Curl.exe
是静态地 linked with the libs,而不是 libcurl
.