[Linux]Linux中的靜態庫、動態共享庫和可加載庫

轉載自:https://blog.csdn.net/imxiangzi/article/details/45871949/

Linux 庫分類

目前可以創建兩種 Linux C/C++ 庫:

  • 靜態庫(.a):會被鏈接進目標代碼,併成爲應用程序的一部分。

  • 動態共享鏈接庫(.so):這種庫只有一種結構,不過可以通過兩種方式使用。

    • I. 運行時動態鏈接但是靜態依賴,在編譯/鏈接階段這些庫需要存在,共享庫不會包含到可執行文件中,但是需要在運行時綁定。

    • II. 在執行過程中使用動態加載鏈接系統函數進行動態加載/卸載和鏈接(比如:瀏覽器插件)。

庫命名規範

庫通常使用 ‘lib’ 作爲命名前綴,這適用於所有 C 標準庫。當鏈接時,在命令行中引用該庫將不需要包含該庫的前綴或後綴。
考慮下面的鏈接命令:

gcc src-file.c -lm -lpthread

這個例子中,在鏈接時需要 math 庫和 thread 庫,他們保存在 /usr/lib/libm.a 和 /usr/lib/libpthread.a 中。

靜態庫

如何創建一個靜態庫(目標代碼歸檔文件):

  • 編譯
gcc -Wall -c calc_*.c       /*編譯成*.o中間文件*/
  • 創建靜態庫
ar -cvq libcalc.a calc_*.o  /*打包生成*.a靜態庫文件*/
  • 列出靜態庫中的文件
ar -t libcalc.a
  • 靜態庫的使用
gcc -o calc calc.c libcalc.a                        /*鏈接同目錄/系統目錄下的靜態庫*/
gcc -o calc calc.c libcalc.a  -L/path/to/lib -lcalc /*鏈接其他目錄的靜態庫*/

動態庫

如何創建一個動態庫(動態鏈接對象庫文件):

  • 編譯
gcc -Wall -fPIC -c calc_*.c     /*編譯與地址無關的*.o中間文件*/
  • 創建動態庫
gcc -shared -Wl,-soname,libcalc.so.1 -o libcalc.so.1.0.1 *.o
  • 創建鏈接
ln -s /path/to/lib/libcalc.so.1.0.1 /path/to/lib/libcalc.so.1
ln -s /path/to/lib/libcalc.so.1 /path/to/lib/libcalc.so
  • 編譯器選項

    • Wall:包含警告,請查看 man pages 獲得更詳細信息。
    • fPIC:編譯器指令,輸出位置無關的代碼。
    • shared:生成可以在運行時鏈接到其他應用程序的共享庫。
    • Wl, options:向鏈接器傳遞選項,在這裏我們傳遞裏鏈接器的選項是 -soname libctest.so.1。
    • -o 選項:輸出操作,在這個例子中共享庫的名字將保存爲 ‘libctest.so.1.0’。

    庫符號鏈接:

    編譯選項 -lcalc 會使用 libcalc.so 符號鏈接,運行時綁定會使用libctest.so.1。

    編譯使用動態鏈接庫的主程序

gcc -Wall -I/path/to/include-files -L/path/to/libraries calc.c -lcalc -o Calc   
/*這時庫目錄中需要有libcalc.so文件,否則編譯不過。*/

列出依賴信息:

使用ldd命令可以列出應用程序依賴的共享庫信息。

ldd Calc 
    linux-vdso.so.1 =>  (0x00007ffe8ffd8000)
    libcalc.so.1 => /home/jinzhu/WorkSpace/Calc/libcalc.so.1 (0x00007f03dcdca000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f03dca00000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f03dcfcc000)

## 程序的運行
程序運行時需要確保系統能夠找個相應的動態鏈接庫。

//找不到庫文件的情況
 ./Calc 
./Calc: error while loading shared libraries: libcalc.so.1:
 cannot open shared object file: No such file or directory

庫路徑問題

爲了讓可執行程序在運行時能找到需要鏈接的庫,需要配置系統使得這些庫可以被找到,有以下方法(至少需要其中一種方法):
1. 將包含動態鏈接庫目錄的路徑加到 /etc/ld.so.conf 文件中。將路徑加入到這個文件後需要執行 ldconfig 命令(以 root 賬號)來配置鏈接器運行時綁定。
2. 增加指定目錄到庫緩存(需要 root 權限):ldconfig -n /opt/lib。其中 /opt/lib 是包含 libcalc.so 文件的目錄。這種方式不會永久在系統中包含相關目錄,在系統重啓後配置信息會丟失。
3. 配置環境變量 LD_LIBRARY_PATH 執行包含共享庫的路徑,這可以指定運行時加載器使用該路徑解決依賴關係,幾種系統的環境變量名稱:
示例(bash shell ~/.bashrc ):

if [ -d /opt/lib ];
then
   LD_LIBRARY_PATH=/opt/lib:$LD_LIBRARY_PATH
fi
export LD_LIBRARY_PATH
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章