1. Static library
static library 把許多 object 檔包成同一個檔案, 用 ar 指令打包
在 link 的時候, 會在 library 裡找到對應的 object 副本, 再作 link 的動作
它以 object 檔為單位, link 的時候會放一份副本
也因此如果有多個執行檔都用到同個 static library, 每個執行檔都會有一份副本
使用的記憶體也因為每個執行檔都有一份, 所以也使用較多的記憶體
在更新 static library 時, 也得要將所有用到這份 static library 的執行檔都重新 link
2. Shared library
shared library 透過 mmap 的機制讓多個 process 共享記憶體, 並參考其中內容
一樣是將多個 object 打包, OS 會參考 memory mapping table , 等到實際取用的時候才去讀取資料
因為多個執行檔只要一份, 所以較省空間與記憶體
更新 shared library 也只需要更新一次
製作 shared library:
$ gcc -c foo.c $ gcc -c bar.c $ gcc -shared -W1,-soname,libfoo.so.o -o libfoo.so foo.o bar.o-shared 表示要建立 shared object
-soname 表示 shared object soname, (別名)
使用的方式:
$ gcc -o baz baz.o -lfoo
3. Dependency of shared library
ELF 的 dynamic section 的 NEEDED 裡會儲存檔案用到哪些 shared library, 可以用objdump來看
$ objdump -p /bin/ls /bin/ls: file format elf32-littlearm Program Header: ...... Dynamic Section: NEEDED libselinux.so.1 NEEDED librt.so.1 NEEDED libacl.so.1 NEEDED libgcc_s.so.1 NEEDED libc.so.6 NEEDED ld-linux-armhf.so.3 INIT 0x00009bb8
或是用readelf
$ readelf -d /bin/ls Dynamic section at offset 0x16ee8 contains 30 entries: Tag Type Name/Value 0x00000001 (NEEDED) Shared library: [libselinux.so.1] 0x00000001 (NEEDED) Shared library: [librt.so.1] 0x00000001 (NEEDED) Shared library: [libacl.so.1] 0x00000001 (NEEDED) Shared library: [libgcc_s.so.1] 0x00000001 (NEEDED) Shared library: [libc.so.6] 0x00000001 (NEEDED) Shared library: [ld-linux-armhf.so.3] 0x0000000c (INIT) 0x9bb8
NEEDED 記錄的是 soname, 為了要找到 soname 對應的實際的檔案, 底下是可能的找法
- 它會先從 /usr/lib 找 soname的檔案
- 如果環境變數 LD_LIBRARY_PAT 有設定, 就會在設定的路徑下找
- 如果 /etc/ld.so.cache 有記錄相關資訊的話, 也會使用它的內容
一個一個找其實很麻煩, 通常會使用 ldd 來檢查
$ ldd /bin/ls /usr/lib/arm-linux-gnueabihf/libcofi_rpi.so (0xb6f10000) libselinux.so.1 => /lib/arm-linux-gnueabihf/libselinux.so.1 (0xb6edf000) librt.so.1 => /lib/arm-linux-gnueabihf/librt.so.1 (0xb6ed0000) libacl.so.1 => /lib/arm-linux-gnueabihf/libacl.so.1 (0xb6ec1000) libgcc_s.so.1 => /lib/arm-linux-gnueabihf/libgcc_s.so.1 (0xb6e99000) libc.so.6 => /lib/arm-linux-gnueabihf/libc.so.6 (0xb6d69000) /lib/ld-linux-armhf.so.3 (0xb6f1e000) libdl.so.2 => /lib/arm-linux-gnueabihf/libdl.so.2 (0xb6d5e000) libpthread.so.0 => /lib/arm-linux-gnueabihf/libpthread.so.0 (0xb6d3f000) libattr.so.1 => /lib/arm-linux-gnueabihf/libattr.so.1 (0xb6d32000)
它會顯示出所有需要的 shared library, soname, 以及實際的位置
沒有留言:
張貼留言