1. 程式人生 > >GCC同時使用靜態庫和動態庫連結

GCC同時使用靜態庫和動態庫連結

在應用程式需要連線外部庫的情況下,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表示將預設庫連結模式恢復成動態連結。

二:檢視靜態庫匯出函式

注意:引數資訊只能存在於 .h 標頭檔案中
windows下
dumpbin   /exports   libxxx.a
linux 下
nm   -g   --defined-only   libxxx.a

場景是這樣的。我在寫一個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

http://blog.csdn.net/lapal/article/details/5482277

http://blog.chinaunix.net/uid-207