Reputation: 29
(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.)
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
Throws unending lines of error, as if libcurl isn't statically linked with its dependencies*:
...\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)
Upvotes: 0
Views: 3052
Reputation: 29
It is so enormously saddening to see how many people have struggled and are still struggling to statically link libcurl
to their program. 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."
Since linker
is saying undefined references, then libcurl.a
must be:
Linker
is sensitive to sequence. 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
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
.
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
. 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.x.x is statically linked with: [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
.
Upvotes: 1
Reputation: 7287
The best way to use libcurl is to get the necessary flags via pkg-config. In MSYS2 this works quite well. Otherwise you may need to point the environment variable PKG_CONFIG_PATH
to the location of 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. 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. 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:
#if defined(BUILDING_LIBCURL) && !defined(DLL_EXPORT)
#define NGHTTP2_STATICLIB
#endif
This will define NGHTTP2_STATICLIB
when building static libcurl.
I have reported this as a bug at: https://github.com/curl/curl/issues/7353
Upvotes: 0