linux的链接库
linux的鏈接庫
- 概述
- 如何指定鏈接的是動(dòng)態(tài)庫還是靜態(tài)庫?
- 鏈接庫的順序
- 靜態(tài)庫鏈接問題
- gcc鏈接參數(shù)
- 庫鏈接參數(shù)
- `--whole-archive`
- `--no-whole-archive`
- `--wrap`
- `–start-group` `--end-group`
- ld
- cc
- 動(dòng)態(tài)鏈接庫
- 參考鏈接
概述
程序函數(shù)庫可分為3種類型:靜態(tài)函數(shù)庫(static libraries)、共享函數(shù)庫(shared libraries)、動(dòng)態(tài)加載函數(shù)庫(dynamically loaded libraries)
程序函數(shù)庫可分為下面幾種類型:
- 動(dòng)態(tài)加載函數(shù)庫(dynamically loaded libraries),在進(jìn)程運(yùn)行期間,使用dlfcn.h中的函數(shù)加載、調(diào)用、關(guān)閉動(dòng)態(tài)庫
注意: LD_LIBRARY_PATH這個(gè)也是很關(guān)鍵的環(huán)境變量,一般的linux系統(tǒng)里都沒設(shè)置這個(gè) export LD_LIBRARY_PATH=/usr/local/lib/:/usr/lib/
如何指定鏈接的是動(dòng)態(tài)庫還是靜態(tài)庫?
如果我們?cè)趃cc中使用參數(shù)-l來鏈接某個(gè)庫,gcc會(huì)首先查找動(dòng)態(tài)庫,動(dòng)態(tài)庫沒有再查找靜態(tài)庫,當(dāng)然我們可以通過-Wl,-Bstatic的方式使用靜態(tài)庫,使用完成之后記得加上-Wl,-Bdynamic收尾,否則所有-Wl,-Bstatic之后的庫都變成靜態(tài)庫了
在CMake中,如果一個(gè)庫既有動(dòng)態(tài)版本,又有靜態(tài)版本,可以在CMake里面指定target_link_libraries(xxx.a),指向靜態(tài)庫
鏈接庫的順序
GCC在鏈接過程中,對(duì)參數(shù)中的庫的順序是有要求的,參數(shù)右側(cè)的庫會(huì)先于左側(cè)的庫加載,也就是說參數(shù)的解析是從右往左的。
假設(shè)庫B依賴與庫A,則鏈接的時(shí)候要寫為:
gcc -o bin -lB -lA如果寫為:
gcc -o bin -lA -lB則在B中引用的A中的內(nèi)容就會(huì)無法鏈接通過。
靜態(tài)庫鏈接問題
靜態(tài)庫本質(zhì)上就是使用ar命令打包一堆.o文件
但是靜態(tài)庫和.o文件有不同的地方:
gcc鏈接參數(shù)
庫鏈接參數(shù)
--whole-archive
調(diào)整庫的鏈接順序可以解決大部分問題,但當(dāng)靜態(tài)庫之間存在環(huán)形依賴時(shí),則無法通過調(diào)整順序來解決。
使用--whole-archive可以告訴編譯器把靜態(tài)庫中的所有.o .a都進(jìn)行鏈接、
--no-whole-archive
- 這個(gè)參數(shù)是跟在–whole-archive之后,作用是告訴編譯器,后面的庫不需要全部都鏈接了
- 也就是說只有跟在這兩個(gè)語句中的參數(shù)才會(huì)全部被鏈接
--wrap
- C++ 工程實(shí)踐(6):單元測(cè)試如何 mock 系統(tǒng)調(diào)用
-Wl,–wrap -Wl,free
--wrap=symbolUse a wrapper function for symbol. Any undefined reference tosymbol will be resolved to "__wrap_symbol". Any undefinedreference to "__real_symbol" will be resolved to symbol.This can be used to provide a wrapper for a system function. Thewrapper function should be called "__wrap_symbol". If it wishes tocall the system function, it should call "__real_symbol".Here is a trivial example:void *__wrap_malloc (size_t c){printf ("malloc called with %zu/n", c);return __real_malloc (c);}If you link other code with this file using --wrap malloc, then allcalls to "malloc" will call the function "__wrap_malloc" instead.The call to "__real_malloc" in "__wrap_malloc" will call the real"malloc" function.You may wish to provide a "__real_malloc" function as well, so thatlinks without the --wrap option will succeed. If you do this, youshould not put the definition of "__real_malloc" in the same fileas "__wrap_malloc"; if you do, the assembler may resolve the callbefore the linker has a chance to wrap it to "malloc".–start-group --end-group
位于--start-group --end-group中的所有靜態(tài)庫將被反復(fù)搜索,而不是默認(rèn)的只搜索一次,直到不再有新的unresolved symbol產(chǎn)生為止。也就是說,出現(xiàn)在這里的.o如果發(fā)現(xiàn)有unresolved symbol,則可能回到之前的靜態(tài)庫中繼續(xù)搜索。
ld
-
ld 命令是二進(jìn)制工具集 GNU Binutils 的一員,是 GNU 鏈接器,用于將目標(biāo)文件與庫鏈接為可執(zhí)行文件或庫文件。相當(dāng)于編譯里面的鏈接環(huán)節(jié)
-
gcc里面使用-Wl,開頭的參數(shù)都是傳遞給ld的參數(shù),如果直接調(diào)用ld,則不需要加-Wl,
常用參數(shù):
cc
在linux下,cc就是gcc,之所以搞了個(gè)cc,是為了和unix兼容,cc在unix下是c語言的編譯器
動(dòng)態(tài)鏈接庫
LD_PRELOAD可以作為參數(shù),增加動(dòng)態(tài)鏈接庫的指向,例如:LD_PRELOAD=/data/tools/lib/libzookeeper_mt.so:/data/tools/lib/libprotobuf.so
參考鏈接
總結(jié)
- 上一篇: gdb常用命令及参考文档
- 下一篇: linux 丢包排查思路简述(tcp+r