日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > linux >内容正文

linux

linux的链接库

發(fā)布時(shí)間:2024/2/28 linux 52 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux的链接库 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

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ù)庫可分為下面幾種類型:

  • 靜態(tài)函數(shù)庫(static libraries):在編譯期間(compile-time)靜態(tài)鏈接庫會(huì)全部拷貝進(jìn)編譯對(duì)象中,一般以.a文件的存在
  • 動(dòng)態(tài)函數(shù)庫(shared libraries):在程序啟動(dòng)的時(shí)候加載到程序中,它可以被不同的程序共享,一般以.so文件存在
    • 動(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文件有不同的地方:

  • 編譯命令里連接了.o文件,那么一定會(huì)連接進(jìn)最后的可執(zhí)行文件。.o文件中的靜態(tài)變量、被__attribute__((constructor))修飾的函數(shù),也會(huì)正常的在main函數(shù)前被調(diào)用
  • 靜態(tài)庫.a文件,如果編譯到它發(fā)現(xiàn)沒有被之前的文件調(diào)用,則編譯器會(huì)忽略這個(gè)靜態(tài)庫文件,這會(huì)導(dǎo)致一些靜態(tài)變量錯(cuò)誤的沒有被初始化。
  • gcc鏈接參數(shù)

  • -L:告訴編譯器搜索庫的時(shí)候可以去哪個(gè)目錄去找,如-L/usr/local/lib
  • -l:指定鏈接某動(dòng)態(tài)庫或靜態(tài)庫,如-ltcmalloc,也可以顯式指定鏈接庫的名字-l:libtest.so
  • -I:告訴編譯器搜索頭文件的目錄,如-I/usr/local/include
  • 庫鏈接參數(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ì)全部被鏈接
    # 例子 g++ -o program main.o \-Wl,--whole-archive -lmylib \-Wl,--no-whole-archive -llib1 -llib2

    --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ù):

  • -WL,–verbose 打印所有的過程
  • -Wl,-Bdynamic 后面所有的庫都使用動(dòng)態(tài)版本
  • -Wl,-Bstatic 后面所有的庫使用靜態(tài)版本
  • -Wl,-soname 加動(dòng)態(tài)鏈接庫的版本號(hào)如1.0
  • -Wl,–as-needed 只鏈接需要的庫,不需要的不鏈接,gcc中默認(rèn)打開,因?yàn)閘d的順序是從右到左的,所以如果鏈接順序有問題,會(huì)導(dǎo)致某些庫沒有鏈接進(jìn)去,導(dǎo)致后面的依賴庫找不到?jīng)]有導(dǎo)入的前面庫的符號(hào),因而編譯失敗
  • -Wl,–version-script 指定庫的輸出符號(hào),spdk使用如spdk_event.map之類的文件導(dǎo)出函數(shù)符號(hào)
  • 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

    參考鏈接

  • 淺析靜態(tài)庫鏈接原理好文,并且介紹了一些編譯連接測(cè)參數(shù)
  • ld linker question: the --whole-archive option
  • How to force gcc to link an unused static library
  • 解壓靜態(tài)庫.a文件
  • linux動(dòng)態(tài)鏈接庫的加載順序 rpath > LD_LIBRARY_PATH > ldconfig > 系統(tǒng)默認(rèn)位置/lib /usr/lib
  • 動(dòng)態(tài)庫(.so)鏈接靜態(tài)庫(.a)的情況總結(jié)
  • gcc 鏈接庫的順序問題
  • 深入理解LINUX下動(dòng)態(tài)庫鏈接器/加載器ld-linux.so.2
  • linux 熱替換so文件 熱替換需要先dlclose,然后再換掉動(dòng)態(tài)庫,切換的過程中不能調(diào)用動(dòng)態(tài)庫中的函數(shù)
  • Linux下g++編譯與使用靜態(tài)庫和動(dòng)態(tài)庫
  • How static library in c++ work with name mangle?C++編譯動(dòng)態(tài)庫文件,會(huì)遇到因?yàn)閏++對(duì)函數(shù)改名,而產(chǎn)生name mangling問題
  • 2.1 Command-line Options ld所有的選項(xiàng)
  • When and why would the C linker exclude unused symbols?
  • C 多個(gè)動(dòng)態(tài)庫存在同名函數(shù)問題處理方法:-fvisibility=hidden
  • gcc編譯參數(shù)-fPIC的一些問題
  • GCC選項(xiàng)_-Wl,-soname 及 DT_NEEDED 的解釋
  • 鏈接腳本(Linker Scripts)語法和規(guī)則解析(翻譯自官方手冊(cè)) GROUP(file, file, …) / GROUP(file file …) AS_NEEDED(file, file, …) / AS_NEEDED(file file …)
  • LD上文是對(duì)這個(gè)LD文檔的部分翻譯
  • LD --version-script及腳本文件控制符號(hào)輸出
  • 超強(qiáng)干貨來襲 云風(fēng)專訪:近40年碼齡,通宵達(dá)旦的技術(shù)人生

    總結(jié)

    以上是生活随笔為你收集整理的linux的链接库的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。