簡體   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