轉自:https://www.cnblogs.com/lidabo/p/6206504.html
chapter1
在應用程序需要連接外部庫的情況下,linux默認對庫的連接是使用動態庫,在找不到動態庫的情況下再選擇靜態庫。使用方式為:
gcc test.cpp -L. -ltestlib
如果當前目錄有兩個庫libtestlib.so libtestlib.a 則肯定是連接libtestlib.so。如果要指定為連接靜態庫則使用:
gcc test.cpp -L. -static -ltestlib
使用靜態庫進行連接。
當對動態庫與靜態庫混合連接的時候,使用-static會導致所有的庫都使用靜態連接的方式。這時需要作用-Wl的方式:
gcc test.cpp -L. -Wl,-Bstatic -ltestlib -Wl,-Bdynamic -ltestdll
另外還要注意系統的運行庫使用動態連接的方式,所以當動態庫在靜態庫前面連接時,必須在命令行最后使用動態連接的命令才能正常連接
,如:
gcc test.cpp -L. -Wl,-Bdynamic -ltestdll -Wl,-Bstatic -ltestlib -Wl,-Bdynamic
最后的-Wl,-Bdynamic表示將缺省庫鏈接模式恢復成動態鏈接。
chapter2:查看靜態庫導出函數
注意:參數信息只能存在於 .h 頭文件中
windows下
dumpbin /exports libxxx.a
linux 下
nm -g --defined-only libxxx.a
chapter3
場景是這樣的。我在寫一個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" |
修改過是這樣的,
12 | 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可以同時存在,這樣會創建共享庫,但該共享庫引用的其他庫會靜態地鏈接到該共享庫中。