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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

linux的链接库

發布時間:2024/2/28 linux 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux的链接库 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

linux的鏈接庫

    • 概述
    • 如何指定鏈接的是動態庫還是靜態庫?
    • 鏈接庫的順序
    • 靜態庫鏈接問題
      • gcc鏈接參數
      • 庫鏈接參數
        • `--whole-archive`
          • `--no-whole-archive`
        • `--wrap`
        • `–start-group` `--end-group`
    • ld
    • cc
    • 動態鏈接庫
    • 參考鏈接


概述

程序函數庫可分為3種類型:靜態函數庫(static libraries)、共享函數庫(shared libraries)、動態加載函數庫(dynamically loaded libraries)

程序函數庫可分為下面幾種類型:

  • 靜態函數庫(static libraries):在編譯期間(compile-time)靜態鏈接庫會全部拷貝進編譯對象中,一般以.a文件的存在
  • 動態函數庫(shared libraries):在程序啟動的時候加載到程序中,它可以被不同的程序共享,一般以.so文件存在
    • 動態加載函數庫(dynamically loaded libraries),在進程運行期間,使用dlfcn.h中的函數加載、調用、關閉動態庫
  • 注意: LD_LIBRARY_PATH這個也是很關鍵的環境變量,一般的linux系統里都沒設置這個 export LD_LIBRARY_PATH=/usr/local/lib/:/usr/lib/

    如何指定鏈接的是動態庫還是靜態庫?

    如果我們在gcc中使用參數-l來鏈接某個庫,gcc會首先查找動態庫,動態庫沒有再查找靜態庫,當然我們可以通過-Wl,-Bstatic的方式使用靜態庫,使用完成之后記得加上-Wl,-Bdynamic收尾,否則所有-Wl,-Bstatic之后的庫都變成靜態庫了

    在CMake中,如果一個庫既有動態版本,又有靜態版本,可以在CMake里面指定target_link_libraries(xxx.a),指向靜態庫

    鏈接庫的順序

    GCC在鏈接過程中,對參數中的庫的順序是有要求的,參數右側的庫會先于左側的庫加載,也就是說參數的解析是從右往左的。

    假設庫B依賴與庫A,則鏈接的時候要寫為:

    gcc -o bin -lB -lA

    如果寫為:

    gcc -o bin -lA -lB

    則在B中引用的A中的內容就會無法鏈接通過。

    靜態庫鏈接問題

    靜態庫本質上就是使用ar命令打包一堆.o文件

    但是靜態庫和.o文件有不同的地方:

  • 編譯命令里連接了.o文件,那么一定會連接進最后的可執行文件。.o文件中的靜態變量、被__attribute__((constructor))修飾的函數,也會正常的在main函數前被調用
  • 靜態庫.a文件,如果編譯到它發現沒有被之前的文件調用,則編譯器會忽略這個靜態庫文件,這會導致一些靜態變量錯誤的沒有被初始化。
  • gcc鏈接參數

  • -L:告訴編譯器搜索庫的時候可以去哪個目錄去找,如-L/usr/local/lib
  • -l:指定鏈接某動態庫或靜態庫,如-ltcmalloc,也可以顯式指定鏈接庫的名字-l:libtest.so
  • -I:告訴編譯器搜索頭文件的目錄,如-I/usr/local/include
  • 庫鏈接參數

    --whole-archive

    調整庫的鏈接順序可以解決大部分問題,但當靜態庫之間存在環形依賴時,則無法通過調整順序來解決。

    使用--whole-archive可以告訴編譯器把靜態庫中的所有.o .a都進行鏈接、

    --no-whole-archive
    • 這個參數是跟在–whole-archive之后,作用是告訴編譯器,后面的庫不需要全部都鏈接了
    • 也就是說只有跟在這兩個語句中的參數才會全部被鏈接
    # 例子 g++ -o program main.o \-Wl,--whole-archive -lmylib \-Wl,--no-whole-archive -llib1 -llib2

    --wrap

    • C++ 工程實踐(6):單元測試如何 mock 系統調用

    -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中的所有靜態庫將被反復搜索,而不是默認的只搜索一次,直到不再有新的unresolved symbol產生為止。也就是說,出現在這里的.o如果發現有unresolved symbol,則可能回到之前的靜態庫中繼續搜索。

    ld

    • ld 命令是二進制工具集 GNU Binutils 的一員,是 GNU 鏈接器,用于將目標文件與庫鏈接為可執行文件或庫文件。相當于編譯里面的鏈接環節

    • gcc里面使用-Wl,開頭的參數都是傳遞給ld的參數,如果直接調用ld,則不需要加-Wl,

    常用參數:

  • -WL,–verbose 打印所有的過程
  • -Wl,-Bdynamic 后面所有的庫都使用動態版本
  • -Wl,-Bstatic 后面所有的庫使用靜態版本
  • -Wl,-soname 加動態鏈接庫的版本號如1.0
  • -Wl,–as-needed 只鏈接需要的庫,不需要的不鏈接,gcc中默認打開,因為ld的順序是從右到左的,所以如果鏈接順序有問題,會導致某些庫沒有鏈接進去,導致后面的依賴庫找不到沒有導入的前面庫的符號,因而編譯失敗
  • -Wl,–version-script 指定庫的輸出符號,spdk使用如spdk_event.map之類的文件導出函數符號
  • cc

    在linux下,cc就是gcc,之所以搞了個cc,是為了和unix兼容,cc在unix下是c語言的編譯器

    動態鏈接庫

    LD_PRELOAD可以作為參數,增加動態鏈接庫的指向,例如:LD_PRELOAD=/data/tools/lib/libzookeeper_mt.so:/data/tools/lib/libprotobuf.so

    參考鏈接

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

    總結

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

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。