1. 程式人生 > >gcc同時使用動態和靜態鏈接

gcc同時使用動態和靜態鏈接

extern 存在 output solved -c -- lib64 resolved sta

場景是這樣的。我在寫一個Nginx模塊,該模塊使用了MySQL的C客戶端接口庫libmysqlclient,當然mysqlclient還引用了其他的庫,比如libm, libz, libcrypto等等。對於使用mysqlclient的代碼來說,需要關心的只是mysqlclient引用到的動態庫。大部分情況下,不是每臺機器都安裝有libmysqlclient,所以我想把這個庫靜態鏈接到Nginx模塊中,但又不想把mysqlclient引用的其他庫也靜態的鏈接進來。
  我們知道gcc的-static選項可以使鏈接器執行靜態鏈接。但簡單地使用-static顯得有些’暴力’,因為他會把命令行中-static後面的所有-l指明的庫都靜態鏈接,更主要的是,有些庫可能並沒有提供靜態庫(.a),而只提供了動態庫(.so)。這樣的話,使用-static就會造成鏈接錯誤。

  
之前的鏈接選項大致是這樣的,

1 CORE_LIBS="$CORE_LIBS -L/usr/lib64/mysql -lmysqlclient -lz -lcrypt -lnsl -lm -L/usr/lib64 -lssl -lcrypto"

修改過是這樣的,

1 2 CORE_LIBS="$CORE_LIBS -L/usr/lib64/mysql -Wl,-Bstatic -lmysqlclient \ -Wl,-Bdynamic -lz -lcrypt -lnsl -lm -L/usr/lib64 -lssl -lcrypto"

  其中用到的兩個選項:-Wl,-Bstatic和-Wl,-Bdynamic。這兩個選項是gcc的特殊選項,它會將選項的參數傳遞給鏈接器,作為鏈接器的選項。比如-Wl,-Bstatic告訴鏈接器使用-Bstatic選項,該選項是告訴鏈接器,對接下來的-l選項使用靜態鏈接;-Wl,-Bdynamic就是告訴鏈接器對接下來的-l選項使用動態鏈接。下面是man gcc對-Wl,option的描述,

-Wl,option Pass option as an option to the linker. If option contains commas, it is split into multiple options at the commas. You can use this syntax to pass an argument to the option. For example, -Wl,-Map,output.map passes -Map output.map to the linker. When using the GNU linker, you can also get the same effect with -Wl,-Map=output.map.

下面是man ld分別對-Bstatic和-Bdynamic的描述,

-Bdynamic -dy -call_shared Link against dynamic libraries. You may use this option multiple times on the command line: it affects library searching for -l options which follow it. -Bstatic -dn -non_shared -static Do not link against shared libraries. You may use this option multiple times on the command line: it affects library searching for -l options which follow it. This option also implies --unresolved-symbols=report-all. This option can be used with -shared. Doing so means that a shared library is being created but that all of the library‘s external references must be resolved by pulling in entries from static libraries.

  值得註意的是對-static的描述:-static和-shared可以同時存在,這樣會創建共享庫,但該共享庫引用的其他庫會靜態地鏈接到該共享庫中。

gcc同時使用動態和靜態鏈接