靜態庫與動態庫文件的制作與使用


靜態庫與動態庫

什么是庫文件?

  • 提供變量,函數/類的封裝的代碼倉庫

  • 不能單獨運行 而一般的程序文件可以單獨運行

  • 分為靜態庫和動態庫

  • 好處: 代碼保密 方便部署和分發

動態庫與靜態庫的區別

靜態庫在程序鏈接階段被復制到程序中, 動態庫在程序運行時由系統定位動態庫文件並加載到內存中使用

image-20211130112706895

庫類型 優點 缺點
靜態 打包到應用程序中加載速度快 消耗系統資源,浪費內存
發布程序無需提供靜態庫,移植方便 更新、部署、發布麻煩
動態 可以實現進程間資源共享(共享庫)
更新、部署、發布簡單 加載速度比靜態庫慢 運行時需要查找庫再加入
可以控制何時加載動態庫 發布程序時需要提供依賴的動態庫

命名規則

靜態庫

Linux: libxxx.a 只有xxx是自定義

Windows:libxxx.lib xxx自定義

動態庫

Linux:libxxx.so

Windows:libxxx.dll

庫的制作與使用

靜態

r 將文件插入備存文件(備存文件?)

c 建立備存文件索引

s 索引

gcc  a.c b.c -o a.o b.o
ar rcs libxxx.a a.o b.o

當前文件

root@iZwz953bcwdl9hfnde2odsZ:~/Linux/lession05/calc# tree
.
├── add.c
├── div.c
├── head.h
├── libcalc.a
├── main.c
├── mult.c
└── sub.c

編譯成目標文件

root@iZwz953bcwdl9hfnde2odsZ:~/Linux/lession05/calc# gcc -c add.c div.c mult.c sub.c 
root@iZwz953bcwdl9hfnde2odsZ:~/Linux/lession05/calc# tree
.
├── add.c
├── add.o
├── div.c
├── div.o
├── head.h
├── main.c
├── mult.c
├── mult.o
├── sub.c
└── sub.o

創建靜態庫

root@iZwz953bcwdl9hfnde2odsZ:~/Linux/lession05/calc# ar rcs libcalc.a  sub.o div.o mult.o add.o
root@iZwz953bcwdl9hfnde2odsZ:~/Linux/lession05/calc# tree
.
├── add.c
├── add.o
├── div.c
├── div.o
├── head.h
├── libcalc.a
├── main.c
├── mult.c
├── mult.o
├── sub.c
└── sub.o

使用靜態庫

root@iZwz953bcwdl9hfnde2odsZ:~/Linux/lession05/library# tree
.
├── include
│   └── head.h
├── lib
│   └── libcalc.a
├── main.c
└── src
    ├── add.c
    ├── div.c
    ├── mult.c
    └── sub.c

編譯main程序頭文件

root@iZwz953bcwdl9hfnde2odsZ:~/Linux/lession05/library# gcc main.c -o app
main.c:2:10: fatal error: head.h: No such file or directory
    2 | #include "head.h"
      |          ^~~~~~~~
compilation terminated.

提供了頭文件 但找不到定義的內部內容

root@iZwz953bcwdl9hfnde2odsZ:~/Linux/lession05/library# gcc main.c -o app -I ./include/
/usr/bin/ld: /tmp/ccmLoZI5.o: in function `main':
main.c:(.text+0x3e): undefined reference to `add'
/usr/bin/ld: main.c:(.text+0x60): undefined reference to `subtract'
/usr/bin/ld: main.c:(.text+0x82): undefined reference to `multiply'
/usr/bin/ld: main.c:(.text+0xa4): undefined reference to `divide'
collect2: error: ld returned 1 exit status

提供靜態庫

root@iZwz953bcwdl9hfnde2odsZ:~/Linux/lession05/library# gcc main.c -o app -I ./include/ -l calc -L ./lib/

執行程序

root@iZwz953bcwdl9hfnde2odsZ:~/Linux/lession05/library# ./app
a = 20, b = 12
a+b= 32
a-b= 8
a*b= 240
a/b= 1.666667

動態

ldd list dynamic dependencies 檢查依賴

定位共享庫文件

知道庫的名字不夠,它會先后搜索elf文件的 DT_RPATH段 ——> 環境變量
LD_LIBRARY_PATH ——> /etc/ld.so.cache文件列表 ——> /lib/,/usr/lib
目錄找到庫文件后將其載入內存

  • 使用LD_LIBRARTY_PATH
  • 使用/lib/, /usr/lib/

動態庫制作

├── calc
│   ├── add.c
│   ├── div.c
│   ├── head.h
│   ├── main.c
│   ├── mult.c
│   └── sub.c
└── library
    ├── include
    │   └── head.h
    ├── lib
    │   └── libcalc.so
    ├── main
    ├── main.c
    └── src
        ├── add.c
        ├── div.c
        ├── mult.c
        └── sub.c

生成位置無關代碼

root@iZwz953bcwdl9hfnde2odsZ:~/Linux/lession06/calc# gcc -c -fpic add.c div.c mult.c sub.c
root@iZwz953bcwdl9hfnde2odsZ:~/Linux/lession06/calc# tree
.
├── add.c
├── add.o
├── div.c
├── div.o
├── head.h
├── main.c
├── mult.c
├── mult.o
├── sub.c
└── sub.o

生成共享動態庫

root@iZwz953bcwdl9hfnde2odsZ:~/Linux/lession06/calc# gcc -shared *.o -o libcalc.so
root@iZwz953bcwdl9hfnde2odsZ:~/Linux/lession06/calc# tree
.
├── add.c
├── add.o
├── div.c
├── div.o
├── head.h
├── libcalc.so
├── main.c
├── mult.c
├── mult.o
├── sub.c
└── sub.o

使用動態庫

├── include
│   └── head.h
├── lib
│   └── libcalc.so
├── main
├── main.c
└── src
    ├── add.c
    ├── div.c
    ├── mult.c
# gcc main.c -o main -I ./include/ -L ./lib/ -l calc
# ldd main  查看依賴關系

提示無法找到共享庫時

使用以下三種方法 定位動態庫文件 因為動態庫是在最后加入內存

環境變量LD_LIBRARY_PATH

export LD_LIBRARY_PATH = $LD_LIBRARY_PATH : /root/Linux/lession06/library/lib  暫時的環境變量 重啟終端后刪除
root@iZwz953bcwdl9hfnde2odsZ:~/Linux/lession06/library# ldd
ldd: missing file arguments
Try `ldd --help' for more information.
root@iZwz953bcwdl9hfnde2odsZ:~/Linux/lession06/library# ldd main
        linux-vdso.so.1 (0x00007ffc1cd4d000)
        libcalc.so => /root/Linux/lession06/library/lib/libcalc.so (0x00007f7a5f3bf000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f7a5f1c6000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f7a5f3cb000)

vim .bashrc 用戶級別永久環境變量
最后插入export LD_LIBRARY_PATH = $LD_LIBRARY_PATH : /root/Linux/lession06/library/lib
. .bashrc或者source .bashrc
vim /etc/profile  系統級別環境變量
下同上

配置/etc/ld.so.cache文件列表

二進制文件無法直接修改 因此間接

# vim /etc/ld.so.conf
include /etc/ld.so.conf.d/*.conf
/root/Linux/lession06/library/lib 插入的內容


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM