1. 程式人生 > >Linux庫檔案使用與編譯

Linux庫檔案使用與編譯

介紹在Linux下使用靜態庫、共享庫、動態庫的方法。

Linux庫檔案

  • 靜態庫
    • 在Linux中,以.a為字尾,如libtest.a
    • 直接拷貝函式到二進位制映像檔案
    • 只需要執行二進位制檔案,可以直接執行
  • 共享庫
    • 在Linux作業系統中,以libxxx.so.x.x為格式命名
    • 可執行檔案在開始執行時將函式從共享庫檔案中讀出,從而間接引用
    • 好處是,當函式介面沒變,實現改變時,不需要再次編譯
  • 動態庫
    • 動態載入庫在指定位置載入的函式庫
    • 可以減少記憶體開銷

庫函式基本路徑

  • /lib
    • 標準共享庫和靜態庫
  • /usr/lib
    • 標準共享庫和靜態庫
  • /usr/local/lib
    • 本地函式庫

庫檔案搜尋順序

  1. 首先在“LD_LIBRARY_PATH”環境變數所設定的路徑下查詢(一般都沒有給此環境變數賦值)
  2. 搜尋動態裝載器在/etc目錄下的快取檔案/etc/ld.so.cache(此檔案由命令ldconfig建立更新)。
  3. ldd命令–檢視到某可執行程式共享庫清單

建立靜態庫

  • libhello.c

    為要構建的庫檔案原始檔,libhello.h為呼叫此庫檔案的標頭檔案,usehello.c為測試程式。

    • 53922333150
  • 首先將所需要檔案編譯成目標檔案

    • gcc -c libhello.c
      
  • 使用ar命令建立靜態庫

    • ar rc libhello.a libhello.o
      
  • 編譯執行

    • gcc -o usehello_static usehello.c libhello.a
      
  • 53922368937

建立共享庫

  • 首先將所需要的庫編譯成目的碼,這裡生成與位置無關,可以在任何地址被連結和裝載:

    • gcc -fPIC -Wall -g -c libhello.c
      
  • 使用-shared來建立共享庫

    • gcc -g -shared -Wl,-soname,libhello.so.1.0 -o libhello.so.1.0 libhello.o
      
    • 這裡的so.1.0表示對應的完整版本號,具體可參考這裡

  • 建立soname連線:

    • ln -sf libhelloso.1.0 libhello.so
      
    • 這裡建立一個連結,只是為了方便以後版本更新時,只需要更改連結的路徑,不改變編譯程式碼

  • 編譯並連線引用庫檔案

    • gcc -Wall -g -c usehello -o usehello.o
      gcc -g -o usehello_dynamic usehello.o -L ./ -lhello //連線引用庫檔案
      
    • 其中,-L表示搜尋路徑,./表示搜尋當前路徑

    • -lhello

      • 會自動在-l前變為lib,加上.so,變為libhello.so
  • 執行,需要添加當前目錄pwd到環境變數中

    • LD_LIBRARY_PATH=$(pwd) ./usehello_dynamic 
      
  • 如果希望在使用聯結器時不使用-Ldirectory標識就可以查詢到該庫,則可以採用以下方式之一:

    • 把此庫拷貝到/usr/lib或者/lib資料夾中,或者在此兩個資料夾任意一箇中建立一個到該庫的快捷方式,並命名為libname.so
    • 如果庫所在路徑沒有在/usr/lib和/lib資料夾下,需要將該路徑新增到檔案“/etc/ld.so.conf”中,每一行增加一個路徑,完成以上設定後,然後執行ldconfig命令更新庫資訊。

動態庫

  • 在Linux中,動態庫的檔案格式跟共享庫沒有區別,主要區別在於共享庫是執行時載入。

  • 有專門的一組API用於完成開啟動態庫,查詢符號,處理出錯,關閉動態庫等功能。

    • dlopen
    • dlerror
    • dlsym
    • dlclose
  • 使用示例

    • 53924215058